diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml
new file mode 100644
index 0000000..58e328a
--- /dev/null
+++ b/.bazelci/presubmit.yml
@@ -0,0 +1,22 @@
+---
+platforms:
+ ubuntu1804:
+ build_flags:
+ - "--build_tag_filters=-nolinux"
+ build_targets:
+ - "//..."
+ test_flags:
+ - "--features=race"
+ - "--test_tag_filters=-nolinux"
+ test_targets:
+ - "//..."
+ macos:
+ build_flags:
+ - "--build_tag_filters=-nomacos"
+ build_targets:
+ - "//..."
+ test_flags:
+ - "--features=race"
+ - "--test_tag_filters=-nomacos"
+ test_targets:
+ - "//..."
diff --git a/.bazelversion b/.bazelversion
new file mode 100644
index 0000000..af8c8ec
--- /dev/null
+++ b/.bazelversion
@@ -0,0 +1 @@
+4.2.2
diff --git a/.circleci/Dockerfile b/.circleci/Dockerfile
new file mode 100644
index 0000000..a3f1108
--- /dev/null
+++ b/.circleci/Dockerfile
@@ -0,0 +1,53 @@
+FROM golang:1.18.0
+
+ENV NVM_DIR="/usr/local/share/nvm"
+ENV NVM_SYMLINK_CURRENT=true \
+ PATH=${NVM_DIR}/current/bin:${PATH}
+
+ARG VSCODE_SCRIPTS_VERSION="v0.193.0"
+ARG NODE_VERSION="10"
+# Run some common installation scripts for a nicer dev environment. In order:
+# Used to create non-root user and update system packages
+# https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/common.md
+# We use this to install Go tools used by gopls
+# https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/go.md
+# We use this to install Node
+# https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/node.md
+RUN apt-get update && \
+ wget "https://raw.githubusercontent.com/microsoft/vscode-dev-containers/${VSCODE_SCRIPTS_VERSION}/script-library/common-debian.sh" && \
+ chmod +x ./common-debian.sh && \
+ ./common-debian.sh false vscode automatic automatic true false && \
+ wget "https://raw.githubusercontent.com/microsoft/vscode-dev-containers/${VSCODE_SCRIPTS_VERSION}/script-library/go-debian.sh" && \
+ chmod +x ./go-debian.sh && \
+ ./go-debian.sh none /usr/local/go /go vscode false true && \
+ wget "https://raw.githubusercontent.com/microsoft/vscode-dev-containers/${VSCODE_SCRIPTS_VERSION}/script-library/node-debian.sh" && \
+ chmod +x ./node-debian.sh && \
+ ./node-debian.sh "${NVM_DIR}" "${NODE_VERSION}" vscode true && \
+ rm common-debian.sh go-debian.sh node-debian.sh && \
+ DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends \
+ wget \
+ unzip \
+ openjdk-11-jre \
+ bzip2 \
+ patch && \
+ apt-get clean -y && \
+ rm -rf /var/lib/apt/lists/*
+
+# Install swagger-codegen
+ENV SWAGGER_CODEGEN_VERSION=2.4.8
+RUN wget https://repo1.maven.org/maven2/io/swagger/swagger-codegen-cli/${SWAGGER_CODEGEN_VERSION}/swagger-codegen-cli-${SWAGGER_CODEGEN_VERSION}.jar \
+ -O /usr/local/bin/swagger-codegen-cli.jar && \
+ echo -e '#!/bin/bash\njava -jar /usr/local/bin/swagger-codegen-cli.jar "$@"' > /usr/local/bin/swagger-codegen && \
+ chmod +x /usr/local/bin/swagger-codegen
+
+# Install Bazelisk as bazel to manage Bazel
+RUN go install github.com/bazelbuild/bazelisk@latest && \
+ mv $(which bazelisk) /usr/local/bin/bazel
+
+# Install buildifier for bazel formatting
+RUN go install github.com/bazelbuild/buildtools/buildifier@latest
+
+# Give vscode ownership of GOPATH
+RUN chown -R vscode: /go
+
+USER vscode
diff --git a/.circleci/README.md b/.circleci/README.md
new file mode 100644
index 0000000..bbdcc3b
--- /dev/null
+++ b/.circleci/README.md
@@ -0,0 +1,8 @@
+## gRPC-Gateway CI testing setup
+
+Contained within is the CI test setup for the Gateway. It runs on Circle CI.
+
+### Whats up with the Dockerfile?
+
+The `Dockerfile` in this folder is used as the build environment when regenerating the files (see CONTRIBUTING.md).
+The canonical repository for this Dockerfile is `docker.pkg.github.com/binchencoder/janus-gateway/build-env`.
diff --git a/.circleci/config.yml b/.circleci/config.yml
new file mode 100644
index 0000000..b693f4d
--- /dev/null
+++ b/.circleci/config.yml
@@ -0,0 +1,228 @@
+version: 2.1
+
+commands:
+ configure_bazel:
+ description: Create Bazel config file (.bazelrc)
+ steps:
+ - run: |
+ cat > .bazelrc \<< EOF
+ startup --output_base /home/vscode/.cache/_janus_gateway_bazel
+ build --test_output errors
+ build --features race
+ # Workaround https://github.com/bazelbuild/bazel/issues/3645
+ # See https://docs.bazel.build/versions/0.23.0/command-line-reference.html
+ build --local_ram_resources=4096 # Circle Docker runners have 4G of memory
+ build --local_cpu_resources=2 # Circle Docker runners have 2 vCPU
+ EOF
+ generate:
+ steps:
+ - run: make install
+ - run: make clean
+ - run: make generate
+ - run: go mod tidy
+ renovate_git_amend_push:
+ description: Git amend and push changes
+ steps:
+ - run: |
+ git add .
+ if output=$(git status --porcelain) && [ ! -z "$output" ]; then
+ git config user.name "Renovate Bot"
+ git config user.email "bot@renovateapp.com"
+ git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/grpc-ecosystem/grpc-gateway.git
+ git commit --amend --no-edit
+ git push --force-with-lease origin ${CIRCLE_BRANCH}
+ fi
+
+executors:
+ build-env:
+ environment:
+ ## Split key to avoid github revoking it
+ password0: "99544cdcb19ad4e3fd64"
+ password1: "3ec86b2e5a431be2d72c"
+ GLOG_logtostderr: "1"
+ docker:
+ - image: docker.pkg.github.com/binchencoder/janus-gateway/build-env:1.15
+ auth:
+ username: gateway-ci-user
+ password: ${password0}${password1}
+
+jobs:
+ build:
+ executor: build-env
+ working_directory: /home/vscode/src/janus-gateway
+ steps:
+ - checkout
+ - run: go build ./...
+ test:
+ executor: build-env
+ working_directory: /home/vscode/src/janus-gateway
+ steps:
+ - checkout
+ - run: go test -race -coverprofile=coverage.txt ./...
+ - run: bash <(curl -s https://codecov.io/bash)
+ node_test:
+ executor: build-env
+ working_directory: /home/vscode/src/janus-gateway
+ steps:
+ - checkout
+ - run: go mod vendor
+ - run: >
+ cd examples/internal/browser &&
+ npm install gulp-cli &&
+ npm install &&
+ ./node_modules/.bin/gulp
+ generate:
+ executor: build-env
+ working_directory: /home/vscode/src/janus-gateway
+ steps:
+ - checkout
+ - generate
+ - run: git diff --exit-code
+ bazel:
+ executor: build-env
+ working_directory: /home/vscode/src/janus-gateway
+ steps:
+ - checkout
+ - restore_cache:
+ keys:
+ - v3-bazel-cache-{{ checksum "repositories.bzl" }}
+ - v3-bazel-cache-
+ - configure_bazel
+ - run:
+ name: Check that Bazel BUILD files are up-to-date
+ command: |
+ bazel run //:gazelle &&
+ git diff --exit-code
+ - run:
+ name: Check that repositories.bzl is up-to-date
+ command: |
+ bazel run //:gazelle -- update-repos -from_file=go.mod -to_macro=repositories.bzl%go_repositories &&
+ git diff --exit-code
+ - run:
+ name: Check formatting of Bazel BUILD files
+ command: |
+ bazel run //:buildifier &&
+ git diff --exit-code
+ - run:
+ name: Run tests with Bazel
+ command: bazel test //...
+ - save_cache:
+ key: v3-bazel-cache-{{ checksum "repositories.bzl" }}
+ paths:
+ - /home/vscode/.cache/_janus_gateway_bazel
+ gorelease:
+ executor: build-env
+ working_directory: /home/vscode/src/janus-gateway
+ steps:
+ - checkout
+ - run:
+ name: Install gorelease outside local module
+ command: |
+ cd $(mktemp -d) &&
+ go mod init tmp &&
+ go get golang.org/x/exp/cmd/gorelease@latest
+ - run: gorelease -base=v2.8.0
+ push_bsr_plugins:
+ docker:
+ - image: circleci/golang
+ steps:
+ - setup_remote_docker
+ - checkout
+ - run: echo "${BUF_API_TOKEN}" | docker login --username grpcgatewaybot --password-stdin plugins.buf.build
+ - run: |
+ cd .circleci/plugins/protoc-gen-grpc-gateway &&
+ docker build -t plugins.buf.build/grpc-ecosystem/grpc-gateway:${CIRCLE_TAG}-1 --build-arg=RELEASE_VERSION=${CIRCLE_TAG} . &&
+ docker push plugins.buf.build/grpc-ecosystem/grpc-gateway:${CIRCLE_TAG}-1
+ - run: |
+ cd .circleci/plugins/protoc-gen-openapiv2 &&
+ docker build -t plugins.buf.build/grpc-ecosystem/openapiv2:${CIRCLE_TAG}-1 --build-arg=RELEASE_VERSION=${CIRCLE_TAG} . &&
+ docker push plugins.buf.build/grpc-ecosystem/openapiv2:${CIRCLE_TAG}-1
+ proto_lint:
+ docker:
+ - image: bufbuild/buf:1.1.0
+ steps:
+ - checkout
+ - run: buf build
+ - run: buf lint
+ - run: buf breaking --path protoc-gen-openapiv2/ --against 'https://github.com/grpc-ecosystem/grpc-gateway.git#branch=master'
+ proto_push:
+ docker:
+ - image: bufbuild/buf:1.1.0
+ steps:
+ - checkout
+ # Limit pushes to protoc-gen-openapiv2 files. This is a total hack.
+ # It excludes all the files that we don't want to publish, just for the push step.
+ - run: echo -e " - examples\n - internal\n - runtime" >> buf.yaml
+ - run: BUF_TOKEN="${BUF_API_TOKEN}" buf push --tag "$CIRCLE_SHA1"
+ release:
+ executor: build-env
+ working_directory: /home/vscode/src/janus-gateway
+ steps:
+ - checkout
+ - run: go mod vendor
+ - run: curl -sL https://git.io/goreleaser | bash
+ update-repositoriesbzl:
+ executor: build-env
+ working_directory: /home/vscode/src/janus-gateway
+ steps:
+ - checkout
+ - restore_cache:
+ keys:
+ - v3-bazel-cache-{{ checksum "repositories.bzl" }}
+ - v3-bazel-cache-
+ - configure_bazel
+ - run:
+ name: Update repositories.bzl
+ command: |
+ bazel run //:gazelle -- update-repos -from_file=go.mod -to_macro=repositories.bzl%go_repositories
+ - renovate_git_amend_push
+ regenerate:
+ executor: build-env
+ working_directory: /home/vscode/src/janus-gateway
+ steps:
+ - checkout
+ - generate
+ - renovate_git_amend_push
+workflows:
+ version: 2
+ all:
+ jobs:
+ - build
+ - test
+ - node_test
+ - generate
+ - bazel
+ - gorelease
+ - proto_lint
+ - proto_push:
+ filters:
+ branches:
+ only: /^master$/
+ - release:
+ filters:
+ branches:
+ ignore: /.*/
+ tags:
+ only: /v[0-9]+(\.[0-9]+)*(-.*)*/
+ - push_bsr_plugins:
+ filters:
+ branches:
+ ignore: /.*/
+ tags:
+ only: /v[0-9]+(\.[0-9]+)*(-.*)*/
+ - update-repositoriesbzl:
+ filters:
+ branches:
+ only: /renovate\/master-.+/
+ tags:
+ ignore: /.*/
+ - regenerate:
+ requires:
+ # Run after update-repositoriesbzl to avoid
+ # git conflicts
+ - update-repositoriesbzl
+ filters:
+ branches:
+ only: /renovate\/master-.+/
+ tags:
+ ignore: /.*/
diff --git a/.circleci/plugins/protoc-gen-grpc-gateway/Dockerfile b/.circleci/plugins/protoc-gen-grpc-gateway/Dockerfile
new file mode 100644
index 0000000..baf7d3a
--- /dev/null
+++ b/.circleci/plugins/protoc-gen-grpc-gateway/Dockerfile
@@ -0,0 +1,13 @@
+FROM golang:1.18.0 as builder
+
+ARG RELEASE_VERSION
+
+# Buf plugins must be built for linux/amd64
+ENV GOOS=linux GOARCH=amd64 CGO_ENABLED=0
+RUN go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@${RELEASE_VERSION}
+
+FROM scratch
+
+COPY --from=builder /go/bin/protoc-gen-grpc-gateway /usr/local/bin/protoc-gen-grpc-gateway
+
+ENTRYPOINT ["/usr/local/bin/protoc-gen-grpc-gateway"]
diff --git a/.circleci/plugins/protoc-gen-openapiv2/Dockerfile b/.circleci/plugins/protoc-gen-openapiv2/Dockerfile
new file mode 100644
index 0000000..2b9115e
--- /dev/null
+++ b/.circleci/plugins/protoc-gen-openapiv2/Dockerfile
@@ -0,0 +1,13 @@
+FROM golang:1.18.0 as builder
+
+ARG RELEASE_VERSION
+
+# Buf plugins must be built for linux/amd64
+ENV GOOS=linux GOARCH=amd64 CGO_ENABLED=0
+RUN go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@${RELEASE_VERSION}
+
+FROM scratch
+
+COPY --from=builder /go/bin/protoc-gen-openapiv2 /usr/local/bin/protoc-gen-openapiv2
+
+ENTRYPOINT ["/usr/local/bin/protoc-gen-openapiv2"]
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 0000000..0386e5f
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,25 @@
+// For format details, see https://aka.ms/devcontainer.json.
+{
+ "name": "Go",
+ "build": {
+ "dockerfile": "../.circleci/Dockerfile",
+ "args": {
+ "NODE_VERSION": "10"
+ }
+ },
+ "settings": {
+ "editor.formatOnSave": true,
+ "go.toolsManagement.checkForUpdates": "local",
+ "go.useLanguageServer": true,
+ "go.gopath": "/go",
+ "go.goroot": "/usr/local/go",
+ "bazel.buildifierExecutable": "/go/bin/buildifier",
+ "bazel.buildifierFixOnFormat": true,
+ "bazel.enableCodeLens": true,
+ },
+ "extensions": [
+ "golang.Go",
+ "bazelbuild.vscode-bazel",
+ ],
+ "remoteUser": "vscode"
+}
diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
new file mode 100644
index 0000000..d31e87f
--- /dev/null
+++ b/.github/workflows/go.yml
@@ -0,0 +1,37 @@
+name: Go
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+jobs:
+
+ build:
+ name: Build
+ runs-on: ubuntu-latest
+ steps:
+
+ - name: Set up Go 1.x
+ uses: actions/setup-go@v2
+ with:
+ go-version: ^1.13
+ id: go
+
+ - name: Check out code into the Go module directory
+ uses: actions/checkout@v2
+
+ - name: Get dependencies
+ run: |
+ go get -v -t -d ./...
+ if [ -f Gopkg.toml ]; then
+ curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
+ dep ensure
+ fi
+
+ - name: Build
+ run: go build -v .
+
+ - name: Test
+ run: go test -v .
diff --git a/.gitignore b/.gitignore
index 9bb694f..82c6465 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,7 +14,7 @@ _output/
# Bazel.
bazel-bin
bazel-genfiles
-bazel-ease-gateway
+bazel-janus-gateway
bazel-out
bazel-testlogs
*.bin
@@ -29,3 +29,6 @@ bin/
# Java files
*.exe
target/
+
+# vscode
+.vscode/
diff --git a/.goreleaser.yml b/.goreleaser.yml
index 9e1ee2a..02aad00 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -1,5 +1,6 @@
builds:
- main: ./gateway/protoc-gen-grpc-gateway/main.go
+ id: protoc-gen-grpc-gateway
binary: protoc-gen-grpc-gateway
env:
- CGO_ENABLED=0
@@ -9,8 +10,9 @@ builds:
- windows
goarch:
- amd64
- - main: ./gateway/protoc-gen-swagger/main.go
- binary: protoc-gen-swagger
+ - main: ./gateway/protoc-gen-openapiv2/main.go
+ id: protoc-gen-openapiv2
+ binary: protoc-gen-openapiv2
env:
- CGO_ENABLED=0
goos:
@@ -19,9 +21,9 @@ builds:
- windows
goarch:
- amd64
-archive:
- name_template: "{{ .Binary }}-{{ .Tag }}-{{ .Os }}-{{ .Arch }}"
- format: binary
- replacements:
- amd64: x86_64
+archives:
+ - name_template: "{{ .Binary }}-{{ .Tag }}-{{ .Os }}-{{ .Arch }}"
+ format: binary
+ replacements:
+ amd64: x86_64
dist: _output
diff --git a/BUILD b/BUILD
index f74a4eb..581db5d 100644
--- a/BUILD
+++ b/BUILD
@@ -1,5 +1,9 @@
load("@bazel_gazelle//:def.bzl", "gazelle")
load("@com_github_bazelbuild_buildtools//buildifier:def.bzl", "buildifier")
+load("@io_bazel_rules_go//proto:compiler.bzl", "go_proto_compiler")
+load("@io_bazel_rules_go//proto/wkt:well_known_types.bzl", "PROTO_RUNTIME_DEPS", "WELL_KNOWN_TYPES_APIV2")
+
+exports_files(["LICENSE.txt"])
buildifier(
name = "buildifier",
@@ -10,9 +14,45 @@ buildifier(
mode = "check",
)
-# gazelle:exclude third_party
-# gazelle:exclude vendor
# gazelle:exclude _output
-# gazelle:prefix github.com/binchencoder/ease-gateway
+# gazelle:prefix github.com/binchencoder/janus-gateway/gateway
+# gazelle:go_proto_compilers //:go_apiv2
+# gazelle:go_grpc_compilers //:go_apiv2, //:go_grpc
+# gazelle:go_naming_convention import_alias
gazelle(name = "gazelle")
+
+package_group(
+ name = "generators",
+ packages = [
+ "//gateway/protoc-gen-grpc-gateway/...",
+ "//gateway/protoc-gen-openapiv2/...",
+ ],
+)
+
+go_proto_compiler(
+ name = "go_apiv2",
+ options = [
+ "paths=source_relative",
+ ],
+ plugin = "@org_golang_google_protobuf//cmd/protoc-gen-go",
+ suffix = ".pb.go",
+ visibility = ["//visibility:public"],
+ deps = PROTO_RUNTIME_DEPS + WELL_KNOWN_TYPES_APIV2,
+)
+
+go_proto_compiler(
+ name = "go_grpc",
+ options = [
+ "paths=source_relative",
+ "require_unimplemented_servers=false",
+ ],
+ plugin = "@org_golang_google_grpc_cmd_protoc_gen_go_grpc//:protoc-gen-go-grpc",
+ suffix = "_grpc.pb.go",
+ visibility = ["//visibility:public"],
+ deps = PROTO_RUNTIME_DEPS + [
+ "@org_golang_google_grpc//:go_default_library",
+ "@org_golang_google_grpc//codes:go_default_library",
+ "@org_golang_google_grpc//status:go_default_library",
+ ],
+)
diff --git a/Issues.md b/Issues.md
new file mode 100644
index 0000000..f38b53e
--- /dev/null
+++ b/Issues.md
@@ -0,0 +1,71 @@
+# Issues
+
+## 依赖版本问题
+
+1. org_golang_google_grpc
+ ```go
+ go_repository(
+ name = "org_golang_google_grpc",
+ importpath = "google.golang.org/grpc",
+ sum = "h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=",
+ version = "v1.27.1",
+ )
+ ```
+
+ ```go
+ go_repository(
+ name = "org_golang_google_grpc",
+ importpath = "google.golang.org/grpc",
+ sum = "h1:DGeFlSan2f+WEtCERJ4J9GJWk15TxUi8QGagfI87Xyc=",
+ version = "v1.33.1",
+ )
+ ```
+
+ org_golang_google_grpc 最新版本已经升级到v1.33.1,编译会出现如下error:
+
+ ```verilog
+ chenbin@chenbin-ThinkPad:~/.../github-workspace/janus-gateway$ bazel build gateway/...
+ ERROR: /home/chenbin/.cache/bazel/_bazel_chenbin/95d98bab223e52f58e53a4599e22df3c/external/com_github_binchencoder_skylb_api/balancer/BUILD:5:1: no such package '@org_golang_google_grpc//naming': BUILD file not found in directory 'naming' of external repository @org_golang_google_grpc. Add a BUILD file to a directory to mark it as a package. and referenced by '@com_github_binchencoder_skylb_api//balancer:go_default_library'
+ ERROR: Analysis of target '//gateway/runtime:go_default_test' failed; build aborted: no such package '@org_golang_google_grpc//naming': BUILD file not found in directory 'naming' of external repository @org_golang_google_grpc. Add a BUILD file to a directory to mark it as a package.
+ INFO: Elapsed time: 3.781s
+ INFO: 0 processes.
+ FAILED: Build did NOT complete successfully (43 packages loaded, 588 targets configured)
+ ```
+
+2. org_golang_google_grpc_cmd_protoc_gen_go_grpc
+
+ ```go
+ go_repository(
+ name = "org_golang_google_grpc_cmd_protoc_gen_go_grpc",
+ importpath = "google.golang.org/grpc/cmd/protoc-gen-go-grpc",
+ sum = "h1:KNluVV5ay+orsSPJ6XTpwJQ8qBhrBkOTmtBFGeDlBcY=",
+ version = "v0.0.0-20200527211525-6c9e30c09db2",
+ )
+ ```
+
+ ```go
+ go_repository(
+ name = "org_golang_google_grpc_cmd_protoc_gen_go_grpc",
+ importpath = "google.golang.org/grpc/cmd/protoc-gen-go-grpc",
+ sum = "h1:lQ+dE99pFsb8osbJB3oRfE5eW4Hx6a/lZQr8Jh+eoT4=",
+ version = "v1.0.0",
+ )
+ ```
+
+ github.com/grpc-ecosystem/grpc-gateway 使用 org_golang_google_grpc_cmd_protoc_gen_go_grpc的版本是v1.0.0,janus-gateway 升级会出现如下error:
+
+ ```verilog
+ chenbin@chenbin-ThinkPad:~/.../github-workspace/janus-gateway$ bazel build gateway/...
+ INFO: Analyzed 32 targets (103 packages loaded, 1391 targets configured).
+ INFO: Found 32 targets...
+ ERROR: /home/chenbin/.cache/bazel/_bazel_chenbin/95d98bab223e52f58e53a4599e22df3c/external/com_github_grpc_ecosystem_grpc_gateway/runtime/internal/examplepb/BUILD.bazel:39:1: GoCompilePkg external/com_github_grpc_ecosystem_grpc_gateway/runtime/internal/examplepb/go_default_library.a failed (Exit 1) builder failed: error executing command bazel-out/host/bin/external/go_sdk/builder compilepkg -sdk external/go_sdk -installsuffix linux_amd64 -src ... (remaining 67 argument(s) skipped)
+
+ Use --sandbox_debug to see verbose messages from the sandbox
+ /home/chenbin/.cache/bazel/_bazel_chenbin/95d98bab223e52f58e53a4599e22df3c/sandbox/linux-sandbox/845/execroot/com_github_binchencoder_janus_gateway/bazel-out/k8-fastbuild/bin/external/com_github_grpc_ecosystem_grpc_gateway/runtime/internal/examplepb/examplepb_go_proto_/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/internal/examplepb/non_standard_names_grpc.pb.go:14:11: undefined: grpc.SupportPackageIsVersion7
+ compilepkg: error running subcommand external/go_sdk/pkg/tool/linux_amd64/compile: exit status 2
+ INFO: Elapsed time: 11.320s, Critical Path: 1.12s
+ INFO: 5 processes: 5 linux-sandbox.
+ FAILED: Build did NOT complete successfully
+ ```
+
+
\ No newline at end of file
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..3645162
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,27 @@
+Copyright (c) 2015, Gengo, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Gengo, Inc. nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
index 1e03d24..e08868f 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# ease-gateway
+# Janus-gateway
Gateway service based on [grpc-ecosystem/grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway). This helps you provide your APIs in both gRPC and RESTful style at the same time.
@@ -8,54 +8,44 @@ Gateway service based on [grpc-ecosystem/grpc-gateway](https://github.com/grpc-e
**grpc-gateway** 的出现更能引起开发者对使用gRPC的兴趣, 她可以帮你在原有gRPC服务的基础上做少量的改动, 便可以将原gRPC服务同时提供RESTful HTTP API, 了解更多RESTful API的例子可以参考[GitHub REST API](https://developer.github.com/v3/) 、[Google REST API](https://developers.google.com/drive/v2/reference/)
-**ease-gateway** 是站在巨人的肩膀上实现的, 增加了更符合企业级应用开发的**Features**:
+**janus-gateway** 是站在巨人的肩膀上实现的, 增加了更符合企业级应用开发的**Features**:
- 支持自定义的LoadBalancer
- 既可以部署单机版模式, 也可注册到注册中心实现集群模式
- 支持网关层的Parameter Validation Rules
- 支持自定义的Annotaion
-## Prepared
+## Architecture
-**ease-gateway** 在编译时需要依赖其他的repo, 为了编译时方便, 在WORKSPACE中定义的是依赖本地的repository, 这样在`bazel build` 时就不会再次从远程仓库下载代码. 因此在编译ease-gateway 之前需要将依赖的repositories下载到本地, 并放在与ease-gateway的同级目录
+
-目前依赖本地的repo有:
+## Design
-- gateway-proto [https://github.com/binchencoder/gateway-proto]
-- letsgo [https://github.com/binchencoder/letsgo.git]
-- skylb-api [https://github.com/binchencoder/skylb-api.git]
+[design.md](https://github.com/binchencoder/janus-gateway/tree/master/docs/design.md)
-```
-git clone https://github.com/binchencoder/gateway-proto.git
-git clone https://github.com/binchencoder/letsgo.git
-git clone https://github.com/binchencoder/skylb-api.git
-```
+## Validation Rule
-## Clone code
+[gateway-validation-rule.md](https://github.com/binchencoder/janus-gateway/tree/master/docs/gateway-validation-rule.md)
-```
-git clone https://github.com/binchencoder/ease-gateway.git
+## Prepared
-git clone https://github.com/binchencoder/gateway-proto.git
-git clone https://github.com/binchencoder/letsgo.git
-git clone https://github.com/binchencoder/skylb-api.git
-```
-> 也可以连同submodules一起clone到本地
-```
-git clone --recurse-submodules https://github.com/binchencoder/ease-gateway.git
-```
+**janus-gateway** 使用GO MOD来管理Dependencies,clone代码之后直接在本地使用bazel构建
-## Sync submodule
+### Build tools
-```
-git submodule init
-git submodule update
+- Bazel 3.1.0+
+- Go 1.13.12+
+
+## Clone code
+
+```shell
+git clone https://github.com/binchencoder/janus-gateway.git
```
## Bazel build gateway
```
-cd ease-gateway
+cd janus-gateway
bazel build cmd/gateway/...
```
@@ -66,4 +56,4 @@ TODO
## Run Examples
-See [examples/README.md](https://github.com/binchencoder/ease-gateway/tree/master/examples)
+See [examples/README.md](https://github.com/binchencoder/janus-gateway/tree/master/examples)
diff --git a/WORKSPACE b/WORKSPACE
index eddb400..a4bb804 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -1,61 +1,96 @@
-workspace(name = "com_github_binchencoder_ease_gateway")
+workspace(name = "com_github_binchencoder_janus_gateway")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
+
+# Define before rules_proto, otherwise we receive the version of com_google_protobuf from there
+http_archive(
+ name = "com_google_protobuf",
+ sha256 = "b07772d38ab07e55eca4d50f4b53da2d998bb221575c60a4f81100242d4b4889",
+ strip_prefix = "protobuf-3.20.0",
+ urls = ["https://github.com/protocolbuffers/protobuf/archive/v3.20.0.tar.gz"],
+)
+
+http_archive(
+ name = "bazel_skylib",
+ sha256 = "f7be3474d42aae265405a592bb7da8e171919d74c16f082a5457840f06054728",
+ urls = [
+ "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.2.1/bazel-skylib-1.2.1.tar.gz",
+ "https://github.com/bazelbuild/bazel-skylib/releases/download/1.2.1/bazel-skylib-1.2.1.tar.gz",
+ ],
+)
+
+load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
+
+bazel_skylib_workspace()
+
+http_archive(
+ name = "rules_proto",
+ sha256 = "66bfdf8782796239d3875d37e7de19b1d94301e8972b3cbd2446b332429b4df1",
+ strip_prefix = "rules_proto-4.0.0",
+ urls = [
+ "https://mirror.bazel.build/github.com/bazelbuild/rules_proto/archive/refs/tags/4.0.0.tar.gz",
+ "https://github.com/bazelbuild/rules_proto/archive/refs/tags/4.0.0.tar.gz",
+ ],
+)
+
+load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")
+
+rules_proto_dependencies()
+
+rules_proto_toolchains()
-# ----------从github下载扩展 io_bazel_rules_go ----------
http_archive(
name = "io_bazel_rules_go",
- sha256 = "7b9bbe3ea1fccb46dcfa6c3f3e29ba7ec740d8733370e21cdc8937467b4a4349",
+ sha256 = "f2dcd210c7095febe54b804bb1cd3a58fe8435a909db2ec04e31542631cf715c",
urls = [
- "https://github.com/bazelbuild/rules_go/releases/download/v0.22.4/rules_go-v0.22.4.tar.gz",
+ "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.31.0/rules_go-v0.31.0.zip",
+ "https://github.com/bazelbuild/rules_go/releases/download/v0.31.0/rules_go-v0.31.0.zip",
],
)
# ---------- bazel_gazelle ----------
# 一般来说都会使用gazelle工具来自动生成 BUILD 文件, 而不是手写.
-http_archive(
+# http_archive(
+# name = "bazel_gazelle",
+# sha256 = "b85f48fa105c4403326e9525ad2b2cc437babaa6e15a3fc0b1dbab0ab064bc7c",
+# urls = [
+# "https://storage.googleapis.com/bazel-mirror/github.com/bazelbuild/bazel-gazelle/releases/download/v0.22.2/bazel-gazelle-v0.22.2.tar.gz",
+# "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.22.2/bazel-gazelle-v0.22.2.tar.gz",
+# ],
+# )
+
+# TODO: Revert https://github.com/grpc-ecosystem/grpc-gateway/pull/2578/commits/fb9b59be7f2408767657c83c5002bf700ac7c460 once
+# https://github.com/bazelbuild/bazel-gazelle/pull/1194 is merged
+git_repository(
name = "bazel_gazelle",
- sha256 = "d8c45ee70ec39a57e7a05e5027c32b1576cc7f16d9dd37135b0eddde45cf1b10",
- urls = [
- "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.20.0/bazel-gazelle-v0.20.0.tar.gz",
- ],
+ commit = "f377e6eff8e24508feb1a34b1e5e681982482a9f",
+ remote = "https://github.com/bazelbuild/bazel-gazelle",
+ shallow_since = "1648046534 -0400",
)
# 从下载的扩展里载入 go_rules_dependencies go_register_toolchains 函数
load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
-
# 注册一堆常用依赖 如github.com/google/protobuf golang.org/x/net
go_rules_dependencies()
-
# 下载golang工具链
-go_register_toolchains()
+go_register_toolchains(version = "1.17.2")
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")
-# 加载gazelle依赖
-gazelle_dependencies()
-
# Use gazelle to declare Go dependencies in Bazel.
# gazelle:repository_macro repositories.bzl%go_repositories
+
load("//:repositories.bzl", "go_repositories")
go_repositories()
-# load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
-
-# git_repository(
-# name = "com_google_protobuf",
-# commit = "09745575a923640154bcf307fba8aedff47f240a",
-# remote = "https://github.com/protocolbuffers/protobuf",
-# shallow_since = "1558721209 -0700",
-# )
+# 加载gazelle依赖
+# This must be invoked after our explicit dependencies
+# See https://github.com/bazelbuild/bazel-gazelle/issues/1115.
+gazelle_dependencies()
-go_repository(
- name = "com_google_protobuf",
- importpath = "github.com/protocolbuffers/protobuf",
- sum = "h1:QbxPofk2041MRNYwie5F79xezBbVhMzoWy23+dKfgMY=",
- version = "v3.9.0+incompatible",
-)
+load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
@@ -64,43 +99,15 @@ protobuf_deps()
# ---------- com_github_bazelbuild_buildtools ----------
http_archive(
name = "com_github_bazelbuild_buildtools",
- sha256 = "86592d703ecbe0c5cbb5139333a63268cf58d7efd2c459c8be8e69e77d135e29",
- strip_prefix = "buildtools-0.26.0",
- urls = ["https://github.com/bazelbuild/buildtools/archive/0.26.0.tar.gz"],
+ sha256 = "7f43df3cca7bb4ea443b4159edd7a204c8d771890a69a50a190dc9543760ca21",
+ strip_prefix = "buildtools-5.0.1",
+ urls = ["https://github.com/bazelbuild/buildtools/archive/5.0.1.tar.gz"],
)
load("@com_github_bazelbuild_buildtools//buildifier:deps.bzl", "buildifier_dependencies")
buildifier_dependencies()
-go_repository(
- name = "org_golang_x_net",
- importpath = "golang.org/x/net",
- sum = "h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=",
- version = "v0.0.0-20200625001655-4c5254603344",
-)
-
-go_repository(
- name = "org_golang_x_sys",
- importpath = "golang.org/x/sys",
- sum = "h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo=",
- version = "v0.0.0-20200625212154-ddb9806d33ae",
-)
-
-go_repository(
- name = "org_golang_x_text",
- importpath = "golang.org/x/text",
- sum = "h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=",
- version = "v0.3.3",
-)
-
-go_repository(
- name = "org_golang_x_tools",
- importpath = "golang.org/x/tools",
- sum = "h1:/e4fNMHdLn7SQSxTrRZTma2xjQW6ELdxcnpqMhpo9X4=",
- version = "v0.0.0-20200702044944-0cc1aa72b347",
-)
-
# ---------- local repositories
# local_repository(
# name = "com_github_binchencoder_gateway_proto",
diff --git a/cmd/custom-gateway/BUILD.bazel b/cmd/custom-gateway/BUILD.bazel
index a98d5c1..0ae5f8e 100644
--- a/cmd/custom-gateway/BUILD.bazel
+++ b/cmd/custom-gateway/BUILD.bazel
@@ -3,7 +3,7 @@ package(default_visibility = ["//visibility:public"])
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
go_binary(
- name = "custom-ease-gateway",
+ name = "custom-janus-gateway",
embed = [":go_default_library"],
)
@@ -13,11 +13,12 @@ go_library(
"main.go",
"registrydemo.go",
],
- importpath = "github.com/binchencoder/ease-gateway/cmd/custom-gateway",
+ importpath = "github.com/binchencoder/janus-gateway/cmd/custom-gateway",
deps = [
- "//examples/proto:go_default_library",
- "//gateway/runtime:go_default_library",
+ "//examples/internal/proto/examplepb",
+ "//gateway/runtime",
"//integrate:go_default_library",
+ "//util:go_default_library",
"@com_github_binchencoder_gateway_proto//data:go_default_library",
"@com_github_binchencoder_letsgo//:go_default_library",
"@com_github_golang_glog//:go_default_library",
diff --git a/cmd/custom-gateway/main.go b/cmd/custom-gateway/main.go
index 26f65e5..ef9df18 100644
--- a/cmd/custom-gateway/main.go
+++ b/cmd/custom-gateway/main.go
@@ -9,8 +9,9 @@ import (
"github.com/golang/glog"
- "github.com/binchencoder/ease-gateway/gateway/runtime"
- "github.com/binchencoder/ease-gateway/integrate"
+ "github.com/binchencoder/janus-gateway/gateway/runtime"
+ "github.com/binchencoder/janus-gateway/integrate"
+ "github.com/binchencoder/janus-gateway/util"
"github.com/binchencoder/gateway-proto/data"
"github.com/binchencoder/letsgo"
)
@@ -21,10 +22,10 @@ var (
)
func usage() {
- fmt.Println(`EaseGateway - Ease Gateway of binchencoder.
+ fmt.Println(`JanusGateway - Janus Gateway of binchencoder.
Usage:
- ease-gateway [options]
+ janus-gateway [options]
Options:`)
@@ -34,6 +35,8 @@ Options:`)
func startHTTPGateway(mux *runtime.ServeMux, hostPort string) {
if err := http.ListenAndServe(hostPort, integrate.HttpMux(mux)); err != nil {
+ glog.Errorf("Start http gateway error: %v", err)
+ shutdown()
panic(err)
}
}
@@ -45,20 +48,29 @@ func main() {
// debugMode := flag.Lookup("debug-mode")
// debugMode.Value.Set("true")
- runtime.CallerServiceId = data.ServiceId_EASE_GATEWAY
+ runtime.CallerServiceId = data.ServiceId_JANUS_GATEWAY
// integrate.SetAllowCredentials(true)
// integrate.SetAllowHostsRegexp([]string{"*"})
- glog.Info("***** Ease gateway init. *****")
+ glog.Info("***** Janus gateway init. *****")
hostPort := fmt.Sprintf("%s:%d", *host, *port)
mux := runtime.NewServeMux()
runtime.SetGatewayServiceHook(integrate.NewGatewayHook(mux, hostPort))
- glog.Infof("***** Starting custom ease-gateway at %s. *****", hostPort)
+ glog.Infof("***** Starting custom janus-gateway at %s. *****", hostPort)
signals := make(chan os.Signal, 1)
signal.Notify(signals, os.Interrupt, os.Kill)
- startHTTPGateway(mux, hostPort)
+ go startHTTPGateway(mux, hostPort)
+
+ select {
+ case <-signals:
+ shutdown()
+ }
+}
+
+func shutdown() {
+ util.Flush()
}
diff --git a/cmd/custom-gateway/registrydemo.go b/cmd/custom-gateway/registrydemo.go
index 19dc9c1..e314c16 100755
--- a/cmd/custom-gateway/registrydemo.go
+++ b/cmd/custom-gateway/registrydemo.go
@@ -2,5 +2,5 @@ package main
// Import so that applications register themselves to gateway.
import (
- _ "github.com/binchencoder/ease-gateway/examples/proto"
+ _ "github.com/binchencoder/janus-gateway/examples/internal/proto/examplepb"
)
diff --git a/cmd/gateway/BUILD.bazel b/cmd/gateway/BUILD.bazel
index b7a3a43..5d20127 100644
--- a/cmd/gateway/BUILD.bazel
+++ b/cmd/gateway/BUILD.bazel
@@ -2,35 +2,35 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_tar")
go_library(
- name = "ease-gateway",
+ name = "janus-gateway",
srcs = [
"main.go",
"registryprod.go",
],
- importpath = "github.com/binchencoder/ease-gateway/cmd/gateway",
+ importpath = "github.com/binchencoder/janus-gateway/cmd/gateway",
visibility = ["//visibility:public"],
deps = [
- "//gateway/runtime:go_default_library",
+ "//proto/examplepb",
+ "//gateway/runtime",
"//integrate:go_default_library",
- "//proto/examples:go_default_library",
"//util:go_default_library",
"@com_github_binchencoder_gateway_proto//data:go_default_library",
"@com_github_binchencoder_letsgo//:go_default_library",
"@com_github_binchencoder_letsgo//service/naming:go_default_library",
- "@com_github_golang_glog//:go_default_library",
+ "@com_github_golang_glog//:glog",
],
)
# pkg_tar(
-# name = "ease-gateway-tar",
+# name = "janus-gateway-tar",
# srcs = [
-# ":ease-gateway",
+# ":janus-gateway",
# ],
-# package_dir = "/ease-gateway/bin",
+# package_dir = "/janus-gateway/bin",
# )
go_binary(
name = "gateway",
- embed = [":ease-gateway"],
+ embed = [":janus-gateway"],
visibility = ["//visibility:public"],
)
diff --git a/cmd/gateway/main.go b/cmd/gateway/main.go
index 826ccf3..19ece71 100644
--- a/cmd/gateway/main.go
+++ b/cmd/gateway/main.go
@@ -9,27 +9,27 @@ import (
"github.com/golang/glog"
- "github.com/binchencoder/ease-gateway/gateway/runtime"
- "github.com/binchencoder/ease-gateway/integrate"
- "github.com/binchencoder/ease-gateway/util"
"github.com/binchencoder/gateway-proto/data"
+ "github.com/binchencoder/janus-gateway/gateway/runtime"
+ "github.com/binchencoder/janus-gateway/integrate"
+ "github.com/binchencoder/janus-gateway/util"
"github.com/binchencoder/letsgo"
"github.com/binchencoder/letsgo/service/naming"
)
var (
- host = flag.String("host", "", "The ease-gateway service host ")
- port = flag.Int("port", 8080, "The ease-gateway service port")
+ host = flag.String("host", "", "The janus-gateway service host ")
+ port = flag.Int("port", 8080, "The janus-gateway service port")
enableHTTPS = flag.Bool("enable-https", false, "Whether to enable https.")
certFile = flag.String("cert-file", "", "The TLS cert file.")
keyFile = flag.String("key-file", "", "The TLS key file.")
)
func usage() {
- fmt.Println(`Ease Gateway - Universal Gateway of xxx Inc.
+ fmt.Println(`Janus Gateway - Universal Gateway of xxx Inc.
Usage:
- ease-gateway [options]
+ janus-gateway [options]
Options:`)
@@ -72,7 +72,7 @@ func main() {
checkFlags()
hostPort := fmt.Sprintf("%s:%d", *host, *port)
- runtime.CallerServiceId = data.ServiceId_EASE_GATEWAY
+ runtime.CallerServiceId = data.ServiceId_JANUS_GATEWAY
serviceName, err := naming.ServiceIdToName(runtime.CallerServiceId)
if err != nil {
glog.Errorf("Invalid service id %d", runtime.CallerServiceId)
diff --git a/cmd/gateway/registryprod.go b/cmd/gateway/registryprod.go
index fc761a6..3bbe031 100755
--- a/cmd/gateway/registryprod.go
+++ b/cmd/gateway/registryprod.go
@@ -2,5 +2,5 @@ package main
// Import so that applications register themselves to gateway.
import (
- _ "github.com/binchencoder/ease-gateway/proto/examples"
+ _ "github.com/binchencoder/janus-gateway/proto/examplepb"
)
diff --git a/docs/design.md b/docs/design.md
new file mode 100644
index 0000000..1da7f9c
--- /dev/null
+++ b/docs/design.md
@@ -0,0 +1,224 @@
+# Janus-gatway - Enterprise Universal Gateway Service
+
+`janus-gateway` is a enterprise universal gateway service for mobile, native, and web apps.
+It's based on `grpc-gateway` and mobile team's gateway development experience.
+
+## Overview
+
+`janus-gateway` is a thin gateway layer on top of all front-end or APIs services. It's the single entrance for all enterprise internal services except the connection services (such as EIM connection layer, SSO, etc.). All clients access the gateway (through the reverse proxy or load balancer) with RESTful APIs, the gateway translates the requests to gRPC calls to the target services.
+
+
+
+> SkyLB is an external load balancer for gRPC which is able to load balance on
+> gRPC's long-lived connections. `janus-gateway` instances connect to SkyLB for endpoints
+> of the target services, and load balance the end-users' requests to the target
+> services.
+
+Based on this structure, `janus-gateway` provides foundamental functions to enterprise
+infrastructure such as user identity verification, API management, monitoring,
+and logging.
+
+## How does Janus-gateway Work?
+
+`janus-gateway` is based on the open-sourced `grpc-gateway` framework. The following
+diagram shows how grpc-gateway works:
+
+
+
+> So the first step starts from a protocol buffer definition file (written by
+> the target service's owner). For each gRPC service defined in the file, an
+> annotation can be added to describe its RESTful properties:
+
+
+
+The above code specifies that the client can call a RESTful API
+"https://apis.xxx.com/v1/example/echo" which is a HTTP POST and the
+request and response will be JSON objects.
+
+Once we have the proto file, grpc-gateway translates the RPC methods to both
+gateway and gRPC service stubs in Golang. The generated code can be easily
+hooked up with a HTTP server, and when HTTP requests arrive, it issues gRPC
+calls to the target service.
+
+`janus-gateway` is the project to create such a HTTP server to meet enterprise business
+needs.
+
+### Request Interception
+
+To make it easier to inject our business logic to the generated gateway stub,
+we modified the `grpc-gateway` template with a GatewayServiceHook interface:
+
+
+
+Four request hook functions are put in the proper places of the generated
+code:
+
+
+
+- RequestReceived()
+
+ The request just arrived at the gateway but the JSON payload has not
+ been unmarshaled. It's intended for operations like user identity
+ verification in which the information in the JSON payload is not needed.
+
+- RequestAccepted()
+
+ The request has been verified with legal user identity, but the JSON
+ payload has not yet been unmarshaled. It's the good place for
+ extracting user/enterprise information and return them in a map.
+
+- RequestParsed()
+
+ The JSON payload has been unmarshaled.
+
+- RequestHandled()
+
+ The request has been handled, whether it failed or succeeded. Logging
+ can be done in this function.
+
+### Service Register/Discovery with SkyLB
+
+SkyLB is enterprise external load balancer for gRPC services. When `grpc-gateway`
+translates the proto, it also generates a SkyLB client for each service. The
+SkyLB clients talk to the SkyLB to fetch service endpoints, and get notified
+when the service endpoints were changed so that it can do client side load
+balance properly. A typical SkyLB client example can be found at
+[janus-gateway demo](https://github.com/binchencoder/janus-gateway/tree/master/examples/gateway) (it also contains the `grpc-gateway` example).
+
+The GatewayServiceHook provides a Bootstrap() method for us to do
+initialization work (triggered by calling runtime.SetGatewayServiceHook() of
+`grpc-gateway`). In Bootstrap() we can create gRPC client for each service:
+
+```go
+svc.Register(context.Background(), gh.mux, gh.host, opts)
+if enabled_in_etcd {
+ svc.Enable() // Enable() creates a gRPC client.
+} else {
+ svc.Disable() // Disable() destroies the gRPC client.
+}
+```
+
+Thus we can enable/disable the APIs through ETCD. To keep fresh with service
+configs in ETCD, Janus should maintain a watcher to ETCD instance. See next
+section "Service Keeper" for more details.
+
+### Service Keeper
+
+Service information like enabled/disabled are configured as ETCD keys. Janus
+UI provides a user friendly interface to manage these keys. In Bootstrap()
+method we need to fetch service information from ETCD, and then create an ETCD
+watcher to get notified when service config changes.
+
+
+
+The service hook should cache the services information in memory, and handle
+requests according to the information. For those services which are not
+yet exiting in ETCD, default values are returned (so that such services are
+disabled by default).
+
+Note that ETCD v3 watcher itself is a gRPC stream call so it has ignorable
+connection overhead (long-live connection) and very low latency.
+
+### Customized Annotations
+
+#### Service IDs/Names
+
+All enterprise gRPC services should be registered with distinct enums in
+[gateway-proto/data/data.proto](https://github.com/binchencoder/gateway-proto/tree/master/data/data.proto). The enum value would be the service
+ID. For a service enum MY_SERVICE, its service name would be
+"my-service".
+
+> You can define a utility library to convert the service ID from/to service names.
+
+In gRPC service proto, engineers need to specify the service ID like this:
+
+```proto
+import "options/extension.proto";
+
+service Demo {
+ option (janus.api.service_spec) = {
+ service_id: JANUS_GATEWAY_DEMO
+ namespace: "default"
+ port_name: "grpc"
+ }
+ // RPC definitions below.
+}
+```
+
+The service spec is used by `grpc-gateway` to connect to SkyLB server and create
+gRPC clients.
+
+#### Field Validation
+
+When `grpc-gateway` translates the proto, it also generates validation logic
+for certain fields in request. If the validation failed, it returns HTTP 400
+(BAD REQUEST) directly to the caller.
+
+Engineers can annotate some fields as follows:
+
+```proto
+import "httpoptions/annotations.proto";
+
+// The request message for greeting.
+message GreetingRequest {
+ string name = 1 [
+ (janus.api.rules) = {
+ rules: {
+ type: STRING,
+ operator: NON_NIL,
+ },
+ rules: {
+ type: STRING,
+ function: TRIM,
+ operator: LEN_GT,
+ value: "5",
+ },
+ rules: {
+ type: STRING,
+ function: TRIM,
+ operator: LEN_LT,
+ value: "21",
+ }
+ }
+ ];
+}
+```
+
+The above option specifies that field "name" is a string with at least 5 chars
+and at most 20.
+
+### Monitoring with Prometheus
+
+For commonly used monitoring metrics, we can rely on the existing
+instrumentation in SkyLB client: QPS, latency, and error rate.
+
+We can add Janus customized instrumentation if needed.
+
+## Gateway Rollout Procedure
+
+When a new target service or service update is going to be added to `janus-gateway`,
+it has to following the following steps:
+
+1. Add a service enum if it's a new service.
+
+2. Change the proto file and create gateway bazel build target.
+
+3. Implement the gRPC service and push to production.
+
+4. Link the service to gateway if it's a new service. This can be easily done
+ by adding an anonymous import in `//janus-gateway/cmd/gateway/registryprod.go ` :
+
+ ```go
+ import (
+ _ "github.com/binchencoder/janus-gateway/proto/examples"
+ )
+ ```
+
+5. Rebuild the `janus-gateway` binary and push to production.
+
+
+## References
+
+https://github.com/grpc-ecosystem/grpc-gateway
+
+https://github.com/binchencoder/grpc-skylb
\ No newline at end of file
diff --git a/docs/gateway-validation-rule.md b/docs/gateway-validation-rule.md
new file mode 100644
index 0000000..20858ed
--- /dev/null
+++ b/docs/gateway-validation-rule.md
@@ -0,0 +1,157 @@
+# Janus-gateway Validation Rule
+
+## Rules Defination
+
+Validation Rule定义可以在这里找到:
+
+> janus-gateway/httpoptions/annotations.proto
+
+```protobuf
+// The opertaion type.
+enum OperatorType {
+ OPERATOR_TYPE_UNKNOWN = 0;
+
+ GT = 1; // Greater than
+ LT = 2; // Less than
+ EQ = 3; // Equals
+ MATCH = 4; // String pattern match.
+ NON_NIL = 5; // Not nil
+ LEN_GT = 6; // String length great than
+ LEN_LT = 7; // String length less than
+ LEN_EQ = 8; // String length equals
+}
+
+// The supported function type list
+enum FunctionType{
+ FUNCTION_TYPE_UNKNOWN = 0;
+
+ TRIM = 1; // String trim.
+}
+
+// ValueType is the type of the field.
+enum ValueType {
+ VALUE_TYPE_UNKNOWN = 0;
+
+ NUMBER = 1; // Represent all number type like int,real
+ STRING = 2; // String
+ OBJ = 3;
+}
+
+// ValidationRule defines the rule to validate the input value.
+message ValidationRule {
+ OperatorType operator = 1;
+ ValueType type = 2;
+ string value = 3;
+ FunctionType function = 4;
+}
+```
+
+> NOTE
+>
+> Validation Rule是作为Message's field的Extension Attribute。
+
+每一条Rule包括:
+
+* 类型
+* 操作符
+* 期待值
+* 函数(可选)
+
+## Samples
+
+```protobuf
+// The request message to be greeted.
+message Payment {
+ message SubPayment {
+ PaymentType type = 1;
+ // 100 > paied_amount > 10
+ int64 paied_amount = 2 [
+ (janus.api.rules) = {
+ rules: {
+ type:NUMBER,
+ operator: GT,
+ value:"10",
+ },
+ rules: {
+ type:NUMBER,
+ operator: LT,
+ value:"100",
+ },
+ }
+ ];
+ };
+
+ PaymentType type = 1;
+ // 长度=10
+ string message_value_len_eq = 3 [
+ (janus.api.rules) = {
+ rules: {
+ type:STRING,
+ operator: LEN_EQ,
+ value:"10",
+ },
+ }
+ ];
+
+ // 长度Trim之后小于21
+ string message_value_len_gt = 4 [
+ (janus.api.rules) = {
+ rules: {
+ type:STRING,
+ operator: LEN_LT,
+ value:"21",
+ function: TRIM,
+ },
+ }
+ ];
+}
+```
+
+更多例子可以以下目录找到:
+
+> janus-gateway/proto/examples/...
+
+## Implemention Details
+
+Validation Rule的定义会被编译到相呼应的xxx.gw.go文件中。每个类型会有一个Validation方法,如果这个类型包括任何Rule. 如果一个Field引用另外一个文件的类型(并且有Rule),那么生成的文件会引用相应的go package.
+
+这是一个生成代码的例子:
+
+```go
+
+func Validate__sharedproto_Payment(v *Payment) error {
+ if v == nil {
+ return nil
+ }
+ // Validation for each Fields
+
+ // Validation Field: Type
+
+ // Validation Field: Amount
+
+ if v.Amount <= 10 {
+ return janus_demo_proto_sharedproto_shared_error
+ }
+
+ if v.Amount >= 100 {
+ return janus_demo_proto_sharedproto_shared_error
+ }
+... ...
+ return nil
+}
+
+```
+
+## Add Validation Rule
+
+加一个新的操作符或者函数是比较简单的。可以查阅有关的CR.代码在:
+
+### Defination
+
+> janus-gateway/httpoptions/annotations.proto
+
+### Implementation Validation Rule
+
+> janus-gateway/gateway/protoc-gen-grpc-gateway/internal/gengateway/template.go
+
+所有Validation Rule的实现都在template.go 文件中, 搜索`validatorTemplate`, 参照现有实现Coding
\ No newline at end of file
diff --git a/docs/images/Arch.png b/docs/images/Arch.png
new file mode 100644
index 0000000..2ca913c
Binary files /dev/null and b/docs/images/Arch.png differ
diff --git a/docs/images/Janus-Gateway.drawio b/docs/images/Janus-Gateway.drawio
new file mode 100644
index 0000000..1019253
--- /dev/null
+++ b/docs/images/Janus-Gateway.drawio
@@ -0,0 +1 @@
+7V1td5u4Ev41+WgfJEDAx+bFbe9tt9k2p7fbLznYJjZbbLxAmri//koYYfSGZSxsJ133nMYIEOiZ0TOj0Ui+sK8Wz2+zcDX/mE6j5AJa0+cL+/oCQh/5+H9SsN4UAM92NyWzLJ5WZduCL/GvqCq0qtLHeBrlzIVFmiZFvGILJ+lyGU0KpizMsvSJvewhTdinrsJZJBR8mYSJWPq/eFrMq3ZBb1v+Lopnc/pkgILNmXE4+THL0sdl9bwLaD+Un83pRUjrqhqaz8Np+tQosm8u7KssTYvNt8XzVZQQbClsm/tGirP1e2fRstC5wa/eOy/WtO3RFENRHaZZMU9n6TJMbrall2X7IlIDwEfzYpFUX6Pl9A1BHx+Ok3TyY1M0ihN6wd9RUawrcYePRYqLto/4kKaruqIiW3/DB9bQpYd/kUN6cBtl8SIqoqwqFNtN1SbMZhEtsqvWkiY2rqqgeRuluMpsjS/IoiQs4p+sNoSVUs3q6+pbb9MYPxdaVQdwKulW6m9TtaY1bF6qumkrHYxduG5ctiIX5NqPgS5o1oa/bCqU3wyRy989dADwkONZru9Dx2bfOU8fs0kkvDP+0kBuW1TqmVznoOVsqv4ZJo8R7SecFpJOtBJ0TSnmn1FWRM8ybgjHtErrQiprepcHGTwGbnX8tCUAx6rK5s3ODznpNvWDgakFE+C55jDZAtwdleO0OvANakIN4cG6YPts1xAUoW49A4nlmVAEyyAkNb5GFKHHViMNRZiG+bxsrMVaHWxDV+SSxfOMeCPD8Cm3h+Eqvp+FRfRECPDyAZugqzRJs7Im+zp44znkVnzDNMZw0XPLdEkMXBKOo+SyNuWNO4NghD/koUWW/ogaZ6zyQ56VLovKxAG/Om5cNxpVNezWZ0shPDWHIZbCgKC4Hhq6ogwD24QIA0GEb27f44K3lRh4eeJGFawksyiPf1UaSaCsDCC+2r28cK9xCXEa8gpccpjEsyX+nkQPpCqCVIy9uDdVcUEcist8FU7i5eyu9C4Gzm4RbT6GRVTJxPf0yMQEvULLPkt6Bb7N6KkrQoI8ERLfNUGvopYKkLBQPM3jIvqCdYicfcIMw+osp4Ic00zDyH+YyPgCTfxo/KCw37YC6nZ67gs0aIGXAJrK6VHrYcDqITiiIkLqVDUwvQnzqIUvOyE8wQCRUVIHjEuWrB4PONZEpmRQ63o9DDmeDIoPn4u/4rGbvLn7+unjIv/v7SIe2OjMPHHqkyLAkqY7FKHqy5IokPLMIbVDFt3hWzN3nQwrVwMr6r58IO7nLfZzijglfXicFkW6UPo3TVe47Mw0ZAUlzvFDkj5N5mFWDNNM9Hwsy1O4t6ORf4MuuwvSUwiy1aL1JSLbEcE/IOyVFxhPGviqhhBlWRX5skyGxpos7LSFRPoOctmuGEDChTCookh68SMxLmVzwTNe4IaCZ/xzWqNnHaJcNg2gvQIdMxeO7V8poaCUW5W0XB9108o6dFxrJa7X2n5gLzrKPxVWrTOlo9DS8HX2cjt5H3GnG+pG/tSRGRwfjm0kdzNVMV+178RTlWUJ7gDwZYERI6Nw9HuAzE8ogCOCPFv+Ofn60/avHibv//72Drpelg5sxzmYgqX8KOFRuXigwinj5WCXgcU2OWyIimqUdxw2dRDLPy4NjJueyOKeYyNu1nK/6w/mRYU2yfoxSopNiHHJ6Bn65zEtKl0YbAKWb/AFwFk94z+loK3y3FPVEchZj9ASvRN/m5G/s8+3V/Qx+L03T9qcEpS7U0SVJw9+kLGIp9OkPSpeTXGLqr9rsNDebQ8fNFtDy6K11dy/OTywawwgOxwfAC4gkT485NGhU6VyfFzRszyYtLYuHuPgbf296+fmyet1dcT4pTeff0VZepd+DJdrzj/l0gMmSZjn8YTxUK1WZhRZlFe26DkuvtFH4e+NBuCj7fuTg3XjQNt5bXKwYphbKVcz60Ch48ZTEXRN5fc/J9mP95bz/o/5fPaf2WV+P8Bv7ohTBVk0i3NaeTvN6JPIbkLag2mqV9KZqmnvSYczzcAaAs9m59/sw5jGKJPUPoPSejXNjfUlyjAmunbHsPfKx51P4s16nDcLjzlkAN7BjquU24eu6zX5fVAaSNUovnu4QIPn9c2Ghv9cxy01/Wco0nQ9Fj4+I2NFUvbN8bbTbQpirqeusrRIx48Pjb4a8/fgsvGLcBpL9dk5qQJUweQurG0Bm5uBOiPW1pislna2ZuevvCJraONRU9MzCgD1jTp5QADZmh2mQZmuJKLvmvHI7YB19LFH7rB16Ab7sCFha3L1QtAdBExjJGYkjFxWwLb/mgTscFE8LGC3m4CdwD2WgGu/4aySXW3A9RVHEqyDtBsw028BFwLqlismjjb+mMXLZ1H3kyRe5cSQ0InMSZI+Tnd7mS35eaw7aVlBUOftyfL0FBaMSRVMs2mUcWf4JLOdZq3WFH0nleUpII24SpInAmRAhpRdjaVsLsJlOIsWGJB7rM55WvoPfOYmvN6M9xSZm2qx9wA/ZDuRLeYYUD1vgo9MJFu6GhM3+4GfjuMkup8kcYnIWeMOaFYNk6QuS2w1g7XG/M1+WD8mBTbH0zg8d6AR6xrLNBz1hLonov755svdwyO5qkwsNjGOkacTK4c1GgnFUGJL6oTiZmijN5lxixccSUZdX4k1wFNHmYSRLAGjdF0oTtupj3rR3LZIY3LFJpMr/PzJu7u7W/zaYAgao+HNo9sGyZuyafyTLzqwGVxlmeQtdF8OlzHvdwglzYtidV+GEnA7RFYiKRRXIzUrtftIemslaEi/cZ1zTf7JOmYf1pztNtS32mXNDbhS0DW5DErR7r3HCPVqV0r+2MQC1/MDx7OR70gyKgOJBXaCIb3ecjGC/DRZp/Q9+xwXEPILKl07kGToup4EJMgvEO2ECtCIFumisoXYyMqx/lpNU6Karf5UzMnchdWYy4gnUd6nx3DAAqT6uDHlsVM8tay16c2x2NEKEr0CWezGhFfgadDbXlNI4iwxsgN7KtqtqPwQOWUT6p/BgxFtYFYHHY0rtiKN3KClUDd5b+5DgOU+ACwJ99XxieOk3DsafPiKU+5d1drfVoU+8qoIWXB0t1td+Y+CW53/WCdjctMmiqFyqc/KDMhUQbbyahQu4oR0r3dR8jMi1R9DM2igUQws+n2tzbBlOnFCN6a6y+WG1YBxhi1fwnaygBTnDhtwgByNlUX9phd3Wa65FfNe9HS0IUY9Lni1qNbBVNZyiz39eJiLrnxKXHkwmGWrySDf+PHmxADPSAyQFYMk2+h4o2sN1T8BAePPEGFPE/m43TAIaBJPjdgQjwK2/zxxjgAz8tD3Pd+1HORBP5DMjHnOMMBeCXLo/yYI2vSWA/vq8A0aja6u9tZh/Zw5RktZiIGIsctjbCCEZkONrS5eNsh78PWJRCBG5Ur6hiek76NJJRgGjY/vs5nAUjo/jZRoXPvM2N1FbeRO4gn4tBc42A+3PVu2S8RpyN09Ne9cO9dAHj9o1XCoENx5knufKyjPAuTzJ3dxlFmSu31Ccj+WVHR88xORucENvo7nqhOqZn31s2HzUxPNaBSgS7S3SnfaL+xkVGJ6OujsQD5/NpcNSfdbygyBLNvmkKSY4XC4Owuml3VoUGfHNA2tUa6CYQP6RnTrpQw4FAsv9xiFiDNsx8uB8TjTj5BsXjOQzIUAYMAgta8d7oNAGztWMLqPEEJSWYjo75D4fntaehJoTZh6xUtqzD29ZGS1DdOxcZeFnBlLsjv702+zR3Xy5Jcf6w+7sipbZ4tfgfh3j2eOLf72fXqqNNKD97g4p70qFNtteLv229gu9vNddrUfcI671UWlDafY6qK6lVvVF3C0ZtMUhR2r+oSKkMtW5PL5XOZ+C0OxGYcYSf8dNuMwFn8gy7r5PaLoZvhnsa5bAQA6Cg2quId4rC9ns5/OvwJ0WpJyXbnxNU8t7TsUvfqkyL2n8FzqhNabbZ58f22N6O7vKSvEubAulK216Etakzvv0938+xOIvo6+L6M4LhJvn5BGf/EK7oeLXAhlsEBJNB0Ab2ggeUiRia0RVtedptgBvpHlKgqEUI8ItY+AomScPp3sJ/hqt6DaVsSFuwYpesa5XVn6tsTQgsPGDs4Wy/4DQHZ4Jj/4RCOsAfsAU9uQc3NjA2YXcnFHaIft4S17louPAuyjJF2+b++DrkV+XXuiO8jjesjuYfxL6CEg6KowYlXYElmgOWEh9jancZrf2cfUhuqQb5Gv7kDmtN7oLwH0wvBlDJLheGBGg9vNdXNcJr+SGsbedZ2nYQvyum6K8bl11dtepSb99ht28b7ygT3wvkLe2nkq/fnGwGI5p/wJhwveOZYta+LjiJ12xqCmrwHBx3Q5S6/FKQZxRNayfcN2cDYNMRZhuVmWbFqibd8rdfBuGmcY482YMgrzYp9O3ikrBUkEgHobtElGJv9KZe/ZwiPLTExF/Fdme0/xHVdmOpvF9W0A+KGWLUFFSv8mtrNyNOKu+20iFi0m4aS8nldIeOPZl2TLQeN7iO0Q7uFEbwBqBWmY/oHpl4n/YZTen3Q0Mpp+H+l0JO/epKOz2WT/3jvH3VCPux0TMdv6d9jM6ec6/ye5n47v42VehEviXZxcT1W/tbo/ixsBXcEUGiPJ30gSh/F5n3Iyvjvwa5BTR2bvIid8mKUkF3IbyCFgfkynEbni/w==
\ No newline at end of file
diff --git a/docs/images/Janus-Gateway.png b/docs/images/Janus-Gateway.png
new file mode 100644
index 0000000..69d1ae2
Binary files /dev/null and b/docs/images/Janus-Gateway.png differ
diff --git a/docs/images/code-snippet.png b/docs/images/code-snippet.png
new file mode 100644
index 0000000..9c83718
Binary files /dev/null and b/docs/images/code-snippet.png differ
diff --git a/docs/images/etcd.png b/docs/images/etcd.png
new file mode 100644
index 0000000..910a0d3
Binary files /dev/null and b/docs/images/etcd.png differ
diff --git a/docs/images/gateway-service-hook.png b/docs/images/gateway-service-hook.png
new file mode 100644
index 0000000..cf2e646
Binary files /dev/null and b/docs/images/gateway-service-hook.png differ
diff --git a/docs/images/mechanism.png b/docs/images/mechanism.png
new file mode 100644
index 0000000..41c263d
Binary files /dev/null and b/docs/images/mechanism.png differ
diff --git a/docs/images/request-flow.png b/docs/images/request-flow.png
new file mode 100644
index 0000000..9ed699c
Binary files /dev/null and b/docs/images/request-flow.png differ
diff --git a/docs/scripts/start.sh b/docs/scripts/start.sh
index 2047ede..6c31e93 100755
--- a/docs/scripts/start.sh
+++ b/docs/scripts/start.sh
@@ -29,16 +29,16 @@ fi
STDOUT_FILE=$HOMEDIR/std.out
set +e
-PIDS=`pgrep ^ease-gateway$`
+PIDS=`pgrep ^janus-gateway$`
if [ $? -eq 0 ]; then
- echo "ERROR: The service Ease Gateway already started!"
+ echo "ERROR: The service Janus Gateway already started!"
echo "PID: $PIDS"
exit 1
fi
set -e
-echo "Service Ease Gateway start..."
-nohup $HOMEDIR/bin/ease-gateway \
+echo "Service Janus Gateway start..."
+nohup $HOMEDIR/bin/janus-gateway \
-debug-svc-endpoint=vexillary-service=192.168.10.41:4100 \
-debug-svc-endpoint=pay-grpc-service=192.168.32.18:10008 \
-skylb-endpoints=$SKYLB_ENDPOINTS \
@@ -50,10 +50,10 @@ nohup $HOMEDIR/bin/ease-gateway \
sleep 2
-PIDS_COUNT=`pgrep ^ease-gateway$|wc -l`
+PIDS_COUNT=`pgrep ^janus-gateway$|wc -l`
if [ $PIDS_COUNT -eq 0 ]; then
- echo "ERROR: The service Ease Gateway does not started!"
+ echo "ERROR: The service Janus Gateway does not started!"
exit 1
fi
-echo "Service Ease Gateway start success!"
+echo "Service Janus Gateway start success!"
diff --git a/docs/scripts/stop.sh b/docs/scripts/stop.sh
index fbf0655..fd54eb6 100755
--- a/docs/scripts/stop.sh
+++ b/docs/scripts/stop.sh
@@ -1,13 +1,13 @@
#!/bin/sh
set +e
-PIDS=`pgrep ^ease-gateway$`
+PIDS=`pgrep ^janus-gateway$`
if [ $? -ne 0 ]; then
- echo "INFO: The service Ease Gateway did not started!"
+ echo "INFO: The service Janus Gateway did not started!"
exit 0
fi
-echo -e "Stopping the service Ease Gateway ...\c"
+echo -e "Stopping the service Janus Gateway ...\c"
for PID in $PIDS ; do
kill $PID > /dev/null 2>&1
done
@@ -15,11 +15,11 @@ done
while [ true ]; do
echo -e ".\c"
- IDS=`pgrep ^ease-gateway$`
+ IDS=`pgrep ^janus-gateway$`
if [ $? -ne 0 ]; then
echo
echo "PID: $PIDS"
- echo "Service Ease Gateway stopped."
+ echo "Service Janus Gateway stopped."
exit 0
fi
diff --git a/docs/spring-validation.md b/docs/spring-validation.md
new file mode 100644
index 0000000..aa32d42
--- /dev/null
+++ b/docs/spring-validation.md
@@ -0,0 +1,52 @@
+# Common Validation Annotations by Spring
+
+## @NotNull
+
+The annotated element must not be null. Accepts any type.
+
+## @Min
+
+The annotated element must be a number whose value must be higher or equal
+to the specified minimum.
+
+Supported types are: BigDecimal, BigInteger, byte, short, int, long, and their
+respective wrappers. Note that double and float are not supported due to
+rounding errors (some providers might provide some approximative support).
+
+null elements are considered valid.
+
+## @Max
+
+The annotated element must be a number whose value must be lower or equal
+to the specified maximum.
+
+Supported types are: BigDecimal, BigInteger, byte, short, int, long, and their
+respective wrappers. Note that double and float are not supported due to
+rounding errors (some providers might provide some approximative support).
+
+null elements are considered valid.
+
+## @Size(min = 0, max = 100)
+
+The annotated element size must be between the specified boundaries (included).
+
+Supported types are:
+
+- String (string length is evaludated)
+- Collection (collection size is evaluated)
+- Map (map size is evaluated)
+- Array (array length is evaluated)
+
+null elements are considered valid.
+
+## @Pattern(regex = "XXXX")
+
+The annotated String must match the following regular expression.
+The regular expression follows the Java regular expression conventions
+see Pattern. Accepts String.
+
+null elements are considered valid.
+
+## Reference:
+
+[Package javax.validation.constraints ](http://docs.oracle.com/javaee/6/api/javax/validation/constraints/package-summary.html)
diff --git a/examples/README.md b/examples/README.md
deleted file mode 100644
index 90edd8b..0000000
--- a/examples/README.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# Overrview
-
-ease-gateway/examples 是使用ease-gateway的一个完整示例,包含gateway-server 和 gRPC-server. 还有Java实现gRPC Server的例子 [https://github.com/binchencoder/spring-boot-grpc/tree/master/spring-boot-grpc-examples]
-
-# Build the example
-
-build gateway server
-```
-bazel build ease-gateway/examples/cmd/example-gateway-server/...
-```
-
-build gRPC server
-```
-bazel build ease-gateway/examples/cmd/example-grpc-server/...
-```
-
-# Run the example
-
-start gateway server
-```
-ease-gateway/bazel-bin/examples/cmd/example-gateway-server/linux_amd64_stripped/example-gateway-server -skylb-endpoints="127.0.0.1:1900" -debug-svc-endpoint=custom-ease-gateway-test=localhost:9090
-```
-
-start custom-gateway server
-```
-ease-gateway/bazel-bin/cmd/custom-gateway/linux_amd64_stripped/custom-ease-gateway -skylb-endpoints="127.0.0.1:1900" -debug-service=custom-ease-gateway-test -debug-svc-endpoint=custom-ease-gateway-test=localhost:9090
-```
-
-start examples gRPC server for test //examples/cmd/example-gateway-server
-```
-ease-gateway/bazel-bin/examples/cmd/example-grpc-server/linux_amd64_stripped/example-grpc-server
-```
-
-start gRPC server for test //cmd/gateway
-```
-ease-gateway/bazel-bin/examples/cmd/grpc-server/linux_amd64_stripped/grpc-server -skylb-endpoints="127.0.0.1:1900"
-```
-
-start //cmd/gateway
-```
-ease-gateway/bazel-bin/cmd/gateway/linux_amd64_stripped/gateway -skylb-endpoints="127.0.0.1:1900" -v=2 -log_dir=.
-```
-
-# Usage
-
-You can use curl or a browser to test:
-```
-# List all apis
-$ curl http://localhost:8080/swagger/echo_service.swagger.json
-
-# Visit the apis
-$ curl -XPOST -H "x-source: web" http://localhost:8080/v1/example/echo/foo
-{"id":"foo"}
-
-$ curl -H "x-source: web" http://localhost:8080/v1/example/echo/foo/123
-{"id":"foo","num":"123"}
-
-$ curl -XDELETE -H "x-source: web" http://localhost:8080/v1/example/echo_delete
-
-$ curl -XPOST -H "Content-Type:application/json" -H "x-source:web" -d '{"id": "11", "num": 1}' http://localhost:8080/v1/example/echo_body
-```
-
-> NOTE: 请注意当前用户是否是管理员
\ No newline at end of file
diff --git a/examples/cmd/example-grpc-server/main.go b/examples/cmd/example-grpc-server/main.go
deleted file mode 100644
index ec93493..0000000
--- a/examples/cmd/example-grpc-server/main.go
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Command example-grpc-server is an example grpc server
- * to be called by example-gateway-server.
- */
-package main
-
-import (
- "context"
- "flag"
-
- // examples "github.com/binchencoder/ease-gateway/examples/proto"
- "github.com/binchencoder/ease-gateway/examples/server"
- // "github.com/binchencoder/gateway-proto/data"
- // skylb "github.com/binchencoder/skylb-api/server"
- "github.com/golang/glog"
-)
-
-var (
- addr = flag.String("addr", ":9090", "endpoint of the gRPC service")
- network = flag.String("network", "tcp", "a valid network type which is consistent to -addr")
-
- port = flag.Int("port", 9090, "The gRPC port of the server")
-)
-
-func main() {
- flag.Parse()
- defer glog.Flush()
-
- // Don't regist to skylbserver
- ctx := context.Background()
- if err := server.Run(ctx, *network, *addr); err != nil {
- glog.Fatal(err)
- }
-
- // skylb.Register(data.ServiceId_CUSTOM_EASE_GATEWAY_TEST, "grpc", *port)
- // skylb.EnableHistogram()
- // skylb.Start(fmt.Sprintf(":%d", *port), func(s *grpc.Server) error {
- // examples.RegisterEchoServiceServer(s, server.NewEchoServer())
- // return nil
- // })
-}
diff --git a/examples/cmd/grpc-server/BUILD.bazel b/examples/grpc-server/BUILD.bazel
similarity index 76%
rename from examples/cmd/grpc-server/BUILD.bazel
rename to examples/grpc-server/BUILD.bazel
index bd75490..b55c434 100644
--- a/examples/cmd/grpc-server/BUILD.bazel
+++ b/examples/grpc-server/BUILD.bazel
@@ -8,12 +8,12 @@ go_library(
"main.go",
"echo.go",
],
- importpath = "github.com/binchencoder/ease-gateway/examples/cmd/custom-grpc-server",
+ importpath = "github.com/binchencoder/janus-gateway/examples/grpc-server",
deps = [
- "//proto/examples:go_default_library",
+ "//proto/examplepb",
"@com_github_binchencoder_gateway_proto//data:go_default_library",
"@com_github_binchencoder_skylb_api//server:go_default_library",
- "@com_github_golang_glog//:go_default_library",
+ "@com_github_golang_glog//:glog",
"@org_golang_google_grpc//:go_default_library",
"@org_golang_google_grpc//metadata:go_default_library",
],
diff --git a/examples/cmd/grpc-server/echo.go b/examples/grpc-server/echo.go
similarity index 60%
rename from examples/cmd/grpc-server/echo.go
rename to examples/grpc-server/echo.go
index ccb99b5..752a723 100644
--- a/examples/cmd/grpc-server/echo.go
+++ b/examples/grpc-server/echo.go
@@ -3,7 +3,7 @@ package main
import (
"context"
- examples "github.com/binchencoder/ease-gateway/proto/examples"
+ "github.com/binchencoder/janus-gateway/proto/examplepb"
"github.com/golang/glog"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
@@ -14,16 +14,16 @@ import (
type echoServer struct{}
// NewEchoServer new echo server
-func NewEchoServer() examples.EchoServiceServer {
+func NewEchoServer() examplepb.EchoServiceServer {
return new(echoServer)
}
-func (s *echoServer) Echo(ctx context.Context, msg *examples.SimpleMessage) (*examples.SimpleMessage, error) {
+func (s *echoServer) Echo(ctx context.Context, msg *examplepb.SimpleMessage) (*examplepb.SimpleMessage, error) {
glog.Info(msg)
return msg, nil
}
-func (s *echoServer) EchoBody(ctx context.Context, msg *examples.SimpleMessage) (*examples.SimpleMessage, error) {
+func (s *echoServer) EchoBody(ctx context.Context, msg *examplepb.SimpleMessage) (*examplepb.SimpleMessage, error) {
glog.Info(msg)
grpc.SendHeader(ctx, metadata.New(map[string]string{
"foo": "foo1",
@@ -36,7 +36,7 @@ func (s *echoServer) EchoBody(ctx context.Context, msg *examples.SimpleMessage)
return msg, nil
}
-func (s *echoServer) EchoDelete(ctx context.Context, msg *examples.SimpleMessage) (*examples.SimpleMessage, error) {
+func (s *echoServer) EchoDelete(ctx context.Context, msg *examplepb.SimpleMessage) (*examplepb.SimpleMessage, error) {
glog.Info(msg)
return msg, nil
}
diff --git a/examples/cmd/grpc-server/main.go b/examples/grpc-server/main.go
similarity index 76%
rename from examples/cmd/grpc-server/main.go
rename to examples/grpc-server/main.go
index e4e6369..0880604 100644
--- a/examples/cmd/grpc-server/main.go
+++ b/examples/grpc-server/main.go
@@ -8,7 +8,7 @@ import (
"flag"
"fmt"
- examples "github.com/binchencoder/ease-gateway/proto/examples"
+ examplepb "github.com/binchencoder/janus-gateway/proto/examplepb"
"github.com/binchencoder/gateway-proto/data"
skylb "github.com/binchencoder/skylb-api/server"
"github.com/golang/glog"
@@ -26,10 +26,10 @@ func main() {
defer glog.Flush()
// Regist to skylbserver
- skylb.Register(data.ServiceId_CUSTOM_EASE_GATEWAY_TEST, "grpc", *port)
+ skylb.Register(data.ServiceId_CUSTOM_JANUS_GATEWAY_TEST, "grpc", *port)
skylb.EnableHistogram()
skylb.Start(fmt.Sprintf(":%d", *port), func(s *grpc.Server) error {
- examples.RegisterEchoServiceServer(s, NewEchoServer())
+ examplepb.RegisterEchoServiceServer(s, NewEchoServer())
return nil
})
}
diff --git a/examples/internal/README.md b/examples/internal/README.md
new file mode 100644
index 0000000..89cd791
--- /dev/null
+++ b/examples/internal/README.md
@@ -0,0 +1,63 @@
+# Overrview
+
+janus-gateway/examples/internal 是使用janus-gateway的一个完整示例,包含gateway-server 和 gRPC-server. 还有Java实现gRPC Server的例子 [https://github.com/binchencoder/spring-boot-grpc/tree/master/spring-boot-grpc-examples]
+
+# Build the example
+
+build gateway server
+```
+bazel build examples/internal/cmd/example-gateway-server/...
+```
+
+build gRPC server
+```
+bazel build examples/internal/cmd/example-grpc-server/...
+```
+
+# Run the example
+
+start gateway server
+```shell
+janus-gateway/bazel-bin/examples/internal/cmd/example-gateway-server/example-gateway-server_/example-gateway-server -skylb-endpoints="127.0.0.1:1900" -debug-svc-endpoint=custom-janus-gateway-test=localhost:9090
+```
+
+start custom-gateway server
+```shell
+janus-gateway/bazel-bin/cmd/custom-gateway/custom-janus-gateway_/custom-janus-gateway -skylb-endpoints="127.0.0.1:1900" -debug-service=custom-janus-gateway-test -debug-svc-endpoint=custom-janus-gateway-test=localhost:9090
+```
+
+start examples gRPC server for test //examples/internal/cmd/example-grpc-server
+```shell
+janus-gateway/bazel-bin/examples/internal/cmd/example-grpc-server/example-grpc-server_/example-grpc-server -skylb-endpoints="127.0.0.1:1900,127.0.0.1:1901"
+```
+
+start gRPC server for test //cmd/gateway
+```shell
+janus-gateway/bazel-bin/examples/grpc-server/grpc-server_/grpc-server -skylb-endpoints="127.0.0.1:1900"
+```
+
+start //cmd/gateway
+```shell
+janus-gateway/bazel-bin/cmd/gateway/gateway_/gateway -skylb-endpoints="127.0.0.1:1900" -v=2 -log_dir=.
+```
+
+# Usage
+
+You can use curl or a browser to test:
+```
+# List all apis
+$ curl http://localhost:8080/swagger/echo_service.swagger.json
+
+# Visit the apis
+$ curl -XPOST -H "x-source: web" http://localhost:8080/v1/example/echo/foo
+{"id":"foo"}
+
+$ curl -H "x-source: web" http://localhost:8080/v1/example/echo/foo/123
+{"id":"foo","num":"123"}
+
+$ curl -XDELETE -H "x-source: web" http://localhost:8080/v1/example/echo_delete
+
+$ curl -XPOST -H "Content-Type:application/json" -H "x-source:web" -d '{"id": "11", "num": 1}' http://localhost:8080/v1/example/echo_body
+```
+
+> NOTE: 请注意当前用户是否是管理员
\ No newline at end of file
diff --git a/examples/cmd/example-gateway-server/BUILD.bazel b/examples/internal/cmd/example-gateway-server/BUILD.bazel
similarity index 72%
rename from examples/cmd/example-gateway-server/BUILD.bazel
rename to examples/internal/cmd/example-gateway-server/BUILD.bazel
index 066cd18..39d663d 100644
--- a/examples/cmd/example-gateway-server/BUILD.bazel
+++ b/examples/internal/cmd/example-gateway-server/BUILD.bazel
@@ -3,10 +3,10 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
go_library(
name = "go_default_library",
srcs = ["main.go"],
- importpath = "github.com/binchencoder/ease-gateway/examples/cmd/example-gateway-server",
+ importpath = "github.com/binchencoder/janus-gateway/examples/internal/cmd/example-gateway-server",
visibility = ["//visibility:private"],
deps = [
- "//examples/gateway:go_default_library",
+ "//examples/internal/gateway:go_default_library",
"//gateway/runtime:go_default_library",
"@com_github_golang_glog//:go_default_library",
],
diff --git a/examples/cmd/example-gateway-server/main.go b/examples/internal/cmd/example-gateway-server/main.go
similarity index 74%
rename from examples/cmd/example-gateway-server/main.go
rename to examples/internal/cmd/example-gateway-server/main.go
index 1cbf62c..2d34925 100644
--- a/examples/cmd/example-gateway-server/main.go
+++ b/examples/internal/cmd/example-gateway-server/main.go
@@ -8,14 +8,14 @@ import (
"context"
"flag"
- "github.com/binchencoder/ease-gateway/examples/gateway"
"github.com/golang/glog"
+ "github.com/binchencoder/janus-gateway/examples/internal/gateway"
)
var (
endpoint = flag.String("endpoint", "localhost:9090", "endpoint of the gRPC service")
network = flag.String("network", "tcp", `one of "tcp" or "unix". Must be consistent to -endpoint`)
- swaggerDir = flag.String("swagger_dir", "examples/proto/", "path to the directory which contains swagger definitions")
+ openAPIDir = flag.String("openapi_dir", "examples/internal/proto/examplepb", "path to the directory which contains OpenAPI definitions")
)
func main() {
@@ -29,7 +29,7 @@ func main() {
Network: *network,
Addr: *endpoint,
},
- SwaggerDir: *swaggerDir,
+ OpenAPIDir: *openAPIDir,
}
if err := gateway.Run(ctx, opts); err != nil {
glog.Fatal(err)
diff --git a/examples/internal/cmd/example-grpc-client/BUILD.bazel b/examples/internal/cmd/example-grpc-client/BUILD.bazel
new file mode 100644
index 0000000..25ddab5
--- /dev/null
+++ b/examples/internal/cmd/example-grpc-client/BUILD.bazel
@@ -0,0 +1,39 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
+
+package(default_visibility = ["//visibility:private"])
+
+go_library(
+ name = "go_default_library",
+ srcs = ["grpcclient.go"],
+ importpath = "github.com/binchencoder/janus-gateway/examples/internal/cmd/example-grpc-client",
+ deps = [
+ "//examples/internal/proto/examplepb:go_default_library",
+ "//examples/internal/server:go_default_library",
+ "@com_github_binchencoder_letsgo//:go_default_library",
+ "@com_github_binchencoder_gateway_proto//data:go_default_library",
+ "@com_github_binchencoder_skylb_api//client:go_default_library",
+ "@com_github_binchencoder_skylb_api//proto:go_default_library",
+ "@com_github_binchencoder_skylb_api//server:go_default_library",
+ "@com_github_golang_glog//:go_default_library",
+ "@com_github_prometheus_client_golang//prometheus:go_default_library",
+ "@org_golang_x_net//context:go_default_library",
+ "@org_golang_google_grpc//:go_default_library",
+ "@org_golang_google_grpc//health/grpc_health_v1:go_default_library",
+ ],
+)
+
+go_binary(
+ name = "grpc-client",
+ embed = [":go_default_library"],
+ visibility = ["//visibility:public"],
+)
+
+go_binary(
+ name = "gateway-client",
+ srcs = ["gatewayclient.go"],
+ deps = [
+ "//examples/internal/proto/examplepb:go_default_library",
+ "@com_github_binchencoder_letsgo//:go_default_library",
+ "@com_github_golang_protobuf//jsonpb:go_default_library",
+ ]
+)
\ No newline at end of file
diff --git a/examples/internal/cmd/example-grpc-client/gatewayclient.go b/examples/internal/cmd/example-grpc-client/gatewayclient.go
new file mode 100644
index 0000000..818459b
--- /dev/null
+++ b/examples/internal/cmd/example-grpc-client/gatewayclient.go
@@ -0,0 +1,83 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "net/http"
+ "time"
+
+ "github.com/golang/protobuf/jsonpb"
+
+ examplepb "github.com/binchencoder/janus-gateway/examples/internal/proto/examplepb"
+ "github.com/binchencoder/letsgo"
+)
+
+const urlPattern = "http://%s/v1/example/echo/2211/1"
+
+var (
+ flagServer = flag.String("server", "localhost:8080", "The server host:port")
+ onceOnly = flag.Bool("send-once", false, "Send the request once only")
+ clientId = flag.String("client-id", "", "Client ID")
+ xSource = flag.String("x-source", "web", "X-Source to use")
+)
+
+func main() {
+ letsgo.Init()
+
+ url := fmt.Sprintf(urlPattern, *flagServer)
+
+ // If specified, send request once and return.
+ if *onceOnly {
+ sendRequest(url)
+ return
+ }
+
+ for i := 0; i < 10; i++ {
+ go func() {
+ for range time.Tick(50 * time.Millisecond) {
+ sendRequest(url)
+ }
+ }()
+ }
+
+ select {}
+}
+
+func sendRequest(url string) {
+ req, err := http.NewRequest("GET", url, nil)
+ if err != nil {
+ log.Println("NewRequest: ", err)
+ return
+ }
+ req.Header.Set("x-source", *xSource)
+ req.Header.Set("Content-Type", "application/json")
+ req.Header.Set("x-Uid", "marlin")
+ req.Header.Set("X-Cid", "disney")
+
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ if err != nil {
+ log.Fatal("Do: ", err)
+ return
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode == 200 {
+ bodyBytes, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ log.Println(err)
+ return
+ }
+
+ record := examplepb.SimpleMessage{}
+ if err = jsonpb.UnmarshalString(string(bodyBytes), &record); err != nil {
+ log.Println(err)
+ return
+ }
+ fmt.Printf("%d, resp: %+v.\n", resp.StatusCode, record)
+ } else {
+ fmt.Println(resp.StatusCode)
+ }
+}
diff --git a/examples/internal/cmd/example-grpc-client/grpcclient.go b/examples/internal/cmd/example-grpc-client/grpcclient.go
new file mode 100644
index 0000000..f75e756
--- /dev/null
+++ b/examples/internal/cmd/example-grpc-client/grpcclient.go
@@ -0,0 +1,99 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "os"
+ "time"
+
+ "github.com/golang/glog"
+ prom "github.com/prometheus/client_golang/prometheus"
+ "golang.org/x/net/context"
+ "google.golang.org/grpc"
+ hpb "google.golang.org/grpc/health/grpc_health_v1"
+
+ examplepb "github.com/binchencoder/janus-gateway/examples/internal/proto/examplepb"
+ vexpb "github.com/binchencoder/gateway-proto/data"
+ "github.com/binchencoder/letsgo"
+ skylb "github.com/binchencoder/skylb-api/client"
+ skypb "github.com/binchencoder/skylb-api/proto"
+)
+
+var (
+ nBatchRequest = flag.Int("n-batch-request", 10000, "The number of batched request")
+ requestSleep = flag.Duration("request-sleep", 100*time.Millisecond, "The sleep time after each request")
+ requestTimeout = flag.Duration("request-timeout", 100*time.Millisecond, "The timeout of each request")
+
+ spec = skylb.NewServiceSpec(skylb.DefaultNameSpace, vexpb.ServiceId_CUSTOM_JANUS_GATEWAY_TEST, skylb.DefaultPortName)
+
+ grpcFailCount = prom.NewCounter(
+ prom.CounterOpts{
+ Namespace: "skytest",
+ Subsystem: "client",
+ Name: "grpc_call_failure",
+ Help: "The number of failed gRPC calls.",
+ },
+ )
+)
+
+func startSkylb(sid vexpb.ServiceId) (skylb.ServiceCli, examplepb.EchoServiceClient, hpb.HealthClient) {
+ skycli := skylb.NewServiceCli(vexpb.ServiceId_SHARED_TEST_CLIENT_SERVICE)
+
+ options := []grpc.DialOption{}
+ options = append(options, grpc.WithDefaultServiceConfig(`{"loadBalancingConfig": [{"round_robin": {}}]}`))
+ skycli.Resolve(skylb.NewServiceSpec(skylb.DefaultNameSpace, sid, skylb.DefaultPortName), options...)
+ skycli.EnableHistogram()
+
+ var cli examplepb.EchoServiceClient
+ var healthCli hpb.HealthClient
+ skycli.Start(func(spec *skypb.ServiceSpec, conn *grpc.ClientConn) {
+ cli = examplepb.NewEchoServiceClient(conn)
+ healthCli = hpb.NewHealthClient(conn)
+ })
+ return skycli, cli, healthCli
+}
+
+func usage() {
+ fmt.Println(`Skytest gRPC client.
+
+Usage:
+ skytest-client [options]
+
+Options:`)
+
+ flag.PrintDefaults()
+ os.Exit(2)
+}
+
+func main() {
+ letsgo.Init(letsgo.FlagUsage(usage))
+
+ testClient()
+}
+
+func testClient() {
+ sl, cli, healthCli := startSkylb(vexpb.ServiceId_CUSTOM_JANUS_GATEWAY_TEST)
+ for {
+ for i := 0; i < *nBatchRequest; i++ {
+ req := examplepb.SimpleMessage{
+ Id: fmt.Sprintf("John Doe %d", time.Now().Second()),
+ }
+ ctx, cancel := context.WithTimeout(context.Background(), *requestTimeout)
+ _, err := cli.Echo(ctx, &req, grpc.FailFast(false))
+ if err != nil {
+ cancel()
+ glog.Errorf("Failed to greet service, %v \n", err)
+ grpcFailCount.Inc()
+ time.Sleep(*requestTimeout)
+ continue
+ }
+
+ // glog.Infof("Greeting resp: %v \n", resp)
+
+ healthCli.Check(context.Background(), &hpb.HealthCheckRequest{})
+ time.Sleep(*requestSleep)
+ }
+ }
+
+ sl.Shutdown()
+}
diff --git a/examples/cmd/example-grpc-server/BUILD.bazel b/examples/internal/cmd/example-grpc-server/BUILD.bazel
similarity index 66%
rename from examples/cmd/example-grpc-server/BUILD.bazel
rename to examples/internal/cmd/example-grpc-server/BUILD.bazel
index 1c63a55..eec50ac 100644
--- a/examples/cmd/example-grpc-server/BUILD.bazel
+++ b/examples/internal/cmd/example-grpc-server/BUILD.bazel
@@ -5,13 +5,14 @@ package(default_visibility = ["//visibility:private"])
go_library(
name = "go_default_library",
srcs = ["main.go"],
- importpath = "github.com/binchencoder/ease-gateway/examples/cmd/example-grpc-server",
+ importpath = "github.com/binchencoder/janus-gateway/examples/internal/cmd/example-grpc-server",
deps = [
- "//examples/proto:go_default_library",
- "//examples/server:go_default_library",
+ "//examples/internal/proto/examplepb:go_default_library",
+ "//examples/internal/server:go_default_library",
"@com_github_binchencoder_gateway_proto//data:go_default_library",
"@com_github_binchencoder_skylb_api//server:go_default_library",
"@com_github_golang_glog//:go_default_library",
+ "@com_github_prometheus_client_golang//prometheus:go_default_library",
"@org_golang_google_grpc//:go_default_library",
],
)
diff --git a/examples/internal/cmd/example-grpc-server/main.go b/examples/internal/cmd/example-grpc-server/main.go
new file mode 100644
index 0000000..7df8f7a
--- /dev/null
+++ b/examples/internal/cmd/example-grpc-server/main.go
@@ -0,0 +1,57 @@
+/*
+ * Command example-grpc-server is an example grpc server
+ * to be called by example-gateway-server.
+ */
+package main
+
+import (
+ "flag"
+ "fmt"
+ "log"
+ "net/http"
+
+ examplepb "github.com/binchencoder/janus-gateway/examples/internal/proto/examplepb"
+ "github.com/prometheus/client_golang/prometheus"
+
+ "github.com/binchencoder/gateway-proto/data"
+ skylb "github.com/binchencoder/skylb-api/server"
+
+ "github.com/binchencoder/janus-gateway/examples/internal/server"
+ "github.com/golang/glog"
+ "google.golang.org/grpc"
+)
+
+var (
+ addr = flag.String("addr", ":9090", "endpoint of the gRPC service")
+ network = flag.String("network", "tcp", "a valid network type which is consistent to -addr")
+ scrapeAddr = flag.String("scrape-addr", "0.0.0.0:18001", "The prometheus scrape port")
+
+ port = flag.Int("port", 9090, "The gRPC port of the server")
+)
+
+func registerPrometheus() {
+ http.Handle("/_/metrics", prometheus.UninstrumentedHandler())
+ if err := http.ListenAndServe(*scrapeAddr, nil); err != nil {
+ log.Fatal("ListenServerError:", err)
+ }
+}
+
+func main() {
+ flag.Parse()
+ defer glog.Flush()
+
+ // Don't regist to skylbserver
+ // ctx := context.Background()
+ // if err := server.Run(ctx, *network, *addr); err != nil {
+ // glog.Fatal(err)
+ // }
+
+ go registerPrometheus()
+
+ skylb.Register(data.ServiceId_CUSTOM_JANUS_GATEWAY_TEST, "grpc", *port)
+ skylb.EnableHistogram()
+ skylb.Start(fmt.Sprintf(":%d", *port), func(s *grpc.Server) error {
+ examplepb.RegisterEchoServiceServer(s, server.NewEchoServer())
+ return nil
+ })
+}
diff --git a/examples/gateway/BUILD.bazel b/examples/internal/gateway/BUILD.bazel
similarity index 52%
rename from examples/gateway/BUILD.bazel
rename to examples/internal/gateway/BUILD.bazel
index 927e73c..cdc26b2 100644
--- a/examples/gateway/BUILD.bazel
+++ b/examples/internal/gateway/BUILD.bazel
@@ -1,21 +1,28 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
- name = "go_default_library",
+ name = "gateway",
srcs = [
"doc.go",
"gateway.go",
"handlers.go",
"main.go",
],
- importpath = "github.com/binchencoder/ease-gateway/examples/gateway",
+ importpath = "github.com/binchencoder/janus-gateway/examples/internal/gateway",
visibility = ["//visibility:public"],
deps = [
- "//examples/proto:go_default_library",
- "//gateway/runtime:go_default_library",
+ "//examples/internal/proto/examplepb",
+ "//gateway/runtime",
"//util:go_default_library",
"@com_github_golang_glog//:go_default_library",
"@org_golang_google_grpc//:go_default_library",
- "@org_golang_google_grpc//connectivity:go_default_library",
+ "@org_golang_google_grpc//connectivity",
+ "@org_golang_google_grpc//credentials/insecure",
],
)
+
+alias(
+ name = "go_default_library",
+ actual = ":gateway",
+ visibility = ["//examples:__subpackages__"],
+)
diff --git a/examples/gateway/doc.go b/examples/internal/gateway/doc.go
similarity index 100%
rename from examples/gateway/doc.go
rename to examples/internal/gateway/doc.go
diff --git a/examples/gateway/gateway.go b/examples/internal/gateway/gateway.go
similarity index 65%
rename from examples/gateway/gateway.go
rename to examples/internal/gateway/gateway.go
index 92c64ea..357cd75 100644
--- a/examples/gateway/gateway.go
+++ b/examples/internal/gateway/gateway.go
@@ -5,17 +5,16 @@ import (
"fmt"
"net"
"net/http"
- "time"
- "github.com/binchencoder/ease-gateway/examples/proto"
- "github.com/binchencoder/ease-gateway/gateway/runtime"
+ "github.com/binchencoder/janus-gateway/examples/internal/proto/examplepb"
+ gwruntime "github.com/binchencoder/janus-gateway/gateway/runtime"
"google.golang.org/grpc"
)
// newGateway returns a new gateway server which translates HTTP into gRPC.
-func newGateway(ctx context.Context, conn *grpc.ClientConn, opts []runtime.ServeMuxOption) (http.Handler, error) {
- sgs := runtime.GetServicGroups()
- fmt.Printf("runtime.GetServicGroups: %v", sgs)
+func newGateway(ctx context.Context, conn *grpc.ClientConn, opts []gwruntime.ServeMuxOption) (http.Handler, error) {
+ sgs := gwruntime.GetServicGroups()
+ fmt.Printf("gwruntime.GetServicGroups: %v \n", sgs)
for _, sg := range sgs {
go sg.Enable()
spec := sg.Spec
@@ -23,11 +22,11 @@ func newGateway(ctx context.Context, conn *grpc.ClientConn, opts []runtime.Serve
spec.ServiceName, spec.Namespace, spec.PortName)
}
- mux := runtime.NewServeMux(opts...)
+ mux := gwruntime.NewServeMux(opts...)
- // proto.Enable_CUSTOM_EASE_GATEWAY_TEST__default__grpc_ServiceGroup()
- for _, f := range []func(context.Context, *runtime.ServeMux, *grpc.ClientConn) error{
- proto.RegisterEchoServiceHandler,
+ // examplepb.Enable_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_ServiceGroup()
+ for _, f := range []func(context.Context, *gwruntime.ServeMux, *grpc.ClientConn) error{
+ examplepb.RegisterEchoServiceHandler,
} {
if err := f(ctx, mux, conn); err != nil {
return nil, err
@@ -56,8 +55,8 @@ func dialTCP(ctx context.Context, addr string) (*grpc.ClientConn, error) {
// dialUnix creates a client connection via a unix domain socket.
// "addr" must be a valid path to the socket.
func dialUnix(ctx context.Context, addr string) (*grpc.ClientConn, error) {
- d := func(addr string, timeout time.Duration) (net.Conn, error) {
- return net.DialTimeout("unix", addr, timeout)
+ d := func(ctx context.Context, addr string) (net.Conn, error) {
+ return (&net.Dialer{}).DialContext(ctx, "unix", addr)
}
- return grpc.DialContext(ctx, addr, grpc.WithInsecure(), grpc.WithDialer(d))
+ return grpc.DialContext(ctx, addr, grpc.WithInsecure(), grpc.WithContextDialer(d))
}
diff --git a/examples/gateway/handlers.go b/examples/internal/gateway/handlers.go
similarity index 85%
rename from examples/gateway/handlers.go
rename to examples/internal/gateway/handlers.go
index ceb3839..1f617b1 100644
--- a/examples/gateway/handlers.go
+++ b/examples/internal/gateway/handlers.go
@@ -11,8 +11,8 @@ import (
"google.golang.org/grpc/connectivity"
)
-// swaggerServer returns swagger specification files located under "/swagger/"
-func swaggerServer(dir string) http.HandlerFunc {
+// openAPIServer returns OpenAPI specification files located under "/openapiv2/"
+func openAPIServer(dir string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if !strings.HasSuffix(r.URL.Path, ".swagger.json") {
glog.Errorf("Not Found: %s", r.URL.Path)
@@ -21,10 +21,8 @@ func swaggerServer(dir string) http.HandlerFunc {
}
glog.Infof("Serving %s", r.URL.Path)
- p := strings.TrimPrefix(r.URL.Path, "/swagger/")
- fmt.Printf("serve file trim path: %s\n", p)
+ p := strings.TrimPrefix(r.URL.Path, "/openapiv2/")
p = path.Join(dir, p)
- fmt.Printf("serve file join path: %s\n", p)
http.ServeFile(w, r, p)
}
}
@@ -48,7 +46,7 @@ func allowCORS(h http.Handler) http.Handler {
// CORS from any origin using the methods "GET", "HEAD", "POST", "PUT", "DELETE"
// We insist, don't do this without consideration in production systems.
func preflightHandler(w http.ResponseWriter, r *http.Request) {
- headers := []string{"Content-Type", "Accept"}
+ headers := []string{"Content-Type", "Accept", "Authorization"}
w.Header().Set("Access-Control-Allow-Headers", strings.Join(headers, ","))
methods := []string{"GET", "HEAD", "POST", "PUT", "DELETE"}
w.Header().Set("Access-Control-Allow-Methods", strings.Join(methods, ","))
diff --git a/examples/gateway/main.go b/examples/internal/gateway/main.go
similarity index 85%
rename from examples/gateway/main.go
rename to examples/internal/gateway/main.go
index b981ebb..e467b68 100644
--- a/examples/gateway/main.go
+++ b/examples/internal/gateway/main.go
@@ -5,7 +5,7 @@ import (
"net/http"
"github.com/golang/glog"
- "github.com/binchencoder/ease-gateway/gateway/runtime"
+ gwruntime "github.com/binchencoder/janus-gateway/gateway/runtime"
)
// Endpoint describes a gRPC endpoint
@@ -21,12 +21,12 @@ type Options struct {
// GRPCServer defines an endpoint of a gRPC service
GRPCServer Endpoint
- // SwaggerDir is a path to a directory from which the server
- // serves swagger specs.
- SwaggerDir string
+ // OpenAPIDir is a path to a directory from which the server
+ // serves OpenAPI specs.
+ OpenAPIDir string
// Mux is a list of options to be passed to the grpc-gateway multiplexer
- Mux []runtime.ServeMuxOption
+ Mux []gwruntime.ServeMuxOption
}
// Run starts a HTTP server and blocks while running if successful.
@@ -47,7 +47,7 @@ func Run(ctx context.Context, opts Options) error {
}()
mux := http.NewServeMux()
- mux.HandleFunc("/swagger/", swaggerServer(opts.SwaggerDir))
+ mux.HandleFunc("/openapiv2/", openAPIServer(opts.OpenAPIDir))
mux.HandleFunc("/healthz", healthzServer(conn))
gw, err := newGateway(ctx, conn, opts.Mux)
diff --git a/examples/internal/integration/BUILD.bazel b/examples/internal/integration/BUILD.bazel
new file mode 100644
index 0000000..173b989
--- /dev/null
+++ b/examples/internal/integration/BUILD.bazel
@@ -0,0 +1,26 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_test")
+
+go_test(
+ name = "integration_test",
+ srcs = [
+ # "integration_test.go",
+ "main_test.go",
+ ],
+ deps = [
+ "//examples/internal/gateway",
+ "//examples/internal/proto/examplepb",
+ "//examples/internal/server",
+ "//gateway/runtime",
+ "//httpoptions",
+ "@com_github_golang_glog//:glog",
+ "@com_github_google_go_cmp//cmp",
+ "@go_googleapis//google/rpc:status_go_proto",
+ "@io_bazel_rules_go//proto/wkt:field_mask_go_proto",
+ "@org_golang_google_grpc//codes",
+ "@org_golang_google_protobuf//encoding/protojson",
+ "@org_golang_google_protobuf//proto",
+ "@org_golang_google_protobuf//testing/protocmp",
+ "@org_golang_google_protobuf//types/known/emptypb",
+ "@org_golang_google_protobuf//types/known/structpb",
+ ],
+)
diff --git a/examples/internal/integration/README.md b/examples/internal/integration/README.md
new file mode 100644
index 0000000..6b1d01f
--- /dev/null
+++ b/examples/internal/integration/README.md
@@ -0,0 +1,11 @@
+# Run test
+
+## Bazel test
+
+```shell
+bazel run examples/internal/integration/... --test_arg=--skylb-endpoints="" --test_arg=--debug-svc-endpoint=custom-janus-gateway-test=localhost:9090
+```
+
+> 通过bazel run 执行integration test
+>
+> 因为引入skylb-api, 运行时需要指定skylb-endpoints
\ No newline at end of file
diff --git a/examples/internal/integration/integration_test.go b/examples/internal/integration/integration_test.go
new file mode 100644
index 0000000..bcae784
--- /dev/null
+++ b/examples/internal/integration/integration_test.go
@@ -0,0 +1,435 @@
+package integration_test
+
+import (
+ "bytes"
+ "context"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "strings"
+ "testing"
+
+ examplepb "github.com/binchencoder/janus-gateway/examples/internal/proto/examplepb"
+ "github.com/binchencoder/janus-gateway/gateway/runtime"
+ "github.com/google/go-cmp/cmp"
+ fieldmaskpb "google.golang.org/genproto/protobuf/field_mask"
+
+ // "google.golang.org/grpc/codes"
+ "google.golang.org/protobuf/encoding/protojson"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/testing/protocmp"
+ "google.golang.org/protobuf/types/known/structpb"
+)
+
+var marshaler = &runtime.JSONPb{}
+
+func TestEcho(t *testing.T) {
+ if testing.Short() {
+ t.Skip()
+ return
+ }
+
+ for _, apiPrefix := range []string{"v1", "v2"} {
+ t.Run(apiPrefix, func(t *testing.T) {
+ testEcho(t, 8088, apiPrefix, "application/json")
+ testEchoOneof(t, 8088, apiPrefix, "application/json")
+ testEchoOneof1(t, 8088, apiPrefix, "application/json")
+ testEchoOneof2(t, 8088, apiPrefix, "application/json")
+ testEchoBody(t, 8088, apiPrefix, true)
+ testEchoBody(t, 8088, apiPrefix, false)
+ // Use SendHeader/SetTrailer without gRPC server https://github.com/grpc-ecosystem/grpc-gateway/issues/517#issuecomment-684625645
+ testEchoBody(t, 8089, apiPrefix, true)
+ testEchoBody(t, 8089, apiPrefix, false)
+ })
+ }
+ t.Run("testEchoValidationRules", func(t *testing.T) {
+ testEchoValidationRules(t, 8088, "application/json")
+ })
+}
+
+func TestEchoPatch(t *testing.T) {
+ if testing.Short() {
+ t.Skip()
+ return
+ }
+
+ sent := examplepb.DynamicMessage{
+ StructField: &structpb.Struct{Fields: map[string]*structpb.Value{
+ "struct_key": {Kind: &structpb.Value_StructValue{
+ StructValue: &structpb.Struct{Fields: map[string]*structpb.Value{
+ "layered_struct_key": {Kind: &structpb.Value_StringValue{StringValue: "struct_val"}},
+ }},
+ }},
+ }},
+ ValueField: &structpb.Value{Kind: &structpb.Value_StructValue{
+ StructValue: &structpb.Struct{Fields: map[string]*structpb.Value{
+ "value_struct_key": {Kind: &structpb.Value_StringValue{StringValue: "value_struct_val"}},
+ }},
+ }},
+ }
+ payload, err := protojson.MarshalOptions{UseProtoNames: true}.Marshal(&sent)
+ if err != nil {
+ t.Fatalf("marshaler.Marshal(%#v) failed with %v; want success", payload, err)
+ }
+
+ apiURL := "http://localhost:8088/v1/example/echo_patch"
+ req, err := http.NewRequest("PATCH", apiURL, bytes.NewReader(payload))
+ if err != nil {
+ t.Errorf("http.NewRequest(PATCH, %q) failed with %v; want success", apiURL, err)
+ return
+ }
+ resp, err := http.DefaultClient.Do(req)
+ if err != nil {
+ t.Errorf("http.Post(%#v) failed with %v; want success", req, err)
+ return
+ }
+ defer resp.Body.Close()
+ buf, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ t.Errorf("ioutil.ReadAll(resp.Body) failed with %v; want success", err)
+ return
+ }
+
+ if got, want := resp.StatusCode, http.StatusOK; got != want {
+ t.Errorf("resp.StatusCode = %d; want %d", got, want)
+ t.Logf("%s", buf)
+ }
+
+ var received examplepb.DynamicMessageUpdate
+ if err := marshaler.Unmarshal(buf, &received); err != nil {
+ t.Errorf("marshaler.Unmarshal(%s, msg) failed with %v; want success", buf, err)
+ return
+ }
+ if diff := cmp.Diff(received.Body, sent, protocmp.Transform()); diff != "" {
+ t.Errorf(diff)
+ }
+ if diff := cmp.Diff(received.UpdateMask, fieldmaskpb.FieldMask{Paths: []string{
+ "struct_field.struct_key.layered_struct_key", "value_field.value_struct_key",
+ }}, protocmp.Transform(), protocmp.SortRepeatedFields(received.UpdateMask, "paths")); diff != "" {
+ t.Errorf(diff)
+ }
+}
+
+func TestForwardResponseOption(t *testing.T) {
+ if testing.Short() {
+ t.Skip()
+ return
+ }
+
+ ctx := context.Background()
+ ctx, cancel := context.WithCancel(ctx)
+ defer cancel()
+
+ port := 7079
+ go func() {
+ if err := runGateway(
+ ctx,
+ fmt.Sprintf(":%d", port),
+ runtime.WithForwardResponseOption(
+ func(_ context.Context, w http.ResponseWriter, _ proto.Message) error {
+ w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1.1+json")
+ return nil
+ },
+ ),
+ ); err != nil {
+ t.Errorf("runGateway() failed with %v; want success", err)
+ return
+ }
+ }()
+ if err := waitForGateway(ctx, uint16(port)); err != nil {
+ t.Errorf("waitForGateway(ctx, %d) failed with %v; want success", port, err)
+ }
+ testEcho(t, port, "v1", "application/vnd.docker.plugins.v1.1+json")
+}
+
+func TestForwardResponseOptionHTTPPathPattern(t *testing.T) {
+ if testing.Short() {
+ t.Skip()
+ return
+ }
+
+ ctx := context.Background()
+ ctx, cancel := context.WithCancel(ctx)
+ defer cancel()
+
+ port := 7080
+ go func() {
+ if err := runGateway(
+ ctx,
+ fmt.Sprintf(":%d", port),
+ runtime.WithForwardResponseOption(
+ func(ctx context.Context, w http.ResponseWriter, _ proto.Message) error {
+ path, _ := runtime.HTTPPathPattern(ctx)
+ w.Header().Set("Content-Type", path)
+ return nil
+ },
+ ),
+ ); err != nil {
+ t.Errorf("runGateway() failed with %v; want success", err)
+ return
+ }
+ }()
+ if err := waitForGateway(ctx, uint16(port)); err != nil {
+ t.Errorf("waitForGateway(ctx, %d) failed with %v; want success", port, err)
+ }
+ testEcho(t, port, "v1", "/v1/example/echo/{id}")
+}
+
+func testEcho(t *testing.T, port int, apiPrefix string, contentType string) {
+ apiURL := fmt.Sprintf("http://localhost:%d/%s/example/echo/myid", port, apiPrefix)
+ resp, err := http.Post(apiURL, "application/json", strings.NewReader("{}"))
+ if err != nil {
+ t.Errorf("http.Post(%q) failed with %v; want success", apiURL, err)
+ return
+ }
+ defer resp.Body.Close()
+ buf, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ t.Errorf("ioutil.ReadAll(resp.Body) failed with %v; want success", err)
+ return
+ }
+
+ if got, want := resp.StatusCode, http.StatusOK; got != want {
+ t.Errorf("resp.StatusCode = %d; want %d", got, want)
+ t.Logf("%s", buf)
+ }
+
+ msg := new(examplepb.UnannotatedSimpleMessage)
+ if err := marshaler.Unmarshal(buf, msg); err != nil {
+ t.Errorf("marshaler.Unmarshal(%s, msg) failed with %v; want success", buf, err)
+ return
+ }
+ if got, want := msg.Id, "myid"; got != want {
+ t.Errorf("msg.Id = %q; want %q", got, want)
+ }
+
+ if value := resp.Header.Get("Content-Type"); value != contentType {
+ t.Errorf("Content-Type was %s, wanted %s", value, contentType)
+ }
+}
+
+func testEchoOneof(t *testing.T, port int, apiPrefix string, contentType string) {
+ apiURL := fmt.Sprintf("http://localhost:%d/%s/example/echo/myid/10/golang", port, apiPrefix)
+ resp, err := http.Get(apiURL)
+ if err != nil {
+ t.Errorf("http.Get(%q) failed with %v; want success", apiURL, err)
+ return
+ }
+ defer resp.Body.Close()
+ buf, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ t.Errorf("ioutil.ReadAll(resp.Body) failed with %v; want success", err)
+ return
+ }
+
+ if got, want := resp.StatusCode, http.StatusOK; got != want {
+ t.Errorf("resp.StatusCode = %d; want %d", got, want)
+ t.Logf("%s", buf)
+ }
+
+ msg := new(examplepb.UnannotatedSimpleMessage)
+ if err := marshaler.Unmarshal(buf, msg); err != nil {
+ t.Errorf("marshaler.Unmarshal(%s, msg) failed with %v; want success", buf, err)
+ return
+ }
+ if got, want := msg.GetLang(), "golang"; got != want {
+ t.Errorf("msg.GetLang() = %q; want %q", got, want)
+ }
+
+ if value := resp.Header.Get("Content-Type"); value != contentType {
+ t.Errorf("Content-Type was %s, wanted %s", value, contentType)
+ }
+}
+
+func testEchoOneof1(t *testing.T, port int, apiPrefix string, contentType string) {
+ apiURL := fmt.Sprintf("http://localhost:%d/%s/example/echo1/myid/10/golang", port, apiPrefix)
+ resp, err := http.Get(apiURL)
+ if err != nil {
+ t.Errorf("http.Get(%q) failed with %v; want success", apiURL, err)
+ return
+ }
+ defer resp.Body.Close()
+ buf, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ t.Errorf("ioutil.ReadAll(resp.Body) failed with %v; want success", err)
+ return
+ }
+
+ if got, want := resp.StatusCode, http.StatusOK; got != want {
+ t.Errorf("resp.StatusCode = %d; want %d", got, want)
+ t.Logf("%s", buf)
+ }
+
+ msg := new(examplepb.UnannotatedSimpleMessage)
+ if err := marshaler.Unmarshal(buf, msg); err != nil {
+ t.Errorf("marshaler.Unmarshal(%s, msg) failed with %v; want success", buf, err)
+ return
+ }
+ if got, want := msg.GetStatus().GetNote(), "golang"; got != want {
+ t.Errorf("msg.GetStatus().GetNote() = %q; want %q", got, want)
+ }
+
+ if value := resp.Header.Get("Content-Type"); value != contentType {
+ t.Errorf("Content-Type was %s, wanted %s", value, contentType)
+ }
+}
+
+func testEchoOneof2(t *testing.T, port int, apiPrefix string, contentType string) {
+ apiURL := fmt.Sprintf("http://localhost:%d/%s/example/echo2/golang", port, apiPrefix)
+ resp, err := http.Get(apiURL)
+ if err != nil {
+ t.Errorf("http.Get(%q) failed with %v; want success", apiURL, err)
+ return
+ }
+ defer resp.Body.Close()
+ buf, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ t.Errorf("ioutil.ReadAll(resp.Body) failed with %v; want success", err)
+ return
+ }
+
+ if got, want := resp.StatusCode, http.StatusOK; got != want {
+ t.Errorf("resp.StatusCode = %d; want %d", got, want)
+ t.Logf("%s", buf)
+ }
+
+ msg := new(examplepb.UnannotatedSimpleMessage)
+ if err := marshaler.Unmarshal(buf, msg); err != nil {
+ t.Errorf("marshaler.Unmarshal(%s, msg) failed with %v; want success", buf, err)
+ return
+ }
+ if got, want := msg.GetNo().GetNote(), "golang"; got != want {
+ t.Errorf("msg.GetNo().GetNote() = %q; want %q", got, want)
+ }
+
+ if value := resp.Header.Get("Content-Type"); value != contentType {
+ t.Errorf("Content-Type was %s, wanted %s", value, contentType)
+ }
+}
+
+func testEchoBody(t *testing.T, port int, apiPrefix string, useTrailers bool) {
+ sent := examplepb.UnannotatedSimpleMessage{Id: "example"}
+ payload, err := marshaler.Marshal(&sent)
+ if err != nil {
+ t.Fatalf("marshaler.Marshal(%#v) failed with %v; want success", payload, err)
+ }
+
+ apiURL := fmt.Sprintf("http://localhost:%d/%s/example/echo_body", port, apiPrefix)
+
+ req, err := http.NewRequest("POST", apiURL, bytes.NewReader(payload))
+ if err != nil {
+ t.Errorf("http.NewRequest() failed with %v; want success", err)
+ return
+ }
+ if useTrailers {
+ req.Header.Set("TE", "trailers")
+ }
+
+ resp, err := http.DefaultClient.Do(req)
+ if err != nil {
+ t.Errorf("client.Do(%v) failed with %v; want success", req, err)
+ return
+ }
+ defer resp.Body.Close()
+ buf, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ t.Errorf("ioutil.ReadAll(resp.Body) failed with %v; want success", err)
+ return
+ }
+
+ if got, want := resp.StatusCode, http.StatusOK; got != want {
+ t.Errorf("resp.StatusCode = %d; want %d", got, want)
+ t.Logf("%s", buf)
+ }
+
+ var received examplepb.UnannotatedSimpleMessage
+ if err := marshaler.Unmarshal(buf, &received); err != nil {
+ t.Errorf("marshaler.Unmarshal(%s, msg) failed with %v; want success", buf, err)
+ return
+ }
+ if diff := cmp.Diff(&received, &sent, protocmp.Transform()); diff != "" {
+ t.Errorf(diff)
+ }
+
+ if got, want := resp.Header.Get("Grpc-Metadata-Foo"), "foo1"; got != want {
+ t.Errorf("Grpc-Metadata-Foo was %q, wanted %q", got, want)
+ }
+ if got, want := resp.Header.Get("Grpc-Metadata-Bar"), "bar1"; got != want {
+ t.Errorf("Grpc-Metadata-Bar was %q, wanted %q", got, want)
+ }
+
+ wantedTrailers := map[bool]map[string]string{
+ true: {
+ "Grpc-Trailer-Foo": "foo2",
+ "Grpc-Trailer-Bar": "bar2",
+ },
+ false: {},
+ }
+
+ for trailer, want := range wantedTrailers[useTrailers] {
+ if got := resp.Trailer.Get(trailer); got != want {
+ t.Errorf("%s was %q, wanted %q", trailer, got, want)
+ }
+ }
+}
+
+func testEchoValidationRules(t *testing.T, port int, contentType string) {
+ sent := examplepb.ValidationRuleTestRequest{
+ Id: "example", // rules: NON_NIL, LEN_GT:2, LEN_LT: 61
+ Num: 11, // rules: GT:0
+ }
+ payload, err := marshaler.Marshal(&sent)
+ if err != nil {
+ t.Fatalf("marshaler.Marshal(%#v) failed with %v; want success", payload, err)
+ }
+
+ apiURL := fmt.Sprintf("http://localhost:%d/v1/example/echo:validationRules", port)
+ resp, err := http.Post(apiURL, "", bytes.NewReader(payload))
+ if err != nil {
+ t.Errorf("http.Post(%q) failed with %v; want success", apiURL, err)
+ return
+ }
+ defer resp.Body.Close()
+ buf, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ t.Errorf("ioutil.ReadAll(resp.Body) failed with %v; want success", err)
+ return
+ }
+
+ if got, want := resp.StatusCode, http.StatusOK; got != want {
+ t.Errorf("resp.StatusCode = %d; want %d", got, want)
+ t.Logf("%s", buf)
+ }
+
+ // Test validation error
+ sent = examplepb.ValidationRuleTestRequest{
+ Id: "a", // rules: NON_NIL, LEN_GT:2, LEN_LT: 61
+ Num: 0, // rules: GT:0
+ }
+ payload, err = marshaler.Marshal(&sent)
+ if err != nil {
+ t.Fatalf("marshaler.Marshal(%#v) failed with %v; want success", payload, err)
+ }
+
+ apiURL = fmt.Sprintf("http://localhost:%d/v1/example/echo:validationRules", port)
+ resp, err = http.Post(apiURL, "", bytes.NewReader(payload))
+ if err != nil {
+ t.Errorf("http.Post(%q) failed with %v; want success", apiURL, err)
+ return
+ }
+ defer resp.Body.Close()
+ buf, err = ioutil.ReadAll(resp.Body)
+ if err != nil {
+ t.Errorf("ioutil.ReadAll(resp.Body) failed with %v; want success", err)
+ return
+ }
+
+ if got, want := resp.StatusCode, http.StatusBadRequest; got != want {
+ t.Errorf("resp.StatusCode = %d; want %d", got, want)
+ t.Logf("%s", buf)
+ }
+
+ if value := resp.Header.Get("Content-Type"); value != contentType {
+ t.Errorf("Content-Type was %s, wanted %s", value, contentType)
+ }
+}
diff --git a/examples/internal/integration/main_test.go b/examples/internal/integration/main_test.go
new file mode 100644
index 0000000..6c06980
--- /dev/null
+++ b/examples/internal/integration/main_test.go
@@ -0,0 +1,100 @@
+package integration_test
+
+import (
+ "context"
+ "flag"
+ "fmt"
+ "net/http"
+ "os"
+ "testing"
+ "time"
+
+ "github.com/golang/glog"
+ "github.com/binchencoder/janus-gateway/examples/internal/gateway"
+ server "github.com/binchencoder/janus-gateway/examples/internal/server"
+ gwruntime "github.com/binchencoder/janus-gateway/gateway/runtime"
+)
+
+var (
+ endpoint = flag.String("endpoint", "localhost:9090", "endpoint of the gRPC service")
+ network = flag.String("network", "tcp", `one of "tcp" or "unix". Must be consistent to -endpoint`)
+ openAPIDir = flag.String("openapi_dir", "examples/internal/proto/examplepb", "path to the directory which contains OpenAPI definitions")
+)
+
+func runGateway(ctx context.Context, addr string, opts ...gwruntime.ServeMuxOption) error {
+ return gateway.Run(ctx, gateway.Options{
+ Addr: addr,
+ GRPCServer: gateway.Endpoint{
+ Network: *network,
+ Addr: *endpoint,
+ },
+ OpenAPIDir: *openAPIDir,
+ Mux: opts,
+ })
+}
+
+func waitForGateway(ctx context.Context, port uint16) error {
+ ch := time.After(10 * time.Second)
+
+ for {
+ r, err := http.Get(fmt.Sprintf("http://localhost:%d/healthz", port))
+ if err == nil && r.StatusCode == http.StatusOK {
+ return nil
+ }
+
+ glog.Infof("Waiting for localhost:%d to get ready", port)
+ select {
+ case <-ctx.Done():
+ return err
+ case <-ch:
+ return err
+ case <-time.After(10 * time.Millisecond):
+ }
+ }
+}
+
+func runServers(ctx context.Context) <-chan error {
+ ch := make(chan error, 3)
+ go func() {
+ if err := server.Run(ctx, *network, *endpoint); err != nil {
+ ch <- fmt.Errorf("cannot run grpc service: %v", err)
+ }
+ }()
+ go func() {
+ if err := runGateway(ctx, ":8088"); err != nil {
+ ch <- fmt.Errorf("cannot run gateway service: %v", err)
+ }
+ }()
+ go func() {
+ if err := server.RunInProcessGateway(ctx, ":8089"); err != nil {
+ ch <- fmt.Errorf("cannot run in process gateway service: %v", err)
+ }
+ }()
+ return ch
+}
+
+func TestMain(m *testing.M) {
+ flag.Parse()
+ defer glog.Flush()
+
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+ errCh := runServers(ctx)
+
+ ch := make(chan int, 1)
+ go func() {
+ if err := waitForGateway(ctx, 8088); err != nil {
+ glog.Errorf("waitForGateway(ctx, 8088) failed with %v; want success", err)
+ }
+ ch <- m.Run()
+ }()
+
+ select {
+ case err := <-errCh:
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ case status := <-ch:
+ cancel()
+ os.Exit(status)
+ }
+}
diff --git a/examples/internal/proto/examplepb/BUILD.bazel b/examples/internal/proto/examplepb/BUILD.bazel
new file mode 100644
index 0000000..bd69aa4
--- /dev/null
+++ b/examples/internal/proto/examplepb/BUILD.bazel
@@ -0,0 +1,148 @@
+load("@rules_proto//proto:defs.bzl", "proto_library")
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
+load("@com_github_binchencoder_janus_gateway//gateway/protoc-gen-openapiv2:defs.bzl", "protoc_gen_openapiv2")
+
+package(default_visibility = ["//visibility:public"])
+
+# TODO(yannic): Add examples/tests that use import_prefix/strip_import_prefix.
+
+# gazelle:exclude a_bit_of_everything.pb.gw.go
+# gazelle:exclude a_bit_of_everything_grpc.pb.go
+# gazelle:exclude echo_service.pb.gw.go
+# gazelle:exclude echo_service_grpc.pb.go
+# gazelle:exclude flow_combination.pb.gw.go
+# gazelle:exclude flow_combination_grpc.pb.go
+# gazelle:exclude generate_unbound_methods.pb.gw.go
+# gazelle:exclude generate_unbound_methods_grpc.pb.go
+# gazelle:exclude generated_input.proto
+# gazelle:exclude non_standard_names.pb.gw.go
+# gazelle:exclude non_standard_names_grpc.pb.go
+# gazelle:exclude response_body_service.pb.gw.go
+# gazelle:exclude response_body_service_grpc.pb.go
+# gazelle:exclude stream.pb.gw.go
+# gazelle:exclude stream_grpc.pb.go
+# gazelle:exclude use_go_template.pb.gw.go
+# gazelle:exclude use_go_template_grpc.pb.go
+# gazelle:exclude wrappers.pb.gw.go
+# gazelle:exclude wrappers_grpc.pb.go
+# gazelle:exclude unannotated_echo_service.pb.gw.go
+# gazelle:exclude unannotated_echo_service_grpc.pb.go
+# gazelle:exclude visibility_rule_echo_service.pb.gw.go
+# gazelle:exclude visibility_rule_echo_service_grpc.pb.go
+# gazelle:exclude openapi_merge_a.proto
+# gazelle:exclude openapi_merge_b.proto
+# gazelle:go_grpc_compilers //:go_apiv2, //:go_grpc, //protoc-gen-grpc-gateway:go_gen_grpc_gateway
+
+genrule(
+ name = "generated_proto",
+ srcs = ["generated_input.proto"],
+ outs = ["generated_output.proto"],
+ cmd = "cp $< $@", # A simple copy simulates a generated proto file.
+)
+
+proto_library(
+ name = "examplepb_proto",
+ srcs = [
+ "echo_service.proto",
+ "unannotated_echo_service.proto",
+ ],
+ deps = [
+ "//httpoptions:options_proto",
+ "//gateway/protoc-gen-openapiv2/options:options_proto",
+ "@com_github_binchencoder_gateway_proto//data:data_proto",
+ "@com_github_binchencoder_gateway_proto//frontend:error_proto",
+ "@com_google_protobuf//:duration_proto",
+ "@com_google_protobuf//:empty_proto",
+ "@com_google_protobuf//:field_mask_proto",
+ "@com_google_protobuf//:struct_proto",
+ "@com_google_protobuf//:timestamp_proto",
+ "@com_google_protobuf//:wrappers_proto",
+ "@go_googleapis//google/api:annotations_proto",
+ "@go_googleapis//google/api:httpbody_proto",
+ "@go_googleapis//google/api:visibility_proto",
+ "@go_googleapis//google/rpc:status_proto",
+ ],
+)
+
+#keep
+# proto_library(
+# name = "openapi_merge_proto",
+# srcs = [
+# "openapi_merge_a.proto",
+# "openapi_merge_b.proto",
+# ],
+# deps = [
+# "@go_googleapis//google/api:annotations_proto",
+# "@go_googleapis//google/api:httpbody_proto",
+# ],
+# )
+
+go_proto_library(
+ name = "examplepb_go_proto",
+ compilers = [
+ "//:go_apiv2",
+ "//:go_grpc",
+ "//gateway/protoc-gen-grpc-gateway:go_gen_grpc_gateway",
+ ],
+ importpath = "github.com/binchencoder/janus-gateway/examples/internal/proto/examplepb",
+ proto = ":examplepb_proto",
+ deps = [
+ "//httpoptions",
+ "@com_github_binchencoder_letsgo//grpc:go_default_library",
+ "@com_github_binchencoder_skylb_api//client:go_default_library",
+ "@com_github_binchencoder_skylb_api//proto:go_default_library",
+ "//gateway/protoc-gen-openapiv2/options",
+ "@com_github_golang_protobuf//descriptor:go_default_library_gen", # keep
+ "@go_googleapis//google/api:annotations_go_proto",
+ "@go_googleapis//google/api:httpbody_go_proto",
+ "@go_googleapis//google/api:visibility_go_proto",
+ "@go_googleapis//google/rpc:status_go_proto",
+ "@org_golang_google_protobuf//proto:go_default_library", # keep
+ ],
+)
+
+go_library(
+ name = "examplepb",
+ embed = [":examplepb_go_proto"],
+ importpath = "github.com/binchencoder/janus-gateway/examples/internal/proto/examplepb",
+ deps = [
+ "//httpoptions",
+ "//gateway/runtime",
+ "@com_github_grpc_ecosystem_grpc_gateway//utilities",
+ "@com_github_binchencoder_gateway_proto//frontend:go_default_library",
+ "@com_github_binchencoder_skylb_api//client:go_default_library",
+ "@go_googleapis//google/api:annotations_go_proto",
+ "@org_golang_google_grpc//:go_default_library",
+ "@org_golang_google_grpc//codes",
+ "@org_golang_google_grpc//grpclog",
+ "@org_golang_google_grpc//metadata",
+ "@org_golang_google_grpc//status",
+ "@org_golang_google_protobuf//proto",
+ "@org_golang_google_protobuf//reflect/protoreflect",
+ "@org_golang_google_protobuf//runtime/protoimpl",
+ ],
+)
+
+protoc_gen_openapiv2(
+ name = "examplepb_protoc_gen_openapiv2",
+ proto = ":examplepb_proto",
+)
+
+protoc_gen_openapiv2(
+ name = "examplepb_protoc_gen_openapiv2_merged",
+ proto = ":examplepb_proto",
+ single_output = True, # Outputs a single swagger.json file.
+)
+
+# protoc_gen_openapiv2(
+# name = "examplepb_openapi_merge",
+# proto = ":openapi_merge_proto",
+# single_output = True, # Outputs a single swagger.json file.
+# )
+
+alias(
+ name = "go_default_library",
+ actual = ":examplepb",
+ visibility = ["//examples:__subpackages__"],
+)
diff --git a/examples/internal/proto/examplepb/echo_service.pb.go b/examples/internal/proto/examplepb/echo_service.pb.go
new file mode 100755
index 0000000..eb22854
--- /dev/null
+++ b/examples/internal/proto/examplepb/echo_service.pb.go
@@ -0,0 +1,753 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.27.1
+// protoc v3.19.4
+// source: examples/internal/proto/examplepb/echo_service.proto
+
+package examplepb
+
+import (
+ _ "github.com/binchencoder/janus-gateway/httpoptions"
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb"
+ structpb "google.golang.org/protobuf/types/known/structpb"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type Embedded struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Types that are assignable to Mark:
+ // *Embedded_Progress
+ // *Embedded_Note
+ Mark isEmbedded_Mark `protobuf_oneof:"mark"`
+}
+
+func (x *Embedded) Reset() {
+ *x = Embedded{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_examples_internal_proto_examplepb_echo_service_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Embedded) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Embedded) ProtoMessage() {}
+
+func (x *Embedded) ProtoReflect() protoreflect.Message {
+ mi := &file_examples_internal_proto_examplepb_echo_service_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Embedded.ProtoReflect.Descriptor instead.
+func (*Embedded) Descriptor() ([]byte, []int) {
+ return file_examples_internal_proto_examplepb_echo_service_proto_rawDescGZIP(), []int{0}
+}
+
+func (m *Embedded) GetMark() isEmbedded_Mark {
+ if m != nil {
+ return m.Mark
+ }
+ return nil
+}
+
+func (x *Embedded) GetProgress() int64 {
+ if x, ok := x.GetMark().(*Embedded_Progress); ok {
+ return x.Progress
+ }
+ return 0
+}
+
+func (x *Embedded) GetNote() string {
+ if x, ok := x.GetMark().(*Embedded_Note); ok {
+ return x.Note
+ }
+ return ""
+}
+
+type isEmbedded_Mark interface {
+ isEmbedded_Mark()
+}
+
+type Embedded_Progress struct {
+ Progress int64 `protobuf:"varint,1,opt,name=progress,proto3,oneof"`
+}
+
+type Embedded_Note struct {
+ Note string `protobuf:"bytes,2,opt,name=note,proto3,oneof"`
+}
+
+func (*Embedded_Progress) isEmbedded_Mark() {}
+
+func (*Embedded_Note) isEmbedded_Mark() {}
+
+type SimpleMessage struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
+ Num int64 `protobuf:"varint,2,opt,name=num,proto3" json:"num,omitempty"`
+ // Types that are assignable to Code:
+ // *SimpleMessage_LineNum
+ // *SimpleMessage_Lang
+ Code isSimpleMessage_Code `protobuf_oneof:"code"`
+ Status *Embedded `protobuf:"bytes,5,opt,name=status,proto3" json:"status,omitempty"`
+ // Types that are assignable to Ext:
+ // *SimpleMessage_En
+ // *SimpleMessage_No
+ Ext isSimpleMessage_Ext `protobuf_oneof:"ext"`
+}
+
+func (x *SimpleMessage) Reset() {
+ *x = SimpleMessage{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_examples_internal_proto_examplepb_echo_service_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SimpleMessage) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SimpleMessage) ProtoMessage() {}
+
+func (x *SimpleMessage) ProtoReflect() protoreflect.Message {
+ mi := &file_examples_internal_proto_examplepb_echo_service_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use SimpleMessage.ProtoReflect.Descriptor instead.
+func (*SimpleMessage) Descriptor() ([]byte, []int) {
+ return file_examples_internal_proto_examplepb_echo_service_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *SimpleMessage) GetId() string {
+ if x != nil {
+ return x.Id
+ }
+ return ""
+}
+
+func (x *SimpleMessage) GetNum() int64 {
+ if x != nil {
+ return x.Num
+ }
+ return 0
+}
+
+func (m *SimpleMessage) GetCode() isSimpleMessage_Code {
+ if m != nil {
+ return m.Code
+ }
+ return nil
+}
+
+func (x *SimpleMessage) GetLineNum() int64 {
+ if x, ok := x.GetCode().(*SimpleMessage_LineNum); ok {
+ return x.LineNum
+ }
+ return 0
+}
+
+func (x *SimpleMessage) GetLang() string {
+ if x, ok := x.GetCode().(*SimpleMessage_Lang); ok {
+ return x.Lang
+ }
+ return ""
+}
+
+func (x *SimpleMessage) GetStatus() *Embedded {
+ if x != nil {
+ return x.Status
+ }
+ return nil
+}
+
+func (m *SimpleMessage) GetExt() isSimpleMessage_Ext {
+ if m != nil {
+ return m.Ext
+ }
+ return nil
+}
+
+func (x *SimpleMessage) GetEn() int64 {
+ if x, ok := x.GetExt().(*SimpleMessage_En); ok {
+ return x.En
+ }
+ return 0
+}
+
+func (x *SimpleMessage) GetNo() *Embedded {
+ if x, ok := x.GetExt().(*SimpleMessage_No); ok {
+ return x.No
+ }
+ return nil
+}
+
+type isSimpleMessage_Code interface {
+ isSimpleMessage_Code()
+}
+
+type SimpleMessage_LineNum struct {
+ LineNum int64 `protobuf:"varint,3,opt,name=line_num,json=lineNum,proto3,oneof"`
+}
+
+type SimpleMessage_Lang struct {
+ Lang string `protobuf:"bytes,4,opt,name=lang,proto3,oneof"`
+}
+
+func (*SimpleMessage_LineNum) isSimpleMessage_Code() {}
+
+func (*SimpleMessage_Lang) isSimpleMessage_Code() {}
+
+type isSimpleMessage_Ext interface {
+ isSimpleMessage_Ext()
+}
+
+type SimpleMessage_En struct {
+ En int64 `protobuf:"varint,6,opt,name=en,proto3,oneof"`
+}
+
+type SimpleMessage_No struct {
+ No *Embedded `protobuf:"bytes,7,opt,name=no,proto3,oneof"`
+}
+
+func (*SimpleMessage_En) isSimpleMessage_Ext() {}
+
+func (*SimpleMessage_No) isSimpleMessage_Ext() {}
+
+type ValidationRuleTestRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
+ Num int64 `protobuf:"varint,2,opt,name=num,proto3" json:"num,omitempty"`
+}
+
+func (x *ValidationRuleTestRequest) Reset() {
+ *x = ValidationRuleTestRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_examples_internal_proto_examplepb_echo_service_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ValidationRuleTestRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ValidationRuleTestRequest) ProtoMessage() {}
+
+func (x *ValidationRuleTestRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_examples_internal_proto_examplepb_echo_service_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ValidationRuleTestRequest.ProtoReflect.Descriptor instead.
+func (*ValidationRuleTestRequest) Descriptor() ([]byte, []int) {
+ return file_examples_internal_proto_examplepb_echo_service_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *ValidationRuleTestRequest) GetId() string {
+ if x != nil {
+ return x.Id
+ }
+ return ""
+}
+
+func (x *ValidationRuleTestRequest) GetNum() int64 {
+ if x != nil {
+ return x.Num
+ }
+ return 0
+}
+
+type ValidationRuleTestResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+}
+
+func (x *ValidationRuleTestResponse) Reset() {
+ *x = ValidationRuleTestResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_examples_internal_proto_examplepb_echo_service_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ValidationRuleTestResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ValidationRuleTestResponse) ProtoMessage() {}
+
+func (x *ValidationRuleTestResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_examples_internal_proto_examplepb_echo_service_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ValidationRuleTestResponse.ProtoReflect.Descriptor instead.
+func (*ValidationRuleTestResponse) Descriptor() ([]byte, []int) {
+ return file_examples_internal_proto_examplepb_echo_service_proto_rawDescGZIP(), []int{3}
+}
+
+type DynamicMessage struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ StructField *structpb.Struct `protobuf:"bytes,1,opt,name=struct_field,json=structField,proto3" json:"struct_field,omitempty"`
+ ValueField *structpb.Value `protobuf:"bytes,2,opt,name=value_field,json=valueField,proto3" json:"value_field,omitempty"`
+}
+
+func (x *DynamicMessage) Reset() {
+ *x = DynamicMessage{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_examples_internal_proto_examplepb_echo_service_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *DynamicMessage) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DynamicMessage) ProtoMessage() {}
+
+func (x *DynamicMessage) ProtoReflect() protoreflect.Message {
+ mi := &file_examples_internal_proto_examplepb_echo_service_proto_msgTypes[4]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use DynamicMessage.ProtoReflect.Descriptor instead.
+func (*DynamicMessage) Descriptor() ([]byte, []int) {
+ return file_examples_internal_proto_examplepb_echo_service_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *DynamicMessage) GetStructField() *structpb.Struct {
+ if x != nil {
+ return x.StructField
+ }
+ return nil
+}
+
+func (x *DynamicMessage) GetValueField() *structpb.Value {
+ if x != nil {
+ return x.ValueField
+ }
+ return nil
+}
+
+type DynamicMessageUpdate struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Body *DynamicMessage `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"`
+ UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,2,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"`
+}
+
+func (x *DynamicMessageUpdate) Reset() {
+ *x = DynamicMessageUpdate{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_examples_internal_proto_examplepb_echo_service_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *DynamicMessageUpdate) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DynamicMessageUpdate) ProtoMessage() {}
+
+func (x *DynamicMessageUpdate) ProtoReflect() protoreflect.Message {
+ mi := &file_examples_internal_proto_examplepb_echo_service_proto_msgTypes[5]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use DynamicMessageUpdate.ProtoReflect.Descriptor instead.
+func (*DynamicMessageUpdate) Descriptor() ([]byte, []int) {
+ return file_examples_internal_proto_examplepb_echo_service_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *DynamicMessageUpdate) GetBody() *DynamicMessage {
+ if x != nil {
+ return x.Body
+ }
+ return nil
+}
+
+func (x *DynamicMessageUpdate) GetUpdateMask() *fieldmaskpb.FieldMask {
+ if x != nil {
+ return x.UpdateMask
+ }
+ return nil
+}
+
+var File_examples_internal_proto_examplepb_echo_service_proto protoreflect.FileDescriptor
+
+var file_examples_internal_proto_examplepb_echo_service_proto_rawDesc = []byte{
+ 0x0a, 0x34, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72,
+ 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
+ 0x65, 0x70, 0x62, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74,
+ 0x65, 0x77, 0x61, 0x79, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x69, 0x6e,
+ 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x65, 0x78, 0x61,
+ 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x1a, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x6f, 0x70, 0x74, 0x69,
+ 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73,
+ 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x46, 0x0a, 0x08, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65,
+ 0x64, 0x12, 0x1c, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12,
+ 0x14, 0x0a, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52,
+ 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x22, 0xa3, 0x02,
+ 0x0a, 0x0d, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12,
+ 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12,
+ 0x10, 0x0a, 0x03, 0x6e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x6e, 0x75,
+ 0x6d, 0x12, 0x1b, 0x0a, 0x08, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x07, 0x6c, 0x69, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x12, 0x14,
+ 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04,
+ 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x50, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65,
+ 0x77, 0x61, 0x79, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74,
+ 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x65, 0x78, 0x61, 0x6d,
+ 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x52, 0x06,
+ 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x10, 0x0a, 0x02, 0x65, 0x6e, 0x18, 0x06, 0x20, 0x01,
+ 0x28, 0x03, 0x48, 0x01, 0x52, 0x02, 0x65, 0x6e, 0x12, 0x4a, 0x0a, 0x02, 0x6e, 0x6f, 0x18, 0x07,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65,
+ 0x77, 0x61, 0x79, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74,
+ 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x65, 0x78, 0x61, 0x6d,
+ 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x48, 0x01,
+ 0x52, 0x02, 0x6e, 0x6f, 0x42, 0x06, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x42, 0x05, 0x0a, 0x03,
+ 0x65, 0x78, 0x74, 0x22, 0x6f, 0x0a, 0x19, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x12, 0x31, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xb2, 0xe4,
+ 0x34, 0x1d, 0x0a, 0x04, 0x08, 0x05, 0x10, 0x02, 0x0a, 0x09, 0x08, 0x06, 0x10, 0x02, 0x1a, 0x01,
+ 0x32, 0x20, 0x01, 0x0a, 0x0a, 0x08, 0x07, 0x10, 0x02, 0x1a, 0x02, 0x36, 0x31, 0x20, 0x01, 0x52,
+ 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x03, 0x6e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03,
+ 0x42, 0x0d, 0xb2, 0xe4, 0x34, 0x09, 0x0a, 0x07, 0x08, 0x01, 0x10, 0x01, 0x1a, 0x01, 0x30, 0x52,
+ 0x03, 0x6e, 0x75, 0x6d, 0x22, 0x1c, 0x0a, 0x1a, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69,
+ 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+ 0x73, 0x65, 0x22, 0x85, 0x01, 0x0a, 0x0e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x65,
+ 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3a, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x5f,
+ 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f,
+ 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74,
+ 0x72, 0x75, 0x63, 0x74, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x46, 0x69, 0x65, 0x6c,
+ 0x64, 0x12, 0x37, 0x0a, 0x0b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a,
+ 0x76, 0x61, 0x6c, 0x75, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x22, 0xa7, 0x01, 0x0a, 0x14, 0x44,
+ 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x70, 0x64,
+ 0x61, 0x74, 0x65, 0x12, 0x52, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x3e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
+ 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
+ 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
+ 0x70, 0x62, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
+ 0x65, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74,
+ 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67,
+ 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46,
+ 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65,
+ 0x4d, 0x61, 0x73, 0x6b, 0x32, 0xd5, 0x08, 0x0a, 0x0b, 0x45, 0x63, 0x68, 0x6f, 0x53, 0x65, 0x72,
+ 0x76, 0x69, 0x63, 0x65, 0x12, 0xba, 0x02, 0x0a, 0x04, 0x45, 0x63, 0x68, 0x6f, 0x12, 0x3d, 0x2e,
+ 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x65, 0x78, 0x61,
+ 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x53,
+ 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x3d, 0x2e, 0x67,
+ 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x65, 0x78, 0x61, 0x6d,
+ 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x53, 0x69,
+ 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xb3, 0x01, 0xca, 0xf3,
+ 0x34, 0xae, 0x01, 0x22, 0x15, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
+ 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x5a, 0x1d, 0x12, 0x1b, 0x2f, 0x76,
+ 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x2f, 0x7b,
+ 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x6e, 0x75, 0x6d, 0x7d, 0x5a, 0x24, 0x12, 0x22, 0x2f, 0x76, 0x31,
+ 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x2f, 0x7b, 0x69,
+ 0x64, 0x7d, 0x2f, 0x7b, 0x6e, 0x75, 0x6d, 0x7d, 0x2f, 0x7b, 0x6c, 0x61, 0x6e, 0x67, 0x7d, 0x5a,
+ 0x31, 0x12, 0x2f, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65,
+ 0x63, 0x68, 0x6f, 0x31, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x6c, 0x69, 0x6e, 0x65, 0x5f,
+ 0x6e, 0x75, 0x6d, 0x7d, 0x2f, 0x7b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x6e, 0x6f, 0x74,
+ 0x65, 0x7d, 0x5a, 0x1d, 0x12, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
+ 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x32, 0x2f, 0x7b, 0x6e, 0x6f, 0x2e, 0x6e, 0x6f, 0x74, 0x65,
+ 0x7d, 0x12, 0xa8, 0x01, 0x0a, 0x08, 0x45, 0x63, 0x68, 0x6f, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x3d,
+ 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x65, 0x78,
+ 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e,
+ 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x3d, 0x2e,
+ 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x65, 0x78, 0x61,
+ 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x53,
+ 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x1e, 0xca, 0xf3,
+ 0x34, 0x1a, 0x22, 0x15, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f,
+ 0x65, 0x63, 0x68, 0x6f, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x3a, 0x01, 0x2a, 0x12, 0xa9, 0x01, 0x0a,
+ 0x0a, 0x45, 0x63, 0x68, 0x6f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x3d, 0x2e, 0x67, 0x72,
+ 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70,
+ 0x6c, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x53, 0x69, 0x6d,
+ 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x3d, 0x2e, 0x67, 0x72, 0x70,
+ 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
+ 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x53, 0x69, 0x6d, 0x70,
+ 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x1d, 0xca, 0xf3, 0x34, 0x19, 0x2a,
+ 0x17, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68,
+ 0x6f, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0xbb, 0x01, 0x0a, 0x09, 0x45, 0x63, 0x68,
+ 0x6f, 0x50, 0x61, 0x74, 0x63, 0x68, 0x12, 0x44, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61,
+ 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x69,
+ 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x65, 0x78,
+ 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d,
+ 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x1a, 0x44, 0x2e, 0x67,
+ 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x65, 0x78, 0x61, 0x6d,
+ 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x44, 0x79,
+ 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x70, 0x64, 0x61,
+ 0x74, 0x65, 0x22, 0x22, 0xca, 0xf3, 0x34, 0x1e, 0x32, 0x16, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78,
+ 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x5f, 0x70, 0x61, 0x74, 0x63, 0x68,
+ 0x3a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0xd6, 0x01, 0x0a, 0x12, 0x45, 0x63, 0x68, 0x6f, 0x56,
+ 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x49, 0x2e,
+ 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x65, 0x78, 0x61,
+ 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x56,
+ 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x65, 0x73,
+ 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x4a, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e,
+ 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73,
+ 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
+ 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70,
+ 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x29, 0xca, 0xf3, 0x34, 0x25, 0x22, 0x20, 0x2f, 0x76, 0x31, 0x2f,
+ 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x3a, 0x76, 0x61, 0x6c,
+ 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x3a, 0x01, 0x2a, 0x1a,
+ 0x1b, 0xea, 0xf3, 0x34, 0x17, 0x08, 0xb6, 0x95, 0xff, 0xff, 0x07, 0x12, 0x04, 0x67, 0x72, 0x70,
+ 0x63, 0x1a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x01, 0x42, 0x52, 0x5a, 0x50,
+ 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x69, 0x6e, 0x63, 0x68,
+ 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x65, 0x61, 0x73, 0x65, 0x2d, 0x67, 0x61, 0x74,
+ 0x65, 0x77, 0x61, 0x79, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x69, 0x6e,
+ 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x78, 0x61,
+ 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x3b, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62,
+ 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_examples_internal_proto_examplepb_echo_service_proto_rawDescOnce sync.Once
+ file_examples_internal_proto_examplepb_echo_service_proto_rawDescData = file_examples_internal_proto_examplepb_echo_service_proto_rawDesc
+)
+
+func file_examples_internal_proto_examplepb_echo_service_proto_rawDescGZIP() []byte {
+ file_examples_internal_proto_examplepb_echo_service_proto_rawDescOnce.Do(func() {
+ file_examples_internal_proto_examplepb_echo_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_examples_internal_proto_examplepb_echo_service_proto_rawDescData)
+ })
+ return file_examples_internal_proto_examplepb_echo_service_proto_rawDescData
+}
+
+var file_examples_internal_proto_examplepb_echo_service_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
+var file_examples_internal_proto_examplepb_echo_service_proto_goTypes = []interface{}{
+ (*Embedded)(nil), // 0: grpc.gateway.examples.internal.proto.examplepb.Embedded
+ (*SimpleMessage)(nil), // 1: grpc.gateway.examples.internal.proto.examplepb.SimpleMessage
+ (*ValidationRuleTestRequest)(nil), // 2: grpc.gateway.examples.internal.proto.examplepb.ValidationRuleTestRequest
+ (*ValidationRuleTestResponse)(nil), // 3: grpc.gateway.examples.internal.proto.examplepb.ValidationRuleTestResponse
+ (*DynamicMessage)(nil), // 4: grpc.gateway.examples.internal.proto.examplepb.DynamicMessage
+ (*DynamicMessageUpdate)(nil), // 5: grpc.gateway.examples.internal.proto.examplepb.DynamicMessageUpdate
+ (*structpb.Struct)(nil), // 6: google.protobuf.Struct
+ (*structpb.Value)(nil), // 7: google.protobuf.Value
+ (*fieldmaskpb.FieldMask)(nil), // 8: google.protobuf.FieldMask
+}
+var file_examples_internal_proto_examplepb_echo_service_proto_depIdxs = []int32{
+ 0, // 0: grpc.gateway.examples.internal.proto.examplepb.SimpleMessage.status:type_name -> grpc.gateway.examples.internal.proto.examplepb.Embedded
+ 0, // 1: grpc.gateway.examples.internal.proto.examplepb.SimpleMessage.no:type_name -> grpc.gateway.examples.internal.proto.examplepb.Embedded
+ 6, // 2: grpc.gateway.examples.internal.proto.examplepb.DynamicMessage.struct_field:type_name -> google.protobuf.Struct
+ 7, // 3: grpc.gateway.examples.internal.proto.examplepb.DynamicMessage.value_field:type_name -> google.protobuf.Value
+ 4, // 4: grpc.gateway.examples.internal.proto.examplepb.DynamicMessageUpdate.body:type_name -> grpc.gateway.examples.internal.proto.examplepb.DynamicMessage
+ 8, // 5: grpc.gateway.examples.internal.proto.examplepb.DynamicMessageUpdate.update_mask:type_name -> google.protobuf.FieldMask
+ 1, // 6: grpc.gateway.examples.internal.proto.examplepb.EchoService.Echo:input_type -> grpc.gateway.examples.internal.proto.examplepb.SimpleMessage
+ 1, // 7: grpc.gateway.examples.internal.proto.examplepb.EchoService.EchoBody:input_type -> grpc.gateway.examples.internal.proto.examplepb.SimpleMessage
+ 1, // 8: grpc.gateway.examples.internal.proto.examplepb.EchoService.EchoDelete:input_type -> grpc.gateway.examples.internal.proto.examplepb.SimpleMessage
+ 5, // 9: grpc.gateway.examples.internal.proto.examplepb.EchoService.EchoPatch:input_type -> grpc.gateway.examples.internal.proto.examplepb.DynamicMessageUpdate
+ 2, // 10: grpc.gateway.examples.internal.proto.examplepb.EchoService.EchoValidationRule:input_type -> grpc.gateway.examples.internal.proto.examplepb.ValidationRuleTestRequest
+ 1, // 11: grpc.gateway.examples.internal.proto.examplepb.EchoService.Echo:output_type -> grpc.gateway.examples.internal.proto.examplepb.SimpleMessage
+ 1, // 12: grpc.gateway.examples.internal.proto.examplepb.EchoService.EchoBody:output_type -> grpc.gateway.examples.internal.proto.examplepb.SimpleMessage
+ 1, // 13: grpc.gateway.examples.internal.proto.examplepb.EchoService.EchoDelete:output_type -> grpc.gateway.examples.internal.proto.examplepb.SimpleMessage
+ 5, // 14: grpc.gateway.examples.internal.proto.examplepb.EchoService.EchoPatch:output_type -> grpc.gateway.examples.internal.proto.examplepb.DynamicMessageUpdate
+ 3, // 15: grpc.gateway.examples.internal.proto.examplepb.EchoService.EchoValidationRule:output_type -> grpc.gateway.examples.internal.proto.examplepb.ValidationRuleTestResponse
+ 11, // [11:16] is the sub-list for method output_type
+ 6, // [6:11] is the sub-list for method input_type
+ 6, // [6:6] is the sub-list for extension type_name
+ 6, // [6:6] is the sub-list for extension extendee
+ 0, // [0:6] is the sub-list for field type_name
+}
+
+func init() { file_examples_internal_proto_examplepb_echo_service_proto_init() }
+func file_examples_internal_proto_examplepb_echo_service_proto_init() {
+ if File_examples_internal_proto_examplepb_echo_service_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_examples_internal_proto_examplepb_echo_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Embedded); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_examples_internal_proto_examplepb_echo_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SimpleMessage); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_examples_internal_proto_examplepb_echo_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ValidationRuleTestRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_examples_internal_proto_examplepb_echo_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ValidationRuleTestResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_examples_internal_proto_examplepb_echo_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*DynamicMessage); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_examples_internal_proto_examplepb_echo_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*DynamicMessageUpdate); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ file_examples_internal_proto_examplepb_echo_service_proto_msgTypes[0].OneofWrappers = []interface{}{
+ (*Embedded_Progress)(nil),
+ (*Embedded_Note)(nil),
+ }
+ file_examples_internal_proto_examplepb_echo_service_proto_msgTypes[1].OneofWrappers = []interface{}{
+ (*SimpleMessage_LineNum)(nil),
+ (*SimpleMessage_Lang)(nil),
+ (*SimpleMessage_En)(nil),
+ (*SimpleMessage_No)(nil),
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_examples_internal_proto_examplepb_echo_service_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 6,
+ NumExtensions: 0,
+ NumServices: 1,
+ },
+ GoTypes: file_examples_internal_proto_examplepb_echo_service_proto_goTypes,
+ DependencyIndexes: file_examples_internal_proto_examplepb_echo_service_proto_depIdxs,
+ MessageInfos: file_examples_internal_proto_examplepb_echo_service_proto_msgTypes,
+ }.Build()
+ File_examples_internal_proto_examplepb_echo_service_proto = out.File
+ file_examples_internal_proto_examplepb_echo_service_proto_rawDesc = nil
+ file_examples_internal_proto_examplepb_echo_service_proto_goTypes = nil
+ file_examples_internal_proto_examplepb_echo_service_proto_depIdxs = nil
+}
diff --git a/examples/internal/proto/examplepb/echo_service.pb.gw.go b/examples/internal/proto/examplepb/echo_service.pb.gw.go
new file mode 100755
index 0000000..bc7235f
--- /dev/null
+++ b/examples/internal/proto/examplepb/echo_service.pb.gw.go
@@ -0,0 +1,1575 @@
+// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
+// source: examples/internal/proto/examplepb/echo_service.proto
+
+/*
+Package examplepb is a reverse proxy.
+
+It translates gRPC into RESTful JSON APIs.
+*/
+package examplepb
+
+import (
+ "context"
+ "io"
+ "net/http"
+ "regexp"
+ "strings"
+ "sync"
+ "unicode/utf8"
+
+ "github.com/binchencoder/janus-gateway/gateway/runtime"
+ vexpb "github.com/binchencoder/gateway-proto/data"
+ fpb "github.com/binchencoder/gateway-proto/frontend"
+ lgr "github.com/binchencoder/letsgo/grpc"
+ "github.com/binchencoder/skylb-api/client"
+ skypb "github.com/binchencoder/skylb-api/proto"
+ "github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/grpclog"
+ "google.golang.org/grpc/metadata"
+ "google.golang.org/grpc/status"
+ "google.golang.org/protobuf/proto"
+)
+
+// Suppress "imported and not used" errors
+var _ codes.Code
+var _ io.Reader
+var _ status.Status
+var _ = runtime.String
+var _ = utilities.NewDoubleArray
+var _ = metadata.Join
+
+// var _ = descriptor.ForMessage
+var _ sync.RWMutex
+var _ proto.Message
+var _ context.Context
+var _ grpc.ClientConn
+var _ client.ServiceCli
+var _ vexpb.ServiceId
+var _ = http.MethodGet
+var _ regexp.Regexp
+
+// var _ = balancer.ConsistentHashing
+// var _ option.BalancerCreator
+// var _ naming.Resolver
+var _ strings.Reader
+var _ = utf8.UTFMax
+
+// TODO (jiezmo): check if there is any rule before create this var.
+var examples_internal_proto_examplepb_echo_service_error = lgr.ToGrpcError(codes.InvalidArgument, &fpb.Error{Code: fpb.ErrorCode_BADPARAM_ERROR, Params: []string{"Validation error"}})
+
+// Validation methods start
+
+func Validate__grpc_gateway_examples_internal_proto_examplepb_ValidationRuleTestRequest(v *ValidationRuleTestRequest) error {
+ if v == nil {
+ return nil
+ }
+ // Validation for each Fields
+
+ {
+ vv2 := v.Id
+
+ // Validation Field: Id
+
+ // TODO(jiezmo): fail the build
+ // Err
+
+ if utf8.RuneCountInString(strings.TrimSpace(vv2)) <= 2 {
+ return examples_internal_proto_examplepb_echo_service_error
+ }
+
+ if utf8.RuneCountInString(strings.TrimSpace(vv2)) >= 61 {
+ return examples_internal_proto_examplepb_echo_service_error
+ }
+
+ }
+
+ {
+ vv2 := v.Num
+
+ // Validation Field: Num
+
+ if vv2 <= 0 {
+ return examples_internal_proto_examplepb_echo_service_error
+ }
+
+ }
+
+ return nil
+}
+
+// Validation methods done
+
+var (
+ filter_EchoService_Echo_0 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
+)
+
+func request_EchoService_Echo_0(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq SimpleMessage
+ var metadata runtime.ServerMetadata
+ spec := internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec
+
+ var (
+ val string
+ ok bool
+ err error
+ _ = err
+ )
+
+ val, ok = pathParams["id"]
+ if !ok {
+ runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
+ }
+
+ protoReq.Id, err = runtime.String(val)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
+ }
+
+ if err := req.ParseForm(); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+ if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_Echo_0); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+
+ // Only hook up for non-stream call for now.
+
+ runtime.RequestParsed(ctx, spec, "EchoService", "Echo", &protoReq, &metadata)
+ ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
+ msg, err := client.Echo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+ // if err != nil {
+ // grpclog.Errorf("client.%s returns error: %v", "Echo", err)
+ // }
+ runtime.RequestHandled(ctx, spec, "EchoService", "Echo", msg, &metadata, err)
+ return msg, metadata, err
+
+}
+
+func local_request_EchoService_Echo_0(ctx context.Context, marshaler runtime.Marshaler, server EchoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq SimpleMessage
+ var metadata runtime.ServerMetadata
+
+ var (
+ val string
+ ok bool
+ err error
+ _ = err
+ )
+
+ val, ok = pathParams["id"]
+ if !ok {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
+ }
+
+ protoReq.Id, err = runtime.String(val)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
+ }
+
+ if err := req.ParseForm(); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+ if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_Echo_0); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+
+ msg, err := server.Echo(ctx, &protoReq)
+ return msg, metadata, err
+
+}
+
+var (
+ filter_EchoService_Echo_1 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0, "num": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}}
+)
+
+func request_EchoService_Echo_1(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq SimpleMessage
+ var metadata runtime.ServerMetadata
+ spec := internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec
+
+ var (
+ val string
+ ok bool
+ err error
+ _ = err
+ )
+
+ val, ok = pathParams["id"]
+ if !ok {
+ runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
+ }
+
+ protoReq.Id, err = runtime.String(val)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
+ }
+
+ val, ok = pathParams["num"]
+ if !ok {
+ runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "num")
+ }
+
+ protoReq.Num, err = runtime.Int64(val)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "num", err)
+ }
+
+ if err := req.ParseForm(); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+ if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_Echo_1); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+
+ // Only hook up for non-stream call for now.
+
+ runtime.RequestParsed(ctx, spec, "EchoService", "Echo", &protoReq, &metadata)
+ ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
+ msg, err := client.Echo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+ // if err != nil {
+ // grpclog.Errorf("client.%s returns error: %v", "Echo", err)
+ // }
+ runtime.RequestHandled(ctx, spec, "EchoService", "Echo", msg, &metadata, err)
+ return msg, metadata, err
+
+}
+
+func local_request_EchoService_Echo_1(ctx context.Context, marshaler runtime.Marshaler, server EchoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq SimpleMessage
+ var metadata runtime.ServerMetadata
+
+ var (
+ val string
+ ok bool
+ err error
+ _ = err
+ )
+
+ val, ok = pathParams["id"]
+ if !ok {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
+ }
+
+ protoReq.Id, err = runtime.String(val)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
+ }
+
+ val, ok = pathParams["num"]
+ if !ok {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "num")
+ }
+
+ protoReq.Num, err = runtime.Int64(val)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "num", err)
+ }
+
+ if err := req.ParseForm(); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+ if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_Echo_1); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+
+ msg, err := server.Echo(ctx, &protoReq)
+ return msg, metadata, err
+
+}
+
+var (
+ filter_EchoService_Echo_2 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0, "num": 1, "lang": 2}, Base: []int{1, 1, 2, 3, 0, 0, 0}, Check: []int{0, 1, 1, 1, 2, 3, 4}}
+)
+
+func request_EchoService_Echo_2(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq SimpleMessage
+ var metadata runtime.ServerMetadata
+ spec := internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec
+
+ var (
+ val string
+ ok bool
+ err error
+ _ = err
+ )
+
+ val, ok = pathParams["id"]
+ if !ok {
+ runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
+ }
+
+ protoReq.Id, err = runtime.String(val)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
+ }
+
+ val, ok = pathParams["num"]
+ if !ok {
+ runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "num")
+ }
+
+ protoReq.Num, err = runtime.Int64(val)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "num", err)
+ }
+
+ val, ok = pathParams["lang"]
+ if !ok {
+ runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "lang")
+ }
+
+ if protoReq.Code == nil {
+ protoReq.Code = &SimpleMessage_Lang{}
+ } else if _, ok := protoReq.Code.(*SimpleMessage_Lang); !ok {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "expect type: *SimpleMessage_Lang, but: %t\n", protoReq.Code)
+ }
+ protoReq.Code.(*SimpleMessage_Lang).Lang, err = runtime.String(val)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "lang", err)
+ }
+
+ if err := req.ParseForm(); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+ if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_Echo_2); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+
+ // Only hook up for non-stream call for now.
+
+ runtime.RequestParsed(ctx, spec, "EchoService", "Echo", &protoReq, &metadata)
+ ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
+ msg, err := client.Echo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+ // if err != nil {
+ // grpclog.Errorf("client.%s returns error: %v", "Echo", err)
+ // }
+ runtime.RequestHandled(ctx, spec, "EchoService", "Echo", msg, &metadata, err)
+ return msg, metadata, err
+
+}
+
+func local_request_EchoService_Echo_2(ctx context.Context, marshaler runtime.Marshaler, server EchoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq SimpleMessage
+ var metadata runtime.ServerMetadata
+
+ var (
+ val string
+ ok bool
+ err error
+ _ = err
+ )
+
+ val, ok = pathParams["id"]
+ if !ok {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
+ }
+
+ protoReq.Id, err = runtime.String(val)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
+ }
+
+ val, ok = pathParams["num"]
+ if !ok {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "num")
+ }
+
+ protoReq.Num, err = runtime.Int64(val)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "num", err)
+ }
+
+ val, ok = pathParams["lang"]
+ if !ok {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "lang")
+ }
+
+ if protoReq.Code == nil {
+ protoReq.Code = &SimpleMessage_Lang{}
+ } else if _, ok := protoReq.Code.(*SimpleMessage_Lang); !ok {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "expect type: *SimpleMessage_Lang, but: %t\n", protoReq.Code)
+ }
+ protoReq.Code.(*SimpleMessage_Lang).Lang, err = runtime.String(val)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "lang", err)
+ }
+
+ if err := req.ParseForm(); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+ if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_Echo_2); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+
+ msg, err := server.Echo(ctx, &protoReq)
+ return msg, metadata, err
+
+}
+
+var (
+ filter_EchoService_Echo_3 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0, "line_num": 1, "status": 2, "note": 3}, Base: []int{1, 1, 2, 1, 3, 0, 0, 0}, Check: []int{0, 1, 1, 1, 4, 2, 3, 5}}
+)
+
+func request_EchoService_Echo_3(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq SimpleMessage
+ var metadata runtime.ServerMetadata
+ spec := internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec
+
+ var (
+ val string
+ ok bool
+ err error
+ _ = err
+ )
+
+ val, ok = pathParams["id"]
+ if !ok {
+ runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
+ }
+
+ protoReq.Id, err = runtime.String(val)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
+ }
+
+ val, ok = pathParams["line_num"]
+ if !ok {
+ runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "line_num")
+ }
+
+ if protoReq.Code == nil {
+ protoReq.Code = &SimpleMessage_LineNum{}
+ } else if _, ok := protoReq.Code.(*SimpleMessage_LineNum); !ok {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "expect type: *SimpleMessage_LineNum, but: %t\n", protoReq.Code)
+ }
+ protoReq.Code.(*SimpleMessage_LineNum).LineNum, err = runtime.Int64(val)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "line_num", err)
+ }
+
+ val, ok = pathParams["status.note"]
+ if !ok {
+ runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "status.note")
+ }
+
+ err = runtime.PopulateFieldFromPath(&protoReq, "status.note", val)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "status.note", err)
+ }
+
+ if err := req.ParseForm(); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+ if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_Echo_3); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+
+ // Only hook up for non-stream call for now.
+
+ runtime.RequestParsed(ctx, spec, "EchoService", "Echo", &protoReq, &metadata)
+ ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
+ msg, err := client.Echo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+ // if err != nil {
+ // grpclog.Errorf("client.%s returns error: %v", "Echo", err)
+ // }
+ runtime.RequestHandled(ctx, spec, "EchoService", "Echo", msg, &metadata, err)
+ return msg, metadata, err
+
+}
+
+func local_request_EchoService_Echo_3(ctx context.Context, marshaler runtime.Marshaler, server EchoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq SimpleMessage
+ var metadata runtime.ServerMetadata
+
+ var (
+ val string
+ ok bool
+ err error
+ _ = err
+ )
+
+ val, ok = pathParams["id"]
+ if !ok {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
+ }
+
+ protoReq.Id, err = runtime.String(val)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
+ }
+
+ val, ok = pathParams["line_num"]
+ if !ok {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "line_num")
+ }
+
+ if protoReq.Code == nil {
+ protoReq.Code = &SimpleMessage_LineNum{}
+ } else if _, ok := protoReq.Code.(*SimpleMessage_LineNum); !ok {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "expect type: *SimpleMessage_LineNum, but: %t\n", protoReq.Code)
+ }
+ protoReq.Code.(*SimpleMessage_LineNum).LineNum, err = runtime.Int64(val)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "line_num", err)
+ }
+
+ val, ok = pathParams["status.note"]
+ if !ok {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "status.note")
+ }
+
+ err = runtime.PopulateFieldFromPath(&protoReq, "status.note", val)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "status.note", err)
+ }
+
+ if err := req.ParseForm(); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+ if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_Echo_3); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+
+ msg, err := server.Echo(ctx, &protoReq)
+ return msg, metadata, err
+
+}
+
+var (
+ filter_EchoService_Echo_4 = &utilities.DoubleArray{Encoding: map[string]int{"no": 0, "note": 1}, Base: []int{1, 1, 1, 0}, Check: []int{0, 1, 2, 3}}
+)
+
+func request_EchoService_Echo_4(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq SimpleMessage
+ var metadata runtime.ServerMetadata
+ spec := internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec
+
+ var (
+ val string
+ ok bool
+ err error
+ _ = err
+ )
+
+ val, ok = pathParams["no.note"]
+ if !ok {
+ runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "no.note")
+ }
+
+ err = runtime.PopulateFieldFromPath(&protoReq, "no.note", val)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "no.note", err)
+ }
+
+ if err := req.ParseForm(); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+ if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_Echo_4); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+
+ // Only hook up for non-stream call for now.
+
+ runtime.RequestParsed(ctx, spec, "EchoService", "Echo", &protoReq, &metadata)
+ ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
+ msg, err := client.Echo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+ // if err != nil {
+ // grpclog.Errorf("client.%s returns error: %v", "Echo", err)
+ // }
+ runtime.RequestHandled(ctx, spec, "EchoService", "Echo", msg, &metadata, err)
+ return msg, metadata, err
+
+}
+
+func local_request_EchoService_Echo_4(ctx context.Context, marshaler runtime.Marshaler, server EchoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq SimpleMessage
+ var metadata runtime.ServerMetadata
+
+ var (
+ val string
+ ok bool
+ err error
+ _ = err
+ )
+
+ val, ok = pathParams["no.note"]
+ if !ok {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "no.note")
+ }
+
+ err = runtime.PopulateFieldFromPath(&protoReq, "no.note", val)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "no.note", err)
+ }
+
+ if err := req.ParseForm(); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+ if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_Echo_4); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+
+ msg, err := server.Echo(ctx, &protoReq)
+ return msg, metadata, err
+
+}
+
+func request_EchoService_EchoBody_0(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq SimpleMessage
+ var metadata runtime.ServerMetadata
+ spec := internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec
+
+ newReader, berr := utilities.IOReaderFactory(req.Body)
+ if berr != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+ }
+ if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+ runtime.RequestHandled(ctx, spec, "EchoService", "EchoBody", nil, &metadata, err)
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+
+ // Only hook up for non-stream call for now.
+
+ runtime.RequestParsed(ctx, spec, "EchoService", "EchoBody", &protoReq, &metadata)
+ ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
+ msg, err := client.EchoBody(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+ // if err != nil {
+ // grpclog.Errorf("client.%s returns error: %v", "EchoBody", err)
+ // }
+ runtime.RequestHandled(ctx, spec, "EchoService", "EchoBody", msg, &metadata, err)
+ return msg, metadata, err
+
+}
+
+func local_request_EchoService_EchoBody_0(ctx context.Context, marshaler runtime.Marshaler, server EchoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq SimpleMessage
+ var metadata runtime.ServerMetadata
+
+ newReader, berr := utilities.IOReaderFactory(req.Body)
+ if berr != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+ }
+ if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+
+ msg, err := server.EchoBody(ctx, &protoReq)
+ return msg, metadata, err
+
+}
+
+var (
+ filter_EchoService_EchoDelete_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
+)
+
+func request_EchoService_EchoDelete_0(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq SimpleMessage
+ var metadata runtime.ServerMetadata
+ spec := internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec
+
+ if err := req.ParseForm(); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+ if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_EchoDelete_0); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+
+ // Only hook up for non-stream call for now.
+
+ runtime.RequestParsed(ctx, spec, "EchoService", "EchoDelete", &protoReq, &metadata)
+ ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
+ msg, err := client.EchoDelete(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+ // if err != nil {
+ // grpclog.Errorf("client.%s returns error: %v", "EchoDelete", err)
+ // }
+ runtime.RequestHandled(ctx, spec, "EchoService", "EchoDelete", msg, &metadata, err)
+ return msg, metadata, err
+
+}
+
+func local_request_EchoService_EchoDelete_0(ctx context.Context, marshaler runtime.Marshaler, server EchoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq SimpleMessage
+ var metadata runtime.ServerMetadata
+
+ if err := req.ParseForm(); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+ if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_EchoDelete_0); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+
+ msg, err := server.EchoDelete(ctx, &protoReq)
+ return msg, metadata, err
+
+}
+
+var (
+ filter_EchoService_EchoPatch_0 = &utilities.DoubleArray{Encoding: map[string]int{"body": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
+)
+
+func request_EchoService_EchoPatch_0(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq DynamicMessageUpdate
+ var metadata runtime.ServerMetadata
+ spec := internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec
+
+ newReader, berr := utilities.IOReaderFactory(req.Body)
+ if berr != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+ }
+ if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Body); err != nil && err != io.EOF {
+ runtime.RequestHandled(ctx, spec, "EchoService", "EchoPatch", nil, &metadata, err)
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+ if protoReq.UpdateMask == nil || len(protoReq.UpdateMask.GetPaths()) == 0 {
+ if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), protoReq.Body); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ } else {
+ protoReq.UpdateMask = fieldMask
+ }
+ }
+
+ if err := req.ParseForm(); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+ if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_EchoPatch_0); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+
+ // Only hook up for non-stream call for now.
+
+ runtime.RequestParsed(ctx, spec, "EchoService", "EchoPatch", &protoReq, &metadata)
+ ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
+ msg, err := client.EchoPatch(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+ // if err != nil {
+ // grpclog.Errorf("client.%s returns error: %v", "EchoPatch", err)
+ // }
+ runtime.RequestHandled(ctx, spec, "EchoService", "EchoPatch", msg, &metadata, err)
+ return msg, metadata, err
+
+}
+
+func local_request_EchoService_EchoPatch_0(ctx context.Context, marshaler runtime.Marshaler, server EchoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq DynamicMessageUpdate
+ var metadata runtime.ServerMetadata
+
+ newReader, berr := utilities.IOReaderFactory(req.Body)
+ if berr != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+ }
+ if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Body); err != nil && err != io.EOF {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+ if protoReq.UpdateMask == nil || len(protoReq.UpdateMask.GetPaths()) == 0 {
+ if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), protoReq.Body); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ } else {
+ protoReq.UpdateMask = fieldMask
+ }
+ }
+
+ if err := req.ParseForm(); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+ if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_EchoPatch_0); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+
+ msg, err := server.EchoPatch(ctx, &protoReq)
+ return msg, metadata, err
+
+}
+
+func request_EchoService_EchoValidationRule_0(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq ValidationRuleTestRequest
+ var metadata runtime.ServerMetadata
+ spec := internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec
+
+ newReader, berr := utilities.IOReaderFactory(req.Body)
+ if berr != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+ }
+ if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+ runtime.RequestHandled(ctx, spec, "EchoService", "EchoValidationRule", nil, &metadata, err)
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+
+ // Only hook up for non-stream call for now.
+
+ // Validate
+ // ValidationRuleTestRequest
+ if err := Validate__grpc_gateway_examples_internal_proto_examplepb_ValidationRuleTestRequest(&protoReq); err != nil {
+ runtime.RequestHandled(ctx, spec, "EchoService", "EchoValidationRule", nil, &metadata, err)
+ return nil, metadata, err
+ }
+
+ runtime.RequestParsed(ctx, spec, "EchoService", "EchoValidationRule", &protoReq, &metadata)
+ ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
+ msg, err := client.EchoValidationRule(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+ // if err != nil {
+ // grpclog.Errorf("client.%s returns error: %v", "EchoValidationRule", err)
+ // }
+ runtime.RequestHandled(ctx, spec, "EchoService", "EchoValidationRule", msg, &metadata, err)
+ return msg, metadata, err
+
+}
+
+func local_request_EchoService_EchoValidationRule_0(ctx context.Context, marshaler runtime.Marshaler, server EchoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq ValidationRuleTestRequest
+ var metadata runtime.ServerMetadata
+
+ newReader, berr := utilities.IOReaderFactory(req.Body)
+ if berr != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+ }
+ if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+
+ msg, err := server.EchoValidationRule(ctx, &protoReq)
+ return msg, metadata, err
+
+}
+
+// RegisterEchoServiceHandlerServer registers the http handlers for service EchoService to "mux".
+// UnaryRPC :call EchoServiceServer directly.
+// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
+// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterEchoServiceHandlerFromEndpoint instead.
+func RegisterEchoServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server EchoServiceServer) error {
+
+ mux.Handle("POST", pattern_EchoService_Echo_0, vexpb.ServiceId_CUSTOM_JANUS_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ var stream runtime.ServerTransportStream
+ ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ var err error
+ ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/Echo", runtime.WithHTTPPathPattern("/v1/example/echo/{id}"))
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := local_request_EchoService_Echo_0(ctx, inboundMarshaler, server, req, pathParams)
+ md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_EchoService_Echo_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
+ mux.Handle("GET", pattern_EchoService_Echo_1, vexpb.ServiceId_CUSTOM_JANUS_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ var stream runtime.ServerTransportStream
+ ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ var err error
+ ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/Echo", runtime.WithHTTPPathPattern("/v1/example/echo/{id}/{num}"))
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := local_request_EchoService_Echo_1(ctx, inboundMarshaler, server, req, pathParams)
+ md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_EchoService_Echo_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
+ mux.Handle("GET", pattern_EchoService_Echo_2, vexpb.ServiceId_CUSTOM_JANUS_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ var stream runtime.ServerTransportStream
+ ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ var err error
+ ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/Echo", runtime.WithHTTPPathPattern("/v1/example/echo/{id}/{num}/{lang}"))
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := local_request_EchoService_Echo_2(ctx, inboundMarshaler, server, req, pathParams)
+ md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_EchoService_Echo_2(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
+ mux.Handle("GET", pattern_EchoService_Echo_3, vexpb.ServiceId_CUSTOM_JANUS_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ var stream runtime.ServerTransportStream
+ ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ var err error
+ ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/Echo", runtime.WithHTTPPathPattern("/v1/example/echo1/{id}/{line_num}/{status.note}"))
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := local_request_EchoService_Echo_3(ctx, inboundMarshaler, server, req, pathParams)
+ md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_EchoService_Echo_3(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
+ mux.Handle("GET", pattern_EchoService_Echo_4, vexpb.ServiceId_CUSTOM_JANUS_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ var stream runtime.ServerTransportStream
+ ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ var err error
+ ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/Echo", runtime.WithHTTPPathPattern("/v1/example/echo2/{no.note}"))
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := local_request_EchoService_Echo_4(ctx, inboundMarshaler, server, req, pathParams)
+ md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_EchoService_Echo_4(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
+ mux.Handle("POST", pattern_EchoService_EchoBody_0, vexpb.ServiceId_CUSTOM_JANUS_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ var stream runtime.ServerTransportStream
+ ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ var err error
+ ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/EchoBody", runtime.WithHTTPPathPattern("/v1/example/echo_body"))
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := local_request_EchoService_EchoBody_0(ctx, inboundMarshaler, server, req, pathParams)
+ md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_EchoService_EchoBody_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
+ mux.Handle("DELETE", pattern_EchoService_EchoDelete_0, vexpb.ServiceId_CUSTOM_JANUS_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ var stream runtime.ServerTransportStream
+ ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ var err error
+ ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/EchoDelete", runtime.WithHTTPPathPattern("/v1/example/echo_delete"))
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := local_request_EchoService_EchoDelete_0(ctx, inboundMarshaler, server, req, pathParams)
+ md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_EchoService_EchoDelete_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
+ mux.Handle("PATCH", pattern_EchoService_EchoPatch_0, vexpb.ServiceId_CUSTOM_JANUS_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ var stream runtime.ServerTransportStream
+ ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ var err error
+ ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/EchoPatch", runtime.WithHTTPPathPattern("/v1/example/echo_patch"))
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := local_request_EchoService_EchoPatch_0(ctx, inboundMarshaler, server, req, pathParams)
+ md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_EchoService_EchoPatch_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
+ mux.Handle("POST", pattern_EchoService_EchoValidationRule_0, vexpb.ServiceId_CUSTOM_JANUS_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ var stream runtime.ServerTransportStream
+ ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ var err error
+ ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/EchoValidationRule", runtime.WithHTTPPathPattern("/v1/example/echo:validationRules"))
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := local_request_EchoService_EchoValidationRule_0(ctx, inboundMarshaler, server, req, pathParams)
+ md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_EchoService_EchoValidationRule_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
+ return nil
+}
+
+// Register itself to runtime.
+func init() {
+ var s *runtime.Service
+ var spec *skypb.ServiceSpec
+
+ _ = s
+ _ = spec
+
+ spec = internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec
+ s = &runtime.Service{
+ Spec: *spec,
+ Name: "EchoService",
+ Register: RegisterEchoServiceHandlerFromEndpoint,
+ Enable: EnableEchoService_Service,
+ Disable: DisableEchoService_Service,
+ }
+
+ runtime.AddService(s, Enable_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_ServiceGroup, Disable_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_ServiceGroup)
+
+}
+
+// RegisterEchoServiceHandlerFromEndpoint is same as RegisterEchoServiceHandler but
+// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
+func RegisterEchoServiceHandlerFromEndpoint(mux *runtime.ServeMux) (err error) {
+ // conn, err := grpc.Dial(endpoint, opts...)
+ // if err != nil {
+ // return err
+ // }
+ // defer func() {
+ // if err != nil {
+ // if cerr := conn.Close(); cerr != nil {
+ // grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
+ // }
+ // return
+ // }
+ // go func() {
+ // <-ctx.Done()
+ // if cerr := conn.Close(); cerr != nil {
+ // grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
+ // }
+ // }()
+ // }()
+
+ // return RegisterEchoServiceHandler(ctx, mux, conn)
+ return RegisterEchoServiceHandler(nil, mux, nil)
+}
+
+// RegisterEchoServiceHandler registers the http handlers for service EchoService to "mux".
+// The handlers forward requests to the grpc endpoint over "conn".
+func RegisterEchoServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
+ return RegisterEchoServiceHandlerClient(ctx, mux, NewEchoServiceClient(conn))
+}
+
+// RegisterEchoServiceHandlerClient registers the http handlers for service EchoService
+// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "EchoServiceClient".
+// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "EchoServiceClient"
+// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
+// "EchoServiceClient" to call the correct interceptors.
+func RegisterEchoServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client EchoServiceClient) error {
+ spec := internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec
+
+ runtime.AddMethod(spec, "EchoService", "Echo", "/v1/example/echo/{id}", "POST", true, false, false, "UNSPECIFIED", "JANUS_GATEWAY", "JANUS_AUTH_TOKEN", "")
+ mux.Handle("POST", pattern_EchoService_Echo_0, vexpb.ServiceId_CUSTOM_JANUS_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ // TODO(mojz): review all locking/unlocking logic.
+ // internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock.RLock()
+ // defer internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock.RUnlock()
+ client := internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_client
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ if client == nil {
+ err := status.Error(codes.Internal, "service disabled")
+ runtime.HTTPError(inctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec, "EchoService", "Echo", w, req)
+ if err != nil {
+ grpclog.Errorf("runtime.RequestAccepted returns error: %v", err)
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ // inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ // var err error
+ ctx, err = runtime.AnnotateContext(ctx, mux, req, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/Echo", runtime.WithHTTPPathPattern("/v1/example/echo/{id}"))
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := request_EchoService_Echo_0(ctx, inboundMarshaler, client, req, pathParams)
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_EchoService_Echo_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
+ runtime.AddMethod(spec, "EchoService", "Echo", "/v1/example/echo/{id}/{num}", "GET", true, false, false, "UNSPECIFIED", "JANUS_GATEWAY", "JANUS_AUTH_TOKEN", "")
+ mux.Handle("GET", pattern_EchoService_Echo_1, vexpb.ServiceId_CUSTOM_JANUS_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ // TODO(mojz): review all locking/unlocking logic.
+ // internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock.RLock()
+ // defer internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock.RUnlock()
+ client := internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_client
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ if client == nil {
+ err := status.Error(codes.Internal, "service disabled")
+ runtime.HTTPError(inctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec, "EchoService", "Echo", w, req)
+ if err != nil {
+ grpclog.Errorf("runtime.RequestAccepted returns error: %v", err)
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ // inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ // var err error
+ ctx, err = runtime.AnnotateContext(ctx, mux, req, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/Echo", runtime.WithHTTPPathPattern("/v1/example/echo/{id}/{num}"))
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := request_EchoService_Echo_1(ctx, inboundMarshaler, client, req, pathParams)
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_EchoService_Echo_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
+ runtime.AddMethod(spec, "EchoService", "Echo", "/v1/example/echo/{id}/{num}/{lang}", "GET", true, false, false, "UNSPECIFIED", "JANUS_GATEWAY", "JANUS_AUTH_TOKEN", "")
+ mux.Handle("GET", pattern_EchoService_Echo_2, vexpb.ServiceId_CUSTOM_JANUS_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ // TODO(mojz): review all locking/unlocking logic.
+ // internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock.RLock()
+ // defer internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock.RUnlock()
+ client := internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_client
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ if client == nil {
+ err := status.Error(codes.Internal, "service disabled")
+ runtime.HTTPError(inctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec, "EchoService", "Echo", w, req)
+ if err != nil {
+ grpclog.Errorf("runtime.RequestAccepted returns error: %v", err)
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ // inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ // var err error
+ ctx, err = runtime.AnnotateContext(ctx, mux, req, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/Echo", runtime.WithHTTPPathPattern("/v1/example/echo/{id}/{num}/{lang}"))
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := request_EchoService_Echo_2(ctx, inboundMarshaler, client, req, pathParams)
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_EchoService_Echo_2(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
+ runtime.AddMethod(spec, "EchoService", "Echo", "/v1/example/echo1/{id}/{line_num}/{status.note}", "GET", true, false, false, "UNSPECIFIED", "JANUS_GATEWAY", "JANUS_AUTH_TOKEN", "")
+ mux.Handle("GET", pattern_EchoService_Echo_3, vexpb.ServiceId_CUSTOM_JANUS_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ // TODO(mojz): review all locking/unlocking logic.
+ // internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock.RLock()
+ // defer internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock.RUnlock()
+ client := internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_client
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ if client == nil {
+ err := status.Error(codes.Internal, "service disabled")
+ runtime.HTTPError(inctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec, "EchoService", "Echo", w, req)
+ if err != nil {
+ grpclog.Errorf("runtime.RequestAccepted returns error: %v", err)
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ // inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ // var err error
+ ctx, err = runtime.AnnotateContext(ctx, mux, req, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/Echo", runtime.WithHTTPPathPattern("/v1/example/echo1/{id}/{line_num}/{status.note}"))
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := request_EchoService_Echo_3(ctx, inboundMarshaler, client, req, pathParams)
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_EchoService_Echo_3(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
+ runtime.AddMethod(spec, "EchoService", "Echo", "/v1/example/echo2/{no.note}", "GET", true, false, false, "UNSPECIFIED", "JANUS_GATEWAY", "JANUS_AUTH_TOKEN", "")
+ mux.Handle("GET", pattern_EchoService_Echo_4, vexpb.ServiceId_CUSTOM_JANUS_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ // TODO(mojz): review all locking/unlocking logic.
+ // internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock.RLock()
+ // defer internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock.RUnlock()
+ client := internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_client
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ if client == nil {
+ err := status.Error(codes.Internal, "service disabled")
+ runtime.HTTPError(inctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec, "EchoService", "Echo", w, req)
+ if err != nil {
+ grpclog.Errorf("runtime.RequestAccepted returns error: %v", err)
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ // inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ // var err error
+ ctx, err = runtime.AnnotateContext(ctx, mux, req, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/Echo", runtime.WithHTTPPathPattern("/v1/example/echo2/{no.note}"))
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := request_EchoService_Echo_4(ctx, inboundMarshaler, client, req, pathParams)
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_EchoService_Echo_4(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
+ runtime.AddMethod(spec, "EchoService", "EchoBody", "/v1/example/echo_body", "POST", true, false, false, "UNSPECIFIED", "JANUS_GATEWAY", "JANUS_AUTH_TOKEN", "")
+ mux.Handle("POST", pattern_EchoService_EchoBody_0, vexpb.ServiceId_CUSTOM_JANUS_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ // TODO(mojz): review all locking/unlocking logic.
+ // internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock.RLock()
+ // defer internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock.RUnlock()
+ client := internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_client
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ if client == nil {
+ err := status.Error(codes.Internal, "service disabled")
+ runtime.HTTPError(inctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec, "EchoService", "EchoBody", w, req)
+ if err != nil {
+ grpclog.Errorf("runtime.RequestAccepted returns error: %v", err)
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ // inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ // var err error
+ ctx, err = runtime.AnnotateContext(ctx, mux, req, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/EchoBody", runtime.WithHTTPPathPattern("/v1/example/echo_body"))
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := request_EchoService_EchoBody_0(ctx, inboundMarshaler, client, req, pathParams)
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_EchoService_EchoBody_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
+ runtime.AddMethod(spec, "EchoService", "EchoDelete", "/v1/example/echo_delete", "DELETE", true, false, false, "UNSPECIFIED", "JANUS_GATEWAY", "JANUS_AUTH_TOKEN", "")
+ mux.Handle("DELETE", pattern_EchoService_EchoDelete_0, vexpb.ServiceId_CUSTOM_JANUS_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ // TODO(mojz): review all locking/unlocking logic.
+ // internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock.RLock()
+ // defer internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock.RUnlock()
+ client := internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_client
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ if client == nil {
+ err := status.Error(codes.Internal, "service disabled")
+ runtime.HTTPError(inctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec, "EchoService", "EchoDelete", w, req)
+ if err != nil {
+ grpclog.Errorf("runtime.RequestAccepted returns error: %v", err)
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ // inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ // var err error
+ ctx, err = runtime.AnnotateContext(ctx, mux, req, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/EchoDelete", runtime.WithHTTPPathPattern("/v1/example/echo_delete"))
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := request_EchoService_EchoDelete_0(ctx, inboundMarshaler, client, req, pathParams)
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_EchoService_EchoDelete_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
+ runtime.AddMethod(spec, "EchoService", "EchoPatch", "/v1/example/echo_patch", "PATCH", true, false, false, "UNSPECIFIED", "JANUS_GATEWAY", "JANUS_AUTH_TOKEN", "")
+ mux.Handle("PATCH", pattern_EchoService_EchoPatch_0, vexpb.ServiceId_CUSTOM_JANUS_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ // TODO(mojz): review all locking/unlocking logic.
+ // internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock.RLock()
+ // defer internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock.RUnlock()
+ client := internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_client
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ if client == nil {
+ err := status.Error(codes.Internal, "service disabled")
+ runtime.HTTPError(inctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec, "EchoService", "EchoPatch", w, req)
+ if err != nil {
+ grpclog.Errorf("runtime.RequestAccepted returns error: %v", err)
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ // inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ // var err error
+ ctx, err = runtime.AnnotateContext(ctx, mux, req, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/EchoPatch", runtime.WithHTTPPathPattern("/v1/example/echo_patch"))
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := request_EchoService_EchoPatch_0(ctx, inboundMarshaler, client, req, pathParams)
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_EchoService_EchoPatch_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
+ runtime.AddMethod(spec, "EchoService", "EchoValidationRule", "/v1/example/echo:validationRules", "POST", true, false, false, "UNSPECIFIED", "JANUS_GATEWAY", "JANUS_AUTH_TOKEN", "")
+ mux.Handle("POST", pattern_EchoService_EchoValidationRule_0, vexpb.ServiceId_CUSTOM_JANUS_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ // TODO(mojz): review all locking/unlocking logic.
+ // internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock.RLock()
+ // defer internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock.RUnlock()
+ client := internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_client
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ if client == nil {
+ err := status.Error(codes.Internal, "service disabled")
+ runtime.HTTPError(inctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec, "EchoService", "EchoValidationRule", w, req)
+ if err != nil {
+ grpclog.Errorf("runtime.RequestAccepted returns error: %v", err)
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ // inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ // var err error
+ ctx, err = runtime.AnnotateContext(ctx, mux, req, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/EchoValidationRule", runtime.WithHTTPPathPattern("/v1/example/echo:validationRules"))
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := request_EchoService_EchoValidationRule_0(ctx, inboundMarshaler, client, req, pathParams)
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_EchoService_EchoValidationRule_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
+ return nil
+}
+
+func Disable_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_ServiceGroup() {
+ // internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock.Lock()
+ // defer internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock.Unlock()
+ if internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_skycli != nil {
+ spec := internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec
+ sg := runtime.GetServiceGroup(spec)
+ for _, svc := range sg.Services {
+ svc.Disable()
+ }
+
+ internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_client = nil
+ internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_skycli.Shutdown()
+ internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_skycli = nil
+ }
+}
+
+func Enable_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_ServiceGroup() {
+ // internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock.Lock()
+ // defer internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock.Unlock()
+
+ internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_skycli = client.NewServiceCli(runtime.CallerServiceId)
+
+ // Resolve service
+ spec := internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec
+
+ internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_skycli.Resolve(spec)
+
+ internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_skycli.Start(func(spec *skypb.ServiceSpec, conn *grpc.ClientConn) {
+ sg := runtime.GetServiceGroup(spec)
+ for _, svc := range sg.Services {
+ svc.Enable(spec, conn)
+ }
+ })
+}
+
+func EnableEchoService_Service(spec *skypb.ServiceSpec, conn *grpc.ClientConn) {
+ internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_client = NewEchoServiceClient(conn)
+}
+
+func DisableEchoService_Service() {
+ internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_client = nil
+}
+
+var (
+ pattern_EchoService_Echo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "example", "echo", "id"}, ""))
+
+ pattern_EchoService_Echo_1 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4}, []string{"v1", "example", "echo", "id", "num"}, ""))
+
+ pattern_EchoService_Echo_2 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"v1", "example", "echo", "id", "num", "lang"}, ""))
+
+ pattern_EchoService_Echo_3 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"v1", "example", "echo1", "id", "line_num", "status.note"}, ""))
+
+ pattern_EchoService_Echo_4 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "example", "echo2", "no.note"}, ""))
+
+ pattern_EchoService_EchoBody_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "example", "echo_body"}, ""))
+
+ pattern_EchoService_EchoDelete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "example", "echo_delete"}, ""))
+
+ pattern_EchoService_EchoPatch_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "example", "echo_patch"}, ""))
+
+ pattern_EchoService_EchoValidationRule_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "example", "echo"}, "validationRules"))
+)
+
+var (
+ forward_EchoService_Echo_0 = runtime.ForwardResponseMessage
+
+ forward_EchoService_Echo_1 = runtime.ForwardResponseMessage
+
+ forward_EchoService_Echo_2 = runtime.ForwardResponseMessage
+
+ forward_EchoService_Echo_3 = runtime.ForwardResponseMessage
+
+ forward_EchoService_Echo_4 = runtime.ForwardResponseMessage
+
+ forward_EchoService_EchoBody_0 = runtime.ForwardResponseMessage
+
+ forward_EchoService_EchoDelete_0 = runtime.ForwardResponseMessage
+
+ forward_EchoService_EchoPatch_0 = runtime.ForwardResponseMessage
+
+ forward_EchoService_EchoValidationRule_0 = runtime.ForwardResponseMessage
+)
+
+var (
+ internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_spec = client.NewServiceSpec("default", vexpb.ServiceId_CUSTOM_JANUS_GATEWAY_TEST, "grpc")
+ internal_EchoService_CUSTOM_JANUS_GATEWAY_TEST_client EchoServiceClient
+
+ internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_skycli client.ServiceCli
+
+ internal_CUSTOM_JANUS_GATEWAY_TEST__default__grpc_lock = sync.RWMutex{}
+)
diff --git a/examples/internal/proto/examplepb/echo_service.proto b/examples/internal/proto/examplepb/echo_service.proto
new file mode 100644
index 0000000..0f18f38
--- /dev/null
+++ b/examples/internal/proto/examplepb/echo_service.proto
@@ -0,0 +1,149 @@
+syntax = "proto3";
+option go_package = "github.com/binchencoder/janus-gateway/examples/internal/proto/examplepb;examplepb";
+
+// Echo Service
+//
+// Echo Service API consists of a single service which returns
+// a message.
+package grpc.gateway.examples.internal.proto.examplepb;
+
+// import "google/api/annotations.proto";
+import "httpoptions/annotations.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/struct.proto";
+
+// Embedded represents a message embedded in SimpleMessage.
+message Embedded {
+ oneof mark {
+ int64 progress = 1;
+ string note = 2;
+ }
+}
+
+// SimpleMessage represents a simple message sent to the Echo service.
+message SimpleMessage {
+ // Id represents the message identifier.
+ string id = 1;
+ int64 num = 2;
+ oneof code {
+ int64 line_num = 3;
+ string lang = 4;
+ }
+ Embedded status = 5;
+ oneof ext {
+ int64 en = 6;
+ Embedded no = 7;
+ }
+}
+
+// ValidationRuleTestRequest represents a message for validation http rules integration test.
+message ValidationRuleTestRequest {
+ // Id represents the message identifier.
+ string id = 1
+ [
+ (janus.api.rules) = {
+ rules: {
+ type: STRING,
+ operator: NON_NIL,
+ },
+ rules: {
+ type: STRING,
+ function: TRIM,
+ operator: LEN_GT,
+ value: "2",
+ },
+ rules: {
+ type: STRING,
+ function: TRIM,
+ operator: LEN_LT,
+ value: "61",
+ }
+ }
+ ];
+ int64 num = 2
+ [
+ (janus.api.rules) = {
+ rules: {
+ type: NUMBER,
+ operator: GT,
+ value: "0",
+ }
+ }
+ ];
+}
+
+// ValidationRuleTestResponse represents a validation http rules integration test response.
+message ValidationRuleTestResponse {
+}
+
+// DynamicMessage represents a message which can have its structure
+// built dynamically using Struct and Values.
+message DynamicMessage {
+ google.protobuf.Struct struct_field = 1;
+ google.protobuf.Value value_field = 2;
+}
+
+message DynamicMessageUpdate {
+ DynamicMessage body = 1;
+ google.protobuf.FieldMask update_mask = 2;
+}
+
+// Echo service responds to incoming echo requests.
+service EchoService {
+ option (janus.api.service_spec) = {
+ service_id: CUSTOM_JANUS_GATEWAY_TEST
+ port_name : "grpc"
+ namespace : "default"
+ gen_controller: true
+ };
+
+ // Echo method receives a simple message and returns it.
+ //
+ // The message posted as the id parameter will also be
+ // returned.
+ rpc Echo(SimpleMessage) returns (SimpleMessage) {
+ option (janus.api.http) = {
+ post: "/v1/example/echo/{id}"
+ additional_bindings {
+ get: "/v1/example/echo/{id}/{num}"
+ }
+ additional_bindings {
+ get: "/v1/example/echo/{id}/{num}/{lang}"
+ }
+ additional_bindings {
+ get: "/v1/example/echo1/{id}/{line_num}/{status.note}"
+ }
+ additional_bindings {
+ get: "/v1/example/echo2/{no.note}"
+ }
+ };
+ }
+ // EchoBody method receives a simple message and returns it.
+ rpc EchoBody(SimpleMessage) returns (SimpleMessage) {
+ option (janus.api.http) = {
+ post: "/v1/example/echo_body"
+ body: "*"
+ };
+ }
+ // EchoDelete method receives a simple message and returns it.
+ rpc EchoDelete(SimpleMessage) returns (SimpleMessage) {
+ option (janus.api.http) = {
+ delete: "/v1/example/echo_delete"
+ };
+ }
+ // EchoPatch method receives a NonStandardUpdateRequest and returns it.
+ rpc EchoPatch(DynamicMessageUpdate) returns (DynamicMessageUpdate) {
+ option (janus.api.http) = {
+ patch: "/v1/example/echo_patch"
+ body: "body"
+ };
+ }
+
+ // EchoValidationRule method for validation http rules integration test.
+ rpc EchoValidationRule(ValidationRuleTestRequest) returns (ValidationRuleTestResponse) {
+ option (janus.api.http) = {
+ post: "/v1/example/echo:validationRules"
+ body: "*"
+ };
+ };
+}
diff --git a/examples/proto/echo_service.swagger.json b/examples/internal/proto/examplepb/echo_service.swagger.json
similarity index 61%
rename from examples/proto/echo_service.swagger.json
rename to examples/internal/proto/examplepb/echo_service.swagger.json
index 384818e..84fbd45 100755
--- a/examples/proto/echo_service.swagger.json
+++ b/examples/internal/proto/examplepb/echo_service.swagger.json
@@ -5,10 +5,6 @@
"description": "Echo Service API consists of a single service which returns\na message.",
"version": "version not set"
},
- "schemes": [
- "http",
- "https"
- ],
"consumes": [
"application/json"
],
@@ -20,12 +16,18 @@
"post": {
"summary": "Echo method receives a simple message and returns it.",
"description": "The message posted as the id parameter will also be\nreturned.",
- "operationId": "Echo",
+ "operationId": "EchoService_Echo",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
- "$ref": "#/definitions/protoSimpleMessage"
+ "$ref": "#/definitions/examplepbSimpleMessage"
+ }
+ },
+ "default": {
+ "description": "An unexpected error response.",
+ "schema": {
+ "$ref": "#/definitions/rpcStatus"
}
}
},
@@ -47,12 +49,18 @@
"get": {
"summary": "Echo method receives a simple message and returns it.",
"description": "The message posted as the id parameter will also be\nreturned.",
- "operationId": "Echo2",
+ "operationId": "EchoService_Echo2",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
- "$ref": "#/definitions/protoSimpleMessage"
+ "$ref": "#/definitions/examplepbSimpleMessage"
+ }
+ },
+ "default": {
+ "description": "An unexpected error response.",
+ "schema": {
+ "$ref": "#/definitions/rpcStatus"
}
}
},
@@ -72,7 +80,7 @@
"format": "int64"
},
{
- "name": "line_num",
+ "name": "lineNum",
"in": "query",
"required": false,
"type": "string",
@@ -127,12 +135,18 @@
"get": {
"summary": "Echo method receives a simple message and returns it.",
"description": "The message posted as the id parameter will also be\nreturned.",
- "operationId": "Echo3",
+ "operationId": "EchoService_Echo3",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
- "$ref": "#/definitions/protoSimpleMessage"
+ "$ref": "#/definitions/examplepbSimpleMessage"
+ }
+ },
+ "default": {
+ "description": "An unexpected error response.",
+ "schema": {
+ "$ref": "#/definitions/rpcStatus"
}
}
},
@@ -158,7 +172,7 @@
"type": "string"
},
{
- "name": "line_num",
+ "name": "lineNum",
"in": "query",
"required": false,
"type": "string",
@@ -203,16 +217,22 @@
]
}
},
- "/v1/example/echo1/{id}/{line_num}/{status.note}": {
+ "/v1/example/echo1/{id}/{lineNum}/{status.note}": {
"get": {
"summary": "Echo method receives a simple message and returns it.",
"description": "The message posted as the id parameter will also be\nreturned.",
- "operationId": "Echo4",
+ "operationId": "EchoService_Echo4",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
- "$ref": "#/definitions/protoSimpleMessage"
+ "$ref": "#/definitions/examplepbSimpleMessage"
+ }
+ },
+ "default": {
+ "description": "An unexpected error response.",
+ "schema": {
+ "$ref": "#/definitions/rpcStatus"
}
}
},
@@ -225,7 +245,7 @@
"type": "string"
},
{
- "name": "line_num",
+ "name": "lineNum",
"in": "path",
"required": true,
"type": "string",
@@ -281,12 +301,18 @@
"get": {
"summary": "Echo method receives a simple message and returns it.",
"description": "The message posted as the id parameter will also be\nreturned.",
- "operationId": "Echo5",
+ "operationId": "EchoService_Echo5",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
- "$ref": "#/definitions/protoSimpleMessage"
+ "$ref": "#/definitions/examplepbSimpleMessage"
+ }
+ },
+ "default": {
+ "description": "An unexpected error response.",
+ "schema": {
+ "$ref": "#/definitions/rpcStatus"
}
}
},
@@ -312,7 +338,7 @@
"format": "int64"
},
{
- "name": "line_num",
+ "name": "lineNum",
"in": "query",
"required": false,
"type": "string",
@@ -351,15 +377,54 @@
]
}
},
+ "/v1/example/echo:validationRules": {
+ "post": {
+ "summary": "EchoValidationRule method for validation http rules integration test.",
+ "operationId": "EchoService_EchoValidationRule",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/examplepbValidationRuleTestResponse"
+ }
+ },
+ "default": {
+ "description": "An unexpected error response.",
+ "schema": {
+ "$ref": "#/definitions/rpcStatus"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "body",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/examplepbValidationRuleTestRequest"
+ }
+ }
+ ],
+ "tags": [
+ "EchoService"
+ ]
+ }
+ },
"/v1/example/echo_body": {
"post": {
"summary": "EchoBody method receives a simple message and returns it.",
- "operationId": "EchoBody",
+ "operationId": "EchoService_EchoBody",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
- "$ref": "#/definitions/protoSimpleMessage"
+ "$ref": "#/definitions/examplepbSimpleMessage"
+ }
+ },
+ "default": {
+ "description": "An unexpected error response.",
+ "schema": {
+ "$ref": "#/definitions/rpcStatus"
}
}
},
@@ -369,7 +434,7 @@
"in": "body",
"required": true,
"schema": {
- "$ref": "#/definitions/protoSimpleMessage"
+ "$ref": "#/definitions/examplepbSimpleMessage"
}
}
],
@@ -381,12 +446,18 @@
"/v1/example/echo_delete": {
"delete": {
"summary": "EchoDelete method receives a simple message and returns it.",
- "operationId": "EchoDelete",
+ "operationId": "EchoService_EchoDelete",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
- "$ref": "#/definitions/protoSimpleMessage"
+ "$ref": "#/definitions/examplepbSimpleMessage"
+ }
+ },
+ "default": {
+ "description": "An unexpected error response.",
+ "schema": {
+ "$ref": "#/definitions/rpcStatus"
}
}
},
@@ -406,7 +477,7 @@
"format": "int64"
},
{
- "name": "line_num",
+ "name": "lineNum",
"in": "query",
"required": false,
"type": "string",
@@ -456,10 +527,79 @@
"EchoService"
]
}
+ },
+ "/v1/example/echo_patch": {
+ "patch": {
+ "summary": "EchoPatch method receives a NonStandardUpdateRequest and returns it.",
+ "operationId": "EchoService_EchoPatch",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/examplepbDynamicMessageUpdate"
+ }
+ },
+ "default": {
+ "description": "An unexpected error response.",
+ "schema": {
+ "$ref": "#/definitions/rpcStatus"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "body",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/examplepbDynamicMessage"
+ }
+ },
+ {
+ "name": "updateMask",
+ "in": "query",
+ "required": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "collectionFormat": "multi"
+ }
+ ],
+ "tags": [
+ "EchoService"
+ ]
+ }
}
},
"definitions": {
- "protoEmbedded": {
+ "examplepbDynamicMessage": {
+ "type": "object",
+ "properties": {
+ "structField": {
+ "type": "object"
+ },
+ "valueField": {
+ "type": "object"
+ }
+ },
+ "description": "DynamicMessage represents a message which can have its structure\nbuilt dynamically using Struct and Values."
+ },
+ "examplepbDynamicMessageUpdate": {
+ "type": "object",
+ "properties": {
+ "body": {
+ "$ref": "#/definitions/examplepbDynamicMessage"
+ },
+ "updateMask": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "examplepbEmbedded": {
"type": "object",
"properties": {
"progress": {
@@ -472,7 +612,7 @@
},
"description": "Embedded represents a message embedded in SimpleMessage."
},
- "protoSimpleMessage": {
+ "examplepbSimpleMessage": {
"type": "object",
"properties": {
"id": {
@@ -483,7 +623,7 @@
"type": "string",
"format": "int64"
},
- "line_num": {
+ "lineNum": {
"type": "string",
"format": "int64"
},
@@ -491,17 +631,98 @@
"type": "string"
},
"status": {
- "$ref": "#/definitions/protoEmbedded"
+ "$ref": "#/definitions/examplepbEmbedded"
},
"en": {
"type": "string",
"format": "int64"
},
"no": {
- "$ref": "#/definitions/protoEmbedded"
+ "$ref": "#/definitions/examplepbEmbedded"
}
},
"description": "SimpleMessage represents a simple message sent to the Echo service."
+ },
+ "examplepbValidationRuleTestRequest": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "rules": [
+ {
+ "operator": 5,
+ "type": 2
+ },
+ {
+ "operator": 6,
+ "type": 2,
+ "value": "2",
+ "function": 1
+ },
+ {
+ "operator": 7,
+ "type": 2,
+ "value": "61",
+ "function": 1
+ }
+ ],
+ "description": "Id represents the message identifier."
+ },
+ "num": {
+ "type": "string",
+ "format": "int64",
+ "rules": [
+ {
+ "operator": 1,
+ "type": 1,
+ "value": "0"
+ }
+ ]
+ }
+ },
+ "description": "ValidationRuleTestRequest represents a message for validation http rules integration test."
+ },
+ "examplepbValidationRuleTestResponse": {
+ "type": "object",
+ "description": "ValidationRuleTestResponse represents a validation http rules integration test response."
+ },
+ "protobufAny": {
+ "type": "object",
+ "properties": {
+ "typeUrl": {
+ "type": "string"
+ },
+ "value": {
+ "type": "string",
+ "format": "byte"
+ }
+ }
+ },
+ "protobufNullValue": {
+ "type": "string",
+ "enum": [
+ "NULL_VALUE"
+ ],
+ "default": "NULL_VALUE",
+ "description": "`NullValue` is a singleton enumeration to represent the null value for the\n`Value` type union.\n\n The JSON representation for `NullValue` is JSON `null`.\n\n - NULL_VALUE: Null value."
+ },
+ "rpcStatus": {
+ "type": "object",
+ "properties": {
+ "code": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "message": {
+ "type": "string"
+ },
+ "details": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/protobufAny"
+ }
+ }
+ }
}
}
}
diff --git a/examples/internal/proto/examplepb/echo_service_grpc.pb.go b/examples/internal/proto/examplepb/echo_service_grpc.pb.go
new file mode 100755
index 0000000..0284d01
--- /dev/null
+++ b/examples/internal/proto/examplepb/echo_service_grpc.pb.go
@@ -0,0 +1,239 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+
+package examplepb
+
+import (
+ context "context"
+ grpc "google.golang.org/grpc"
+ codes "google.golang.org/grpc/codes"
+ status "google.golang.org/grpc/status"
+)
+
+// 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.SupportPackageIsVersion7
+
+// EchoServiceClient is the client API for EchoService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type EchoServiceClient interface {
+ Echo(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error)
+ EchoBody(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error)
+ EchoDelete(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error)
+ EchoPatch(ctx context.Context, in *DynamicMessageUpdate, opts ...grpc.CallOption) (*DynamicMessageUpdate, error)
+ EchoValidationRule(ctx context.Context, in *ValidationRuleTestRequest, opts ...grpc.CallOption) (*ValidationRuleTestResponse, error)
+}
+
+type echoServiceClient struct {
+ cc grpc.ClientConnInterface
+}
+
+func NewEchoServiceClient(cc grpc.ClientConnInterface) EchoServiceClient {
+ return &echoServiceClient{cc}
+}
+
+func (c *echoServiceClient) Echo(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error) {
+ out := new(SimpleMessage)
+ err := c.cc.Invoke(ctx, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/Echo", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *echoServiceClient) EchoBody(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error) {
+ out := new(SimpleMessage)
+ err := c.cc.Invoke(ctx, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/EchoBody", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *echoServiceClient) EchoDelete(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error) {
+ out := new(SimpleMessage)
+ err := c.cc.Invoke(ctx, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/EchoDelete", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *echoServiceClient) EchoPatch(ctx context.Context, in *DynamicMessageUpdate, opts ...grpc.CallOption) (*DynamicMessageUpdate, error) {
+ out := new(DynamicMessageUpdate)
+ err := c.cc.Invoke(ctx, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/EchoPatch", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *echoServiceClient) EchoValidationRule(ctx context.Context, in *ValidationRuleTestRequest, opts ...grpc.CallOption) (*ValidationRuleTestResponse, error) {
+ out := new(ValidationRuleTestResponse)
+ err := c.cc.Invoke(ctx, "/grpc.gateway.examples.internal.proto.examplepb.EchoService/EchoValidationRule", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+// EchoServiceServer is the server API for EchoService service.
+// All implementations should embed UnimplementedEchoServiceServer
+// for forward compatibility
+type EchoServiceServer interface {
+ Echo(context.Context, *SimpleMessage) (*SimpleMessage, error)
+ EchoBody(context.Context, *SimpleMessage) (*SimpleMessage, error)
+ EchoDelete(context.Context, *SimpleMessage) (*SimpleMessage, error)
+ EchoPatch(context.Context, *DynamicMessageUpdate) (*DynamicMessageUpdate, error)
+ EchoValidationRule(context.Context, *ValidationRuleTestRequest) (*ValidationRuleTestResponse, error)
+}
+
+// UnimplementedEchoServiceServer should be embedded to have forward compatible implementations.
+type UnimplementedEchoServiceServer struct {
+}
+
+func (UnimplementedEchoServiceServer) Echo(context.Context, *SimpleMessage) (*SimpleMessage, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method Echo not implemented")
+}
+func (UnimplementedEchoServiceServer) EchoBody(context.Context, *SimpleMessage) (*SimpleMessage, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method EchoBody not implemented")
+}
+func (UnimplementedEchoServiceServer) EchoDelete(context.Context, *SimpleMessage) (*SimpleMessage, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method EchoDelete not implemented")
+}
+func (UnimplementedEchoServiceServer) EchoPatch(context.Context, *DynamicMessageUpdate) (*DynamicMessageUpdate, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method EchoPatch not implemented")
+}
+func (UnimplementedEchoServiceServer) EchoValidationRule(context.Context, *ValidationRuleTestRequest) (*ValidationRuleTestResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method EchoValidationRule not implemented")
+}
+
+// UnsafeEchoServiceServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to EchoServiceServer will
+// result in compilation errors.
+type UnsafeEchoServiceServer interface {
+ mustEmbedUnimplementedEchoServiceServer()
+}
+
+func RegisterEchoServiceServer(s *grpc.Server, srv EchoServiceServer) {
+ s.RegisterService(&_EchoService_serviceDesc, srv)
+}
+
+func _EchoService_Echo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(SimpleMessage)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(EchoServiceServer).Echo(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/grpc.gateway.examples.internal.proto.examplepb.EchoService/Echo",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(EchoServiceServer).Echo(ctx, req.(*SimpleMessage))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _EchoService_EchoBody_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(SimpleMessage)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(EchoServiceServer).EchoBody(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/grpc.gateway.examples.internal.proto.examplepb.EchoService/EchoBody",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(EchoServiceServer).EchoBody(ctx, req.(*SimpleMessage))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _EchoService_EchoDelete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(SimpleMessage)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(EchoServiceServer).EchoDelete(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/grpc.gateway.examples.internal.proto.examplepb.EchoService/EchoDelete",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(EchoServiceServer).EchoDelete(ctx, req.(*SimpleMessage))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _EchoService_EchoPatch_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(DynamicMessageUpdate)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(EchoServiceServer).EchoPatch(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/grpc.gateway.examples.internal.proto.examplepb.EchoService/EchoPatch",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(EchoServiceServer).EchoPatch(ctx, req.(*DynamicMessageUpdate))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _EchoService_EchoValidationRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(ValidationRuleTestRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(EchoServiceServer).EchoValidationRule(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/grpc.gateway.examples.internal.proto.examplepb.EchoService/EchoValidationRule",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(EchoServiceServer).EchoValidationRule(ctx, req.(*ValidationRuleTestRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+var _EchoService_serviceDesc = grpc.ServiceDesc{
+ ServiceName: "grpc.gateway.examples.internal.proto.examplepb.EchoService",
+ HandlerType: (*EchoServiceServer)(nil),
+ Methods: []grpc.MethodDesc{
+ {
+ MethodName: "Echo",
+ Handler: _EchoService_Echo_Handler,
+ },
+ {
+ MethodName: "EchoBody",
+ Handler: _EchoService_EchoBody_Handler,
+ },
+ {
+ MethodName: "EchoDelete",
+ Handler: _EchoService_EchoDelete_Handler,
+ },
+ {
+ MethodName: "EchoPatch",
+ Handler: _EchoService_EchoPatch_Handler,
+ },
+ {
+ MethodName: "EchoValidationRule",
+ Handler: _EchoService_EchoValidationRule_Handler,
+ },
+ },
+ Streams: []grpc.StreamDesc{},
+ Metadata: "examples/internal/proto/examplepb/echo_service.proto",
+}
diff --git a/examples/internal/proto/examplepb/generated_input.proto b/examples/internal/proto/examplepb/generated_input.proto
new file mode 100644
index 0000000..ed6df0f
--- /dev/null
+++ b/examples/internal/proto/examplepb/generated_input.proto
@@ -0,0 +1,20 @@
+syntax = "proto3";
+option go_package = "github.com/binchencoder/janus-gateway/examples/internal/proto/examplepb";
+package grpc.gateway.examples.internal.proto.examplepb;
+
+import "google/api/annotations.proto";
+import "google/protobuf/empty.proto";
+import "examples/internal/proto/examplepb/echo_service.proto";
+
+// This file is run through a genrule.
+
+// Defines some more operations to be added to EchoService
+service GeneratedService {
+ rpc Create(SimpleMessage) returns (google.protobuf.Empty) {
+ option (google.api.http) = {
+ post: "/v1/example/a_bit_of_everything/generated_create"
+ body: "*"
+ };
+ }
+
+}
diff --git a/examples/internal/proto/examplepb/generated_input.swagger.json b/examples/internal/proto/examplepb/generated_input.swagger.json
new file mode 100644
index 0000000..65bc223
--- /dev/null
+++ b/examples/internal/proto/examplepb/generated_input.swagger.json
@@ -0,0 +1,347 @@
+{
+ "swagger": "2.0",
+ "info": {
+ "title": "examples/internal/proto/examplepb/generated_input.proto",
+ "version": "version not set"
+ },
+ "tags": [
+ {
+ "name": "GeneratedService"
+ }
+ ],
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "paths": {
+ "/v1/example/a_bit_of_everything/generated_create": {
+ "post": {
+ "operationId": "GeneratedService_Create",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "properties": {}
+ }
+ },
+ "default": {
+ "description": "An unexpected error response.",
+ "schema": {
+ "$ref": "#/definitions/rpcStatus"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "body",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/examplepbABitOfEverything"
+ }
+ }
+ ],
+ "tags": [
+ "GeneratedService"
+ ]
+ }
+ }
+ },
+ "definitions": {
+ "ABitOfEverythingNested": {
+ "type": "object",
+ "example": {
+ "ok": "TRUE"
+ },
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "name is nested field."
+ },
+ "amount": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "ok": {
+ "$ref": "#/definitions/NestedDeepEnum",
+ "description": "DeepEnum description."
+ }
+ },
+ "description": "Nested is nested type."
+ },
+ "MessagePathEnumNestedPathEnum": {
+ "type": "string",
+ "enum": [
+ "GHI",
+ "JKL"
+ ],
+ "default": "GHI"
+ },
+ "NestedDeepEnum": {
+ "type": "string",
+ "enum": [
+ "FALSE",
+ "TRUE"
+ ],
+ "default": "FALSE",
+ "description": "DeepEnum is one or zero.\n\n - FALSE: FALSE is false.\n - TRUE: TRUE is true."
+ },
+ "examplepbABitOfEverything": {
+ "type": "object",
+ "example": {
+ "int64_value": 12,
+ "double_value": 12.3
+ },
+ "properties": {
+ "singleNested": {
+ "$ref": "#/definitions/ABitOfEverythingNested"
+ },
+ "uuid": {
+ "type": "string",
+ "minLength": 1,
+ "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}"
+ },
+ "nested": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/ABitOfEverythingNested"
+ }
+ },
+ "floatValue": {
+ "type": "number",
+ "format": "float",
+ "default": "0.2",
+ "description": "Float value field",
+ "required": [
+ "floatValue"
+ ]
+ },
+ "doubleValue": {
+ "type": "number",
+ "format": "double"
+ },
+ "int64Value": {
+ "type": "string",
+ "format": "int64"
+ },
+ "uint64Value": {
+ "type": "string",
+ "format": "uint64"
+ },
+ "int32Value": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "fixed64Value": {
+ "type": "string",
+ "format": "uint64"
+ },
+ "fixed32Value": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "boolValue": {
+ "type": "boolean"
+ },
+ "stringValue": {
+ "type": "string"
+ },
+ "bytesValue": {
+ "type": "string",
+ "format": "byte"
+ },
+ "uint32Value": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "enumValue": {
+ "$ref": "#/definitions/examplepbNumericEnum"
+ },
+ "pathEnumValue": {
+ "$ref": "#/definitions/pathenumPathEnum"
+ },
+ "nestedPathEnumValue": {
+ "$ref": "#/definitions/MessagePathEnumNestedPathEnum"
+ },
+ "sfixed32Value": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "sfixed64Value": {
+ "type": "string",
+ "format": "int64"
+ },
+ "sint32Value": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "sint64Value": {
+ "type": "string",
+ "format": "int64"
+ },
+ "repeatedStringValue": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "oneofEmpty": {
+ "properties": {}
+ },
+ "oneofString": {
+ "type": "string"
+ },
+ "mapValue": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/definitions/examplepbNumericEnum"
+ }
+ },
+ "mappedStringValue": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "mappedNestedValue": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/definitions/ABitOfEverythingNested"
+ }
+ },
+ "nonConventionalNameValue": {
+ "type": "string"
+ },
+ "timestampValue": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "repeatedEnumValue": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/examplepbNumericEnum"
+ },
+ "title": "repeated enum value. it is comma-separated in query"
+ },
+ "repeatedEnumAnnotation": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/examplepbNumericEnum"
+ },
+ "description": "Repeated numeric enum description.",
+ "title": "Repeated numeric enum title"
+ },
+ "enumValueAnnotation": {
+ "$ref": "#/definitions/examplepbNumericEnum",
+ "description": "Numeric enum description.",
+ "title": "Numeric enum title"
+ },
+ "repeatedStringAnnotation": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "Repeated string description.",
+ "title": "Repeated string title"
+ },
+ "repeatedNestedAnnotation": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/ABitOfEverythingNested"
+ },
+ "description": "Repeated nested object description.",
+ "title": "Repeated nested object title"
+ },
+ "nestedAnnotation": {
+ "$ref": "#/definitions/ABitOfEverythingNested",
+ "description": "Nested object description.",
+ "title": "Nested object title"
+ },
+ "int64OverrideType": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "requiredStringViaFieldBehaviorAnnotation": {
+ "type": "string",
+ "title": "mark a field as required in Open API definition",
+ "required": [
+ "requiredStringViaFieldBehaviorAnnotation"
+ ]
+ },
+ "outputOnlyStringViaFieldBehaviorAnnotation": {
+ "type": "string",
+ "title": "mark a field as readonly in Open API definition",
+ "readOnly": true
+ },
+ "optionalStringValue": {
+ "type": "string"
+ }
+ },
+ "description": "Intentionally complicated message type to cover many features of Protobuf.",
+ "title": "A bit of everything",
+ "externalDocs": {
+ "description": "Find out more about ABitOfEverything",
+ "url": "https://github.com/grpc-ecosystem/grpc-gateway"
+ },
+ "required": [
+ "uuid",
+ "int64Value",
+ "doubleValue",
+ "floatValue",
+ "requiredStringViaFieldBehaviorAnnotation"
+ ]
+ },
+ "examplepbNumericEnum": {
+ "type": "string",
+ "enum": [
+ "ZERO",
+ "ONE"
+ ],
+ "default": "ZERO",
+ "description": "NumericEnum is one or zero.\n\n - ZERO: ZERO means 0\n - ONE: ONE means 1"
+ },
+ "pathenumPathEnum": {
+ "type": "string",
+ "enum": [
+ "ABC",
+ "DEF"
+ ],
+ "default": "ABC"
+ },
+ "protobufAny": {
+ "type": "object",
+ "properties": {
+ "@type": {
+ "type": "string",
+ "description": "A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n`path/google.protobuf.Duration`). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme `http`, `https`, or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, `https` is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n URL, or have them precompiled into a binary to avoid any\n lookup. Therefore, binary compatibility needs to be preserved\n on changes to types. (Use versioned type names to manage\n breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com.\n\nSchemes other than `http`, `https` (or the empty scheme) might be\nused with implementation specific semantics."
+ }
+ },
+ "additionalProperties": {},
+ "description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(\u0026foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\n Example 4: Pack and unpack a message in Go\n\n foo := \u0026pb.Foo{...}\n any, err := anypb.New(foo)\n if err != nil {\n ...\n }\n ...\n foo := \u0026pb.Foo{}\n if err := any.UnmarshalTo(foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": \u003cstring\u003e,\n \"lastName\": \u003cstring\u003e\n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }"
+ },
+ "rpcStatus": {
+ "type": "object",
+ "properties": {
+ "code": {
+ "type": "integer",
+ "format": "int32",
+ "description": "The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]."
+ },
+ "message": {
+ "type": "string",
+ "description": "A developer-facing error message, which should be in English. Any\nuser-facing error message should be localized and sent in the\n[google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client."
+ },
+ "details": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/protobufAny"
+ },
+ "description": "A list of messages that carry the error details. There is a common set of\nmessage types for APIs to use."
+ }
+ },
+ "description": "The `Status` type defines a logical error model that is suitable for\ndifferent programming environments, including REST APIs and RPC APIs. It is\nused by [gRPC](https://github.com/grpc). Each `Status` message contains\nthree pieces of data: error code, error message, and error details.\n\nYou can find out more about this error model and how to work with it in the\n[API Design Guide](https://cloud.google.com/apis/design/errors)."
+ }
+ }
+}
diff --git a/examples/internal/proto/examplepb/standalone_echo_service.buf.gen.yaml b/examples/internal/proto/examplepb/standalone_echo_service.buf.gen.yaml
new file mode 100644
index 0000000..8673875
--- /dev/null
+++ b/examples/internal/proto/examplepb/standalone_echo_service.buf.gen.yaml
@@ -0,0 +1,8 @@
+version: v1
+plugins:
+ - name: grpc-gateway
+ out: .
+ opt:
+ - paths=source_relative
+ - standalone=true
+ - grpc_api_configuration=examples/internal/proto/examplepb/standalone_echo_service.yaml
diff --git a/examples/internal/proto/examplepb/standalone_echo_service.yaml b/examples/internal/proto/examplepb/standalone_echo_service.yaml
new file mode 100644
index 0000000..fbd9192
--- /dev/null
+++ b/examples/internal/proto/examplepb/standalone_echo_service.yaml
@@ -0,0 +1,17 @@
+type: google.api.Service
+config_version: 3
+
+http:
+ rules:
+ - selector: grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService.Echo
+ post: "/v2/example/echo/{id}"
+ additional_bindings:
+ - get: "/v2/example/echo/{id}/{num}"
+ - get: "/v2/example/echo/{id}/{num}/{lang}"
+ - get: "/v2/example/echo1/{id}/{line_num}/{status.note}"
+ - get: "/v2/example/echo2/{no.note}"
+ - selector: grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService.EchoBody
+ post: "/v2/example/echo_body"
+ body: "*"
+ - selector: grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService.EchoDelete
+ delete: "/v2/example/echo_delete"
diff --git a/examples/internal/proto/examplepb/unannotated_echo_servic.yaml b/examples/internal/proto/examplepb/unannotated_echo_servic.yaml
new file mode 100644
index 0000000..f3e2384
--- /dev/null
+++ b/examples/internal/proto/examplepb/unannotated_echo_servic.yaml
@@ -0,0 +1,15 @@
+type: google.api.Service
+config_version: 3
+
+http:
+ rules:
+ - selector: grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService.Echo
+ post: "/v1/example/echo/{id}"
+ additional_bindings:
+ - get: "/v1/example/echo/{id}/{num}"
+ - selector: grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService.EchoBody
+ post: "/v1/example/echo_body"
+ body: "*"
+ - selector: grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService.EchoDelete
+ delete: "/v1/example/echo_delete"
+
diff --git a/examples/internal/proto/examplepb/unannotated_echo_service.buf.gen.yaml b/examples/internal/proto/examplepb/unannotated_echo_service.buf.gen.yaml
new file mode 100644
index 0000000..6ec699a
--- /dev/null
+++ b/examples/internal/proto/examplepb/unannotated_echo_service.buf.gen.yaml
@@ -0,0 +1,12 @@
+version: v1
+plugins:
+ - name: grpc-gateway
+ out: .
+ opt:
+ - paths=source_relative
+ - grpc_api_configuration=examples/internal/proto/examplepb/unannotated_echo_service.yaml
+ - name: openapiv2
+ out: .
+ opt:
+ - grpc_api_configuration=examples/internal/proto/examplepb/unannotated_echo_service.yaml
+ - openapi_configuration=examples/internal/proto/examplepb/unannotated_echo_service.swagger.yaml
diff --git a/examples/internal/proto/examplepb/unannotated_echo_service.pb.go b/examples/internal/proto/examplepb/unannotated_echo_service.pb.go
new file mode 100755
index 0000000..238ef7a
--- /dev/null
+++ b/examples/internal/proto/examplepb/unannotated_echo_service.pb.go
@@ -0,0 +1,420 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.27.1
+// protoc v3.20.0--rc2
+// source: examples/internal/proto/examplepb/unannotated_echo_service.proto
+
+package examplepb
+
+import (
+ _ "github.com/binchencoder/janus-gateway/httpoptions"
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type UnannotatedEmbedded struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Types that are assignable to Mark:
+ // *UnannotatedEmbedded_Progress
+ // *UnannotatedEmbedded_Note
+ Mark isUnannotatedEmbedded_Mark `protobuf_oneof:"mark"`
+}
+
+func (x *UnannotatedEmbedded) Reset() {
+ *x = UnannotatedEmbedded{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_examples_internal_proto_examplepb_unannotated_echo_service_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *UnannotatedEmbedded) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UnannotatedEmbedded) ProtoMessage() {}
+
+func (x *UnannotatedEmbedded) ProtoReflect() protoreflect.Message {
+ mi := &file_examples_internal_proto_examplepb_unannotated_echo_service_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use UnannotatedEmbedded.ProtoReflect.Descriptor instead.
+func (*UnannotatedEmbedded) Descriptor() ([]byte, []int) {
+ return file_examples_internal_proto_examplepb_unannotated_echo_service_proto_rawDescGZIP(), []int{0}
+}
+
+func (m *UnannotatedEmbedded) GetMark() isUnannotatedEmbedded_Mark {
+ if m != nil {
+ return m.Mark
+ }
+ return nil
+}
+
+func (x *UnannotatedEmbedded) GetProgress() int64 {
+ if x, ok := x.GetMark().(*UnannotatedEmbedded_Progress); ok {
+ return x.Progress
+ }
+ return 0
+}
+
+func (x *UnannotatedEmbedded) GetNote() string {
+ if x, ok := x.GetMark().(*UnannotatedEmbedded_Note); ok {
+ return x.Note
+ }
+ return ""
+}
+
+type isUnannotatedEmbedded_Mark interface {
+ isUnannotatedEmbedded_Mark()
+}
+
+type UnannotatedEmbedded_Progress struct {
+ Progress int64 `protobuf:"varint,1,opt,name=progress,proto3,oneof"`
+}
+
+type UnannotatedEmbedded_Note struct {
+ Note string `protobuf:"bytes,2,opt,name=note,proto3,oneof"`
+}
+
+func (*UnannotatedEmbedded_Progress) isUnannotatedEmbedded_Mark() {}
+
+func (*UnannotatedEmbedded_Note) isUnannotatedEmbedded_Mark() {}
+
+type UnannotatedSimpleMessage struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
+ Num int64 `protobuf:"varint,2,opt,name=num,proto3" json:"num,omitempty"`
+ // Types that are assignable to Code:
+ // *UnannotatedSimpleMessage_LineNum
+ // *UnannotatedSimpleMessage_Lang
+ Code isUnannotatedSimpleMessage_Code `protobuf_oneof:"code"`
+ Status *UnannotatedEmbedded `protobuf:"bytes,6,opt,name=status,proto3" json:"status,omitempty"`
+ // Types that are assignable to Ext:
+ // *UnannotatedSimpleMessage_En
+ // *UnannotatedSimpleMessage_No
+ Ext isUnannotatedSimpleMessage_Ext `protobuf_oneof:"ext"`
+}
+
+func (x *UnannotatedSimpleMessage) Reset() {
+ *x = UnannotatedSimpleMessage{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_examples_internal_proto_examplepb_unannotated_echo_service_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *UnannotatedSimpleMessage) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UnannotatedSimpleMessage) ProtoMessage() {}
+
+func (x *UnannotatedSimpleMessage) ProtoReflect() protoreflect.Message {
+ mi := &file_examples_internal_proto_examplepb_unannotated_echo_service_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use UnannotatedSimpleMessage.ProtoReflect.Descriptor instead.
+func (*UnannotatedSimpleMessage) Descriptor() ([]byte, []int) {
+ return file_examples_internal_proto_examplepb_unannotated_echo_service_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *UnannotatedSimpleMessage) GetId() string {
+ if x != nil {
+ return x.Id
+ }
+ return ""
+}
+
+func (x *UnannotatedSimpleMessage) GetNum() int64 {
+ if x != nil {
+ return x.Num
+ }
+ return 0
+}
+
+func (m *UnannotatedSimpleMessage) GetCode() isUnannotatedSimpleMessage_Code {
+ if m != nil {
+ return m.Code
+ }
+ return nil
+}
+
+func (x *UnannotatedSimpleMessage) GetLineNum() int64 {
+ if x, ok := x.GetCode().(*UnannotatedSimpleMessage_LineNum); ok {
+ return x.LineNum
+ }
+ return 0
+}
+
+func (x *UnannotatedSimpleMessage) GetLang() string {
+ if x, ok := x.GetCode().(*UnannotatedSimpleMessage_Lang); ok {
+ return x.Lang
+ }
+ return ""
+}
+
+func (x *UnannotatedSimpleMessage) GetStatus() *UnannotatedEmbedded {
+ if x != nil {
+ return x.Status
+ }
+ return nil
+}
+
+func (m *UnannotatedSimpleMessage) GetExt() isUnannotatedSimpleMessage_Ext {
+ if m != nil {
+ return m.Ext
+ }
+ return nil
+}
+
+func (x *UnannotatedSimpleMessage) GetEn() int64 {
+ if x, ok := x.GetExt().(*UnannotatedSimpleMessage_En); ok {
+ return x.En
+ }
+ return 0
+}
+
+func (x *UnannotatedSimpleMessage) GetNo() *UnannotatedEmbedded {
+ if x, ok := x.GetExt().(*UnannotatedSimpleMessage_No); ok {
+ return x.No
+ }
+ return nil
+}
+
+type isUnannotatedSimpleMessage_Code interface {
+ isUnannotatedSimpleMessage_Code()
+}
+
+type UnannotatedSimpleMessage_LineNum struct {
+ LineNum int64 `protobuf:"varint,4,opt,name=line_num,json=lineNum,proto3,oneof"`
+}
+
+type UnannotatedSimpleMessage_Lang struct {
+ Lang string `protobuf:"bytes,5,opt,name=lang,proto3,oneof"`
+}
+
+func (*UnannotatedSimpleMessage_LineNum) isUnannotatedSimpleMessage_Code() {}
+
+func (*UnannotatedSimpleMessage_Lang) isUnannotatedSimpleMessage_Code() {}
+
+type isUnannotatedSimpleMessage_Ext interface {
+ isUnannotatedSimpleMessage_Ext()
+}
+
+type UnannotatedSimpleMessage_En struct {
+ En int64 `protobuf:"varint,7,opt,name=en,proto3,oneof"`
+}
+
+type UnannotatedSimpleMessage_No struct {
+ No *UnannotatedEmbedded `protobuf:"bytes,8,opt,name=no,proto3,oneof"`
+}
+
+func (*UnannotatedSimpleMessage_En) isUnannotatedSimpleMessage_Ext() {}
+
+func (*UnannotatedSimpleMessage_No) isUnannotatedSimpleMessage_Ext() {}
+
+var File_examples_internal_proto_examplepb_unannotated_echo_service_proto protoreflect.FileDescriptor
+
+var file_examples_internal_proto_examplepb_unannotated_echo_service_proto_rawDesc = []byte{
+ 0x0a, 0x40, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72,
+ 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
+ 0x65, 0x70, 0x62, 0x2f, 0x75, 0x6e, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64, 0x5f,
+ 0x65, 0x63, 0x68, 0x6f, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x12, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
+ 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
+ 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
+ 0x70, 0x62, 0x1a, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f,
+ 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x22, 0x51, 0x0a, 0x13, 0x55, 0x6e, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64,
+ 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x67,
+ 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x08, 0x70, 0x72,
+ 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x42, 0x06, 0x0a, 0x04,
+ 0x6d, 0x61, 0x72, 0x6b, 0x22, 0xc4, 0x02, 0x0a, 0x18, 0x55, 0x6e, 0x61, 0x6e, 0x6e, 0x6f, 0x74,
+ 0x61, 0x74, 0x65, 0x64, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
+ 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69,
+ 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03,
+ 0x6e, 0x75, 0x6d, 0x12, 0x1b, 0x0a, 0x08, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x18,
+ 0x04, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x07, 0x6c, 0x69, 0x6e, 0x65, 0x4e, 0x75, 0x6d,
+ 0x12, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00,
+ 0x52, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x5b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
+ 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61,
+ 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x69,
+ 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x65, 0x78,
+ 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x55, 0x6e, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61,
+ 0x74, 0x65, 0x64, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x52, 0x06, 0x73, 0x74, 0x61,
+ 0x74, 0x75, 0x73, 0x12, 0x10, 0x0a, 0x02, 0x65, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x48,
+ 0x01, 0x52, 0x02, 0x65, 0x6e, 0x12, 0x55, 0x0a, 0x02, 0x6e, 0x6f, 0x18, 0x08, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x43, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
+ 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
+ 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
+ 0x70, 0x62, 0x2e, 0x55, 0x6e, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64, 0x45, 0x6d,
+ 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x48, 0x01, 0x52, 0x02, 0x6e, 0x6f, 0x42, 0x06, 0x0a, 0x04,
+ 0x63, 0x6f, 0x64, 0x65, 0x42, 0x05, 0x0a, 0x03, 0x65, 0x78, 0x74, 0x32, 0x94, 0x04, 0x0a, 0x16,
+ 0x55, 0x6e, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64, 0x45, 0x63, 0x68, 0x6f, 0x53,
+ 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x9a, 0x01, 0x0a, 0x04, 0x45, 0x63, 0x68, 0x6f, 0x12,
+ 0x48, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x65,
+ 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62,
+ 0x2e, 0x55, 0x6e, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64, 0x53, 0x69, 0x6d, 0x70,
+ 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x48, 0x2e, 0x67, 0x72, 0x70, 0x63,
+ 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
+ 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x55, 0x6e, 0x61, 0x6e, 0x6e,
+ 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73,
+ 0x61, 0x67, 0x65, 0x12, 0x9e, 0x01, 0x0a, 0x08, 0x45, 0x63, 0x68, 0x6f, 0x42, 0x6f, 0x64, 0x79,
+ 0x12, 0x48, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e,
+ 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61,
+ 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70,
+ 0x62, 0x2e, 0x55, 0x6e, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64, 0x53, 0x69, 0x6d,
+ 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x48, 0x2e, 0x67, 0x72, 0x70,
+ 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
+ 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x55, 0x6e, 0x61, 0x6e,
+ 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73,
+ 0x73, 0x61, 0x67, 0x65, 0x12, 0xa0, 0x01, 0x0a, 0x0a, 0x45, 0x63, 0x68, 0x6f, 0x44, 0x65, 0x6c,
+ 0x65, 0x74, 0x65, 0x12, 0x48, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77,
+ 0x61, 0x79, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65,
+ 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70,
+ 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x55, 0x6e, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64,
+ 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x48, 0x2e,
+ 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x65, 0x78, 0x61,
+ 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x55,
+ 0x6e, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65,
+ 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x19, 0xea, 0xf3, 0x34, 0x15, 0x08, 0xb6, 0x95,
+ 0xff, 0xff, 0x07, 0x12, 0x04, 0x67, 0x72, 0x70, 0x63, 0x1a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75,
+ 0x6c, 0x74, 0x42, 0x53, 0x5a, 0x51, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2f, 0x62, 0x69, 0x6e, 0x63, 0x68, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x6a, 0x61,
+ 0x6e, 0x75, 0x73, 0x2d, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2f, 0x65, 0x78, 0x61, 0x6d,
+ 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x3b, 0x65, 0x78,
+ 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_examples_internal_proto_examplepb_unannotated_echo_service_proto_rawDescOnce sync.Once
+ file_examples_internal_proto_examplepb_unannotated_echo_service_proto_rawDescData = file_examples_internal_proto_examplepb_unannotated_echo_service_proto_rawDesc
+)
+
+func file_examples_internal_proto_examplepb_unannotated_echo_service_proto_rawDescGZIP() []byte {
+ file_examples_internal_proto_examplepb_unannotated_echo_service_proto_rawDescOnce.Do(func() {
+ file_examples_internal_proto_examplepb_unannotated_echo_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_examples_internal_proto_examplepb_unannotated_echo_service_proto_rawDescData)
+ })
+ return file_examples_internal_proto_examplepb_unannotated_echo_service_proto_rawDescData
+}
+
+var file_examples_internal_proto_examplepb_unannotated_echo_service_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
+var file_examples_internal_proto_examplepb_unannotated_echo_service_proto_goTypes = []interface{}{
+ (*UnannotatedEmbedded)(nil), // 0: grpc.gateway.examples.internal.proto.examplepb.UnannotatedEmbedded
+ (*UnannotatedSimpleMessage)(nil), // 1: grpc.gateway.examples.internal.proto.examplepb.UnannotatedSimpleMessage
+}
+var file_examples_internal_proto_examplepb_unannotated_echo_service_proto_depIdxs = []int32{
+ 0, // 0: grpc.gateway.examples.internal.proto.examplepb.UnannotatedSimpleMessage.status:type_name -> grpc.gateway.examples.internal.proto.examplepb.UnannotatedEmbedded
+ 0, // 1: grpc.gateway.examples.internal.proto.examplepb.UnannotatedSimpleMessage.no:type_name -> grpc.gateway.examples.internal.proto.examplepb.UnannotatedEmbedded
+ 1, // 2: grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService.Echo:input_type -> grpc.gateway.examples.internal.proto.examplepb.UnannotatedSimpleMessage
+ 1, // 3: grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService.EchoBody:input_type -> grpc.gateway.examples.internal.proto.examplepb.UnannotatedSimpleMessage
+ 1, // 4: grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService.EchoDelete:input_type -> grpc.gateway.examples.internal.proto.examplepb.UnannotatedSimpleMessage
+ 1, // 5: grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService.Echo:output_type -> grpc.gateway.examples.internal.proto.examplepb.UnannotatedSimpleMessage
+ 1, // 6: grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService.EchoBody:output_type -> grpc.gateway.examples.internal.proto.examplepb.UnannotatedSimpleMessage
+ 1, // 7: grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService.EchoDelete:output_type -> grpc.gateway.examples.internal.proto.examplepb.UnannotatedSimpleMessage
+ 5, // [5:8] is the sub-list for method output_type
+ 2, // [2:5] is the sub-list for method input_type
+ 2, // [2:2] is the sub-list for extension type_name
+ 2, // [2:2] is the sub-list for extension extendee
+ 0, // [0:2] is the sub-list for field type_name
+}
+
+func init() { file_examples_internal_proto_examplepb_unannotated_echo_service_proto_init() }
+func file_examples_internal_proto_examplepb_unannotated_echo_service_proto_init() {
+ if File_examples_internal_proto_examplepb_unannotated_echo_service_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_examples_internal_proto_examplepb_unannotated_echo_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*UnannotatedEmbedded); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_examples_internal_proto_examplepb_unannotated_echo_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*UnannotatedSimpleMessage); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ file_examples_internal_proto_examplepb_unannotated_echo_service_proto_msgTypes[0].OneofWrappers = []interface{}{
+ (*UnannotatedEmbedded_Progress)(nil),
+ (*UnannotatedEmbedded_Note)(nil),
+ }
+ file_examples_internal_proto_examplepb_unannotated_echo_service_proto_msgTypes[1].OneofWrappers = []interface{}{
+ (*UnannotatedSimpleMessage_LineNum)(nil),
+ (*UnannotatedSimpleMessage_Lang)(nil),
+ (*UnannotatedSimpleMessage_En)(nil),
+ (*UnannotatedSimpleMessage_No)(nil),
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_examples_internal_proto_examplepb_unannotated_echo_service_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 2,
+ NumExtensions: 0,
+ NumServices: 1,
+ },
+ GoTypes: file_examples_internal_proto_examplepb_unannotated_echo_service_proto_goTypes,
+ DependencyIndexes: file_examples_internal_proto_examplepb_unannotated_echo_service_proto_depIdxs,
+ MessageInfos: file_examples_internal_proto_examplepb_unannotated_echo_service_proto_msgTypes,
+ }.Build()
+ File_examples_internal_proto_examplepb_unannotated_echo_service_proto = out.File
+ file_examples_internal_proto_examplepb_unannotated_echo_service_proto_rawDesc = nil
+ file_examples_internal_proto_examplepb_unannotated_echo_service_proto_goTypes = nil
+ file_examples_internal_proto_examplepb_unannotated_echo_service_proto_depIdxs = nil
+}
diff --git a/examples/internal/proto/examplepb/unannotated_echo_service.pb.gw.go b/examples/internal/proto/examplepb/unannotated_echo_service.pb.gw.go
new file mode 100755
index 0000000..b76fb60
--- /dev/null
+++ b/examples/internal/proto/examplepb/unannotated_echo_service.pb.gw.go
@@ -0,0 +1,3 @@
+// +build ignore
+
+package ignore
\ No newline at end of file
diff --git a/examples/internal/proto/examplepb/unannotated_echo_service.proto b/examples/internal/proto/examplepb/unannotated_echo_service.proto
new file mode 100644
index 0000000..3454400
--- /dev/null
+++ b/examples/internal/proto/examplepb/unannotated_echo_service.proto
@@ -0,0 +1,62 @@
+syntax = "proto3";
+
+// Unannotated Echo Service
+// Similar to echo_service.proto but without annotations. See
+// unannotated_echo_service.yaml for the equivalent of the annotations in
+// gRPC API configuration format.
+//
+// Echo Service API consists of a single service which returns
+// a message.
+package grpc.gateway.examples.internal.proto.examplepb;
+
+import "httpoptions/annotations.proto";
+// Do not need annotations.proto, can still use well known types as usual
+// import "google/protobuf/duration.proto";
+
+option go_package = "github.com/binchencoder/janus-gateway/examples/internal/proto/examplepb;examplepb";
+
+// Embedded represents a message embedded in SimpleMessage.
+message UnannotatedEmbedded {
+ oneof mark {
+ int64 progress = 1;
+ string note = 2;
+ }
+}
+
+// UnannotatedSimpleMessage represents a simple message sent to the unannotated Echo service.
+message UnannotatedSimpleMessage {
+ // Id represents the message identifier.
+ string id = 1;
+ int64 num = 2;
+ // google.protobuf.Duration duration = 3;
+ oneof code {
+ int64 line_num = 4;
+ string lang = 5;
+ }
+ UnannotatedEmbedded status = 6;
+ oneof ext {
+ int64 en = 7;
+ UnannotatedEmbedded no = 8;
+ }
+}
+
+// Echo service responds to incoming echo requests.
+service UnannotatedEchoService {
+ option (janus.api.service_spec) = {
+ service_id: CUSTOM_JANUS_GATEWAY_TEST
+ port_name : "grpc"
+ namespace : "default"
+ };
+
+ // Echo method receives a simple message and returns it.
+ //
+ // The message posted as the id parameter will also be
+ // returned.
+ rpc Echo(UnannotatedSimpleMessage) returns (UnannotatedSimpleMessage);
+
+ // EchoBody method receives a simple message and returns it.
+ rpc EchoBody(UnannotatedSimpleMessage) returns (UnannotatedSimpleMessage);
+
+ // EchoDelete method receives a simple message and returns it.
+ rpc EchoDelete(UnannotatedSimpleMessage) returns (UnannotatedSimpleMessage);
+}
diff --git a/examples/internal/proto/examplepb/unannotated_echo_service.swagger.yaml b/examples/internal/proto/examplepb/unannotated_echo_service.swagger.yaml
new file mode 100644
index 0000000..6329dad
--- /dev/null
+++ b/examples/internal/proto/examplepb/unannotated_echo_service.swagger.yaml
@@ -0,0 +1,112 @@
+openapiOptions:
+ file:
+ # the file name must be the same as one passed to protoc when generating generating .swagger.json
+ - file: "examples/internal/proto/examplepb/unannotated_echo_service.proto"
+ option:
+ info:
+ title: Unannotated Echo
+ contact:
+ name: gRPC-Gateway project
+ url: https://github.com/grpc-ecosystem/grpc-gateway
+ email: none@example.com
+ license:
+ name: BSD 3-Clause License
+ url: https://github.com/grpc-ecosystem/grpc-gateway/blob/master/LICENSE.txt
+ version: "1.0"
+ extensions:
+ x-something-something: yadda
+ schemes:
+ - HTTP
+ - HTTPS
+ - WSS
+ consumes:
+ - application/json
+ - application/x-foo-mime
+ produces:
+ - application/json
+ - application/x-foo-mime
+ responses:
+ "403":
+ description: Returned when the user does not have permission to access the resource.
+ "404":
+ description: Returned when the resource does not exist.
+ schema:
+ jsonSchema:
+ type:
+ - STRING
+ securityDefinitions:
+ security:
+ ApiKeyAuth:
+ type: TYPE_API_KEY
+ name: X-API-Key
+ in: IN_HEADER
+ extensions:
+ x-amazon-apigateway-authorizer:
+ authorizerResultTtlInSeconds: 60
+ type: token
+ x-amazon-apigateway-authtype: oauth2
+ BasicAuth:
+ type: TYPE_BASIC
+ security:
+ - securityRequirement:
+ ApiKeyAuth: {}
+ BasicAuth: {}
+ - securityRequirement:
+ ApiKeyAuth: {}
+ OAuth2:
+ scope:
+ - read
+ - write
+ externalDocs:
+ description: More about gRPC-Gateway
+ url: https://github.com/grpc-ecosystem/grpc-gateway
+ extensions:
+ x-grpc-gateway-baz-list:
+ - one
+ - true
+ x-grpc-gateway-foo: bar
+ service:
+ - service: grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService
+ option:
+ description: "UnannotatedEchoService description -- which should not be used in place of the documentation comment!"
+ external_docs:
+ url: "https://github.com/grpc-ecosystem/grpc-gateway"
+ description: "Find out more about UnannotatedEchoService"
+ method:
+ - method: grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService.Echo
+ option:
+ description: "Description Echo"
+ summary: "Summary: Echo rpc"
+ external_docs:
+ url: "https://github.com/grpc-ecosystem/grpc-gateway"
+ description: "Find out more Echo"
+ responses:
+ "200":
+ examples:
+ "application/json": '{"value": "the input value"}'
+ "503":
+ description: Returned when the resource is temporarily unavailable.
+ extensions:
+ x-number: 100
+ "404":
+ description: Returned when the resource does not exist.
+ schema:
+ jsonSchema:
+ type: [INTEGER]
+ message:
+ - message: grpc.gateway.examples.internal.proto.examplepb.UnannotatedSimpleMessage
+ option:
+ json_schema:
+ title: "A bit of everything"
+ description: "A simple message with many types"
+ required: ["id"]
+ external_docs:
+ url: "https://github.com/grpc-ecosystem/grpc-gateway"
+ description: "Find out more about UnannotatedSimpleMessage"
+ example: '{"id": "myid"}'
+ field:
+ - field: grpc.gateway.examples.internal.proto.examplepb.UnannotatedSimpleMessage.num
+ option:
+ description: "Int value field"
+ default: "42"
+ required: ["num"]
diff --git a/examples/internal/proto/examplepb/unannotated_echo_service_grpc.pb.go b/examples/internal/proto/examplepb/unannotated_echo_service_grpc.pb.go
new file mode 100755
index 0000000..8e1bb7c
--- /dev/null
+++ b/examples/internal/proto/examplepb/unannotated_echo_service_grpc.pb.go
@@ -0,0 +1,167 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+
+package examplepb
+
+import (
+ context "context"
+ grpc "google.golang.org/grpc"
+ codes "google.golang.org/grpc/codes"
+ status "google.golang.org/grpc/status"
+)
+
+// 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.SupportPackageIsVersion7
+
+// UnannotatedEchoServiceClient is the client API for UnannotatedEchoService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type UnannotatedEchoServiceClient interface {
+ Echo(ctx context.Context, in *UnannotatedSimpleMessage, opts ...grpc.CallOption) (*UnannotatedSimpleMessage, error)
+ EchoBody(ctx context.Context, in *UnannotatedSimpleMessage, opts ...grpc.CallOption) (*UnannotatedSimpleMessage, error)
+ EchoDelete(ctx context.Context, in *UnannotatedSimpleMessage, opts ...grpc.CallOption) (*UnannotatedSimpleMessage, error)
+}
+
+type unannotatedEchoServiceClient struct {
+ cc grpc.ClientConnInterface
+}
+
+func NewUnannotatedEchoServiceClient(cc grpc.ClientConnInterface) UnannotatedEchoServiceClient {
+ return &unannotatedEchoServiceClient{cc}
+}
+
+func (c *unannotatedEchoServiceClient) Echo(ctx context.Context, in *UnannotatedSimpleMessage, opts ...grpc.CallOption) (*UnannotatedSimpleMessage, error) {
+ out := new(UnannotatedSimpleMessage)
+ err := c.cc.Invoke(ctx, "/grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService/Echo", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *unannotatedEchoServiceClient) EchoBody(ctx context.Context, in *UnannotatedSimpleMessage, opts ...grpc.CallOption) (*UnannotatedSimpleMessage, error) {
+ out := new(UnannotatedSimpleMessage)
+ err := c.cc.Invoke(ctx, "/grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService/EchoBody", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *unannotatedEchoServiceClient) EchoDelete(ctx context.Context, in *UnannotatedSimpleMessage, opts ...grpc.CallOption) (*UnannotatedSimpleMessage, error) {
+ out := new(UnannotatedSimpleMessage)
+ err := c.cc.Invoke(ctx, "/grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService/EchoDelete", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+// UnannotatedEchoServiceServer is the server API for UnannotatedEchoService service.
+// All implementations should embed UnimplementedUnannotatedEchoServiceServer
+// for forward compatibility
+type UnannotatedEchoServiceServer interface {
+ Echo(context.Context, *UnannotatedSimpleMessage) (*UnannotatedSimpleMessage, error)
+ EchoBody(context.Context, *UnannotatedSimpleMessage) (*UnannotatedSimpleMessage, error)
+ EchoDelete(context.Context, *UnannotatedSimpleMessage) (*UnannotatedSimpleMessage, error)
+}
+
+// UnimplementedUnannotatedEchoServiceServer should be embedded to have forward compatible implementations.
+type UnimplementedUnannotatedEchoServiceServer struct {
+}
+
+func (UnimplementedUnannotatedEchoServiceServer) Echo(context.Context, *UnannotatedSimpleMessage) (*UnannotatedSimpleMessage, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method Echo not implemented")
+}
+func (UnimplementedUnannotatedEchoServiceServer) EchoBody(context.Context, *UnannotatedSimpleMessage) (*UnannotatedSimpleMessage, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method EchoBody not implemented")
+}
+func (UnimplementedUnannotatedEchoServiceServer) EchoDelete(context.Context, *UnannotatedSimpleMessage) (*UnannotatedSimpleMessage, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method EchoDelete not implemented")
+}
+
+// UnsafeUnannotatedEchoServiceServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to UnannotatedEchoServiceServer will
+// result in compilation errors.
+type UnsafeUnannotatedEchoServiceServer interface {
+ mustEmbedUnimplementedUnannotatedEchoServiceServer()
+}
+
+func RegisterUnannotatedEchoServiceServer(s *grpc.Server, srv UnannotatedEchoServiceServer) {
+ s.RegisterService(&_UnannotatedEchoService_serviceDesc, srv)
+}
+
+func _UnannotatedEchoService_Echo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(UnannotatedSimpleMessage)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(UnannotatedEchoServiceServer).Echo(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService/Echo",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(UnannotatedEchoServiceServer).Echo(ctx, req.(*UnannotatedSimpleMessage))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _UnannotatedEchoService_EchoBody_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(UnannotatedSimpleMessage)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(UnannotatedEchoServiceServer).EchoBody(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService/EchoBody",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(UnannotatedEchoServiceServer).EchoBody(ctx, req.(*UnannotatedSimpleMessage))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _UnannotatedEchoService_EchoDelete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(UnannotatedSimpleMessage)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(UnannotatedEchoServiceServer).EchoDelete(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService/EchoDelete",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(UnannotatedEchoServiceServer).EchoDelete(ctx, req.(*UnannotatedSimpleMessage))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+var _UnannotatedEchoService_serviceDesc = grpc.ServiceDesc{
+ ServiceName: "grpc.gateway.examples.internal.proto.examplepb.UnannotatedEchoService",
+ HandlerType: (*UnannotatedEchoServiceServer)(nil),
+ Methods: []grpc.MethodDesc{
+ {
+ MethodName: "Echo",
+ Handler: _UnannotatedEchoService_Echo_Handler,
+ },
+ {
+ MethodName: "EchoBody",
+ Handler: _UnannotatedEchoService_EchoBody_Handler,
+ },
+ {
+ MethodName: "EchoDelete",
+ Handler: _UnannotatedEchoService_EchoDelete_Handler,
+ },
+ },
+ Streams: []grpc.StreamDesc{},
+ Metadata: "examples/internal/proto/examplepb/unannotated_echo_service.proto",
+}
diff --git a/examples/internal/server/BUILD.bazel b/examples/internal/server/BUILD.bazel
new file mode 100644
index 0000000..8f21e56
--- /dev/null
+++ b/examples/internal/server/BUILD.bazel
@@ -0,0 +1,39 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+package(default_visibility = ["//visibility:public"])
+
+go_library(
+ name = "server",
+ srcs = [
+ "echo.go",
+ "main.go",
+ "unannotatedecho.go",
+ ],
+ importpath = "github.com/binchencoder/janus-gateway/examples/internal/server",
+ deps = [
+ "//examples/internal/proto/examplepb",
+ # "//examples/internal/proto/standalone",
+ "//gateway/runtime",
+ "@com_github_golang_glog//:glog",
+ "@com_github_rogpeppe_fastuuid//:fastuuid",
+ "@go_googleapis//google/api:httpbody_go_proto",
+ "@go_googleapis//google/rpc:errdetails_go_proto",
+ "@go_googleapis//google/rpc:status_go_proto",
+ "@io_bazel_rules_go//proto/wkt:field_mask_go_proto",
+ "@org_golang_google_grpc//:go_default_library",
+ "@org_golang_google_grpc//codes",
+ "@org_golang_google_grpc//metadata",
+ "@org_golang_google_grpc//status",
+ "@org_golang_google_protobuf//proto",
+ "@org_golang_google_protobuf//reflect/protoreflect",
+ "@org_golang_google_protobuf//types/known/durationpb",
+ "@org_golang_google_protobuf//types/known/emptypb",
+ "@org_golang_google_protobuf//types/known/wrapperspb",
+ ],
+)
+
+alias(
+ name = "go_default_library",
+ actual = ":server",
+ visibility = ["//examples:__subpackages__"],
+)
diff --git a/examples/server/echo.go b/examples/internal/server/echo.go
similarity index 54%
rename from examples/server/echo.go
rename to examples/internal/server/echo.go
index b0fd3a2..d2f6d38 100644
--- a/examples/server/echo.go
+++ b/examples/internal/server/echo.go
@@ -3,17 +3,18 @@ package server
import (
"context"
- examples "github.com/binchencoder/ease-gateway/examples/proto"
+ examples "github.com/binchencoder/janus-gateway/examples/internal/proto/examplepb"
"github.com/golang/glog"
"google.golang.org/grpc"
+ "google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
+ "google.golang.org/grpc/status"
)
// Implements of EchoServiceServer
type echoServer struct{}
-// NewEchoServer new echo server
func NewEchoServer() examples.EchoServiceServer {
return new(echoServer)
}
@@ -40,3 +41,18 @@ func (s *echoServer) EchoDelete(ctx context.Context, msg *examples.SimpleMessage
glog.Info(msg)
return msg, nil
}
+
+func (s *echoServer) EchoPatch(ctx context.Context, msg *examples.DynamicMessageUpdate) (*examples.DynamicMessageUpdate, error) {
+ glog.Info(msg)
+ return msg, nil
+}
+
+func (s *echoServer) EchoUnauthorized(ctx context.Context, msg *examples.SimpleMessage) (*examples.SimpleMessage, error) {
+ glog.Info(msg)
+ return nil, status.Error(codes.Unauthenticated, "unauthorized err")
+}
+
+func (s *echoServer) EchoValidationRule(ctx context.Context, msg *examples.ValidationRuleTestRequest) (*examples.ValidationRuleTestResponse, error) {
+ glog.Info(msg)
+ return &examples.ValidationRuleTestResponse{}, nil
+}
diff --git a/examples/internal/server/main.go b/examples/internal/server/main.go
new file mode 100644
index 0000000..ca95cfc
--- /dev/null
+++ b/examples/internal/server/main.go
@@ -0,0 +1,65 @@
+package server
+
+import (
+ "context"
+ "net"
+ "net/http"
+
+ examples "github.com/binchencoder/janus-gateway/examples/internal/proto/examplepb"
+ "github.com/binchencoder/janus-gateway/gateway/runtime"
+ "github.com/golang/glog"
+
+ // standalone "github.com/binchencoder/janus-gateway/examples/internal/proto/standalone"
+ "google.golang.org/grpc"
+)
+
+// Run starts the example gRPC service.
+// "network" and "address" are passed to net.Listen.
+func Run(ctx context.Context, network, address string) error {
+ l, err := net.Listen(network, address)
+ if err != nil {
+ return err
+ }
+ defer func() {
+ if err := l.Close(); err != nil {
+ glog.Errorf("Failed to close %s %s: %v", network, address, err)
+ }
+ }()
+
+ s := grpc.NewServer()
+ examples.RegisterEchoServiceServer(s, NewEchoServer())
+ examples.RegisterUnannotatedEchoServiceServer(s, newUnannotatedEchoServer())
+
+ go func() {
+ defer s.GracefulStop()
+ <-ctx.Done()
+ }()
+ return s.Serve(l)
+}
+
+// RunInProcessGateway starts the invoke in process http gateway.
+func RunInProcessGateway(ctx context.Context, addr string, opts ...runtime.ServeMuxOption) error {
+ mux := runtime.NewServeMux(opts...)
+
+ examples.RegisterEchoServiceHandlerServer(ctx, mux, NewEchoServer())
+ // examples.RegisterNonStandardServiceHandlerServer(ctx, mux, newNonStandardServer())
+ // standalone.RegisterUnannotatedEchoServiceHandlerServer(ctx, mux, newUnannotatedEchoServer())
+ s := &http.Server{
+ Addr: addr,
+ Handler: mux,
+ }
+
+ go func() {
+ <-ctx.Done()
+ glog.Infof("Shutting down the http gateway server")
+ if err := s.Shutdown(context.Background()); err != nil {
+ glog.Errorf("Failed to shutdown http gateway server: %v", err)
+ }
+ }()
+
+ if err := s.ListenAndServe(); err != http.ErrServerClosed {
+ glog.Errorf("Failed to listen and serve: %v", err)
+ return err
+ }
+ return nil
+}
diff --git a/examples/internal/server/unannotatedecho.go b/examples/internal/server/unannotatedecho.go
new file mode 100644
index 0000000..2b446b2
--- /dev/null
+++ b/examples/internal/server/unannotatedecho.go
@@ -0,0 +1,41 @@
+package server
+
+import (
+ "context"
+
+ "github.com/golang/glog"
+ examples "github.com/binchencoder/janus-gateway/examples/internal/proto/examplepb"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/metadata"
+)
+
+// Implements of UnannotatedEchoServiceServer
+
+type unannotatedEchoServer struct{}
+
+func newUnannotatedEchoServer() examples.UnannotatedEchoServiceServer {
+ return new(unannotatedEchoServer)
+}
+
+func (s *unannotatedEchoServer) Echo(ctx context.Context, msg *examples.UnannotatedSimpleMessage) (*examples.UnannotatedSimpleMessage, error) {
+ glog.Info(msg)
+ return msg, nil
+}
+
+func (s *unannotatedEchoServer) EchoBody(ctx context.Context, msg *examples.UnannotatedSimpleMessage) (*examples.UnannotatedSimpleMessage, error) {
+ glog.Info(msg)
+ grpc.SendHeader(ctx, metadata.New(map[string]string{
+ "foo": "foo1",
+ "bar": "bar1",
+ }))
+ grpc.SetTrailer(ctx, metadata.New(map[string]string{
+ "foo": "foo2",
+ "bar": "bar2",
+ }))
+ return msg, nil
+}
+
+func (s *unannotatedEchoServer) EchoDelete(ctx context.Context, msg *examples.UnannotatedSimpleMessage) (*examples.UnannotatedSimpleMessage, error) {
+ glog.Info(msg)
+ return msg, nil
+}
diff --git a/examples/proto/BUILD.bazel b/examples/proto/BUILD.bazel
deleted file mode 100644
index 93aaf48..0000000
--- a/examples/proto/BUILD.bazel
+++ /dev/null
@@ -1,63 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library")
-load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
-load("//gateway/protoc-gen-swagger:defs.bzl", "protoc_gen_swagger")
-
-package(default_visibility = ["//visibility:public"])
-
-# gazelle:exclude echo_service.pb.gw.go
-
-proto_library(
- name = "examplepb_proto",
- srcs = glob(["*.proto"]),
- deps = [
- "//httpoptions:options_proto",
- "@com_github_binchencoder_gateway_proto//data:data_proto",
- "@com_github_binchencoder_gateway_proto//frontend:error_proto",
- "@com_google_protobuf//:duration_proto",
- "@com_google_protobuf//:empty_proto",
- "@com_google_protobuf//:field_mask_proto",
- "@com_google_protobuf//:timestamp_proto",
- "@com_google_protobuf//:wrappers_proto",
- "@go_googleapis//google/api:annotations_proto",
- ],
-)
-
-go_proto_library(
- name = "examplepb_go_proto",
- compilers = [
- "@io_bazel_rules_go//proto:go_grpc",
- "//gateway/protoc-gen-grpc-gateway:go_gen_grpc_gateway", # keep
- ],
- importpath = "github.com/binchencoder/ease-gateway/examples/proto",
- proto = ":examplepb_proto",
- deps = [
- "//httpoptions:go_default_library",
- "//gateway/runtime:go_default_library",
- "@com_github_binchencoder_letsgo//grpc:go_default_library",
- "@com_github_binchencoder_skylb_api//balancer:go_default_library",
- "@com_github_binchencoder_skylb_api//client:go_default_library",
- "@com_github_binchencoder_skylb_api//client/option:go_default_library",
- "@com_github_binchencoder_skylb_api//proto:go_default_library",
- "@org_golang_google_grpc//naming:go_default_library",
- ],
-)
-
-go_library(
- name = "go_default_library",
- embed = [":examplepb_go_proto"],
- importpath = "github.com/binchencoder/ease-gateway/examples/proto",
- deps = [
- "//httpoptions:go_default_library",
- "//gateway/runtime:go_default_library",
- "@com_github_binchencoder_gateway_proto//data:go_default_library",
- "@com_github_binchencoder_gateway_proto//frontend:go_default_library",
- "@com_github_binchencoder_skylb_api//balancer:go_default_library",
- "@com_github_binchencoder_skylb_api//client:go_default_library",
- ],
-)
-
-protoc_gen_swagger(
- name = "expamplepb_protoc_gen_swagger",
- proto = ":examplepb_proto",
- single_output = False, # Outputs a single swagger.json file.
-)
\ No newline at end of file
diff --git a/examples/proto/echo_service.pb.go b/examples/proto/echo_service.pb.go
deleted file mode 100755
index 18a3f20..0000000
--- a/examples/proto/echo_service.pb.go
+++ /dev/null
@@ -1,431 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: examples/proto/echo_service.proto
-
-package proto
-
-import (
- context "context"
- fmt "fmt"
- _ "github.com/binchencoder/ease-gateway/httpoptions"
- proto "github.com/golang/protobuf/proto"
- grpc "google.golang.org/grpc"
- 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 Embedded struct {
- // Types that are valid to be assigned to Mark:
- // *Embedded_Progress
- // *Embedded_Note
- Mark isEmbedded_Mark `protobuf_oneof:"mark"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
-}
-
-func (m *Embedded) Reset() { *m = Embedded{} }
-func (m *Embedded) String() string { return proto.CompactTextString(m) }
-func (*Embedded) ProtoMessage() {}
-func (*Embedded) Descriptor() ([]byte, []int) {
- return fileDescriptor_4b4d3f52be8fcd98, []int{0}
-}
-
-func (m *Embedded) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Embedded.Unmarshal(m, b)
-}
-func (m *Embedded) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Embedded.Marshal(b, m, deterministic)
-}
-func (m *Embedded) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Embedded.Merge(m, src)
-}
-func (m *Embedded) XXX_Size() int {
- return xxx_messageInfo_Embedded.Size(m)
-}
-func (m *Embedded) XXX_DiscardUnknown() {
- xxx_messageInfo_Embedded.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Embedded proto.InternalMessageInfo
-
-type isEmbedded_Mark interface {
- isEmbedded_Mark()
-}
-
-type Embedded_Progress struct {
- Progress int64 `protobuf:"varint,1,opt,name=progress,proto3,oneof"`
-}
-
-type Embedded_Note struct {
- Note string `protobuf:"bytes,2,opt,name=note,proto3,oneof"`
-}
-
-func (*Embedded_Progress) isEmbedded_Mark() {}
-
-func (*Embedded_Note) isEmbedded_Mark() {}
-
-func (m *Embedded) GetMark() isEmbedded_Mark {
- if m != nil {
- return m.Mark
- }
- return nil
-}
-
-func (m *Embedded) GetProgress() int64 {
- if x, ok := m.GetMark().(*Embedded_Progress); ok {
- return x.Progress
- }
- return 0
-}
-
-func (m *Embedded) GetNote() string {
- if x, ok := m.GetMark().(*Embedded_Note); ok {
- return x.Note
- }
- return ""
-}
-
-// XXX_OneofWrappers is for the internal use of the proto package.
-func (*Embedded) XXX_OneofWrappers() []interface{} {
- return []interface{}{
- (*Embedded_Progress)(nil),
- (*Embedded_Note)(nil),
- }
-}
-
-type SimpleMessage struct {
- Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
- Num int64 `protobuf:"varint,2,opt,name=num,proto3" json:"num,omitempty"`
- // Types that are valid to be assigned to Code:
- // *SimpleMessage_LineNum
- // *SimpleMessage_Lang
- Code isSimpleMessage_Code `protobuf_oneof:"code"`
- Status *Embedded `protobuf:"bytes,5,opt,name=status,proto3" json:"status,omitempty"`
- // Types that are valid to be assigned to Ext:
- // *SimpleMessage_En
- // *SimpleMessage_No
- Ext isSimpleMessage_Ext `protobuf_oneof:"ext"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
-}
-
-func (m *SimpleMessage) Reset() { *m = SimpleMessage{} }
-func (m *SimpleMessage) String() string { return proto.CompactTextString(m) }
-func (*SimpleMessage) ProtoMessage() {}
-func (*SimpleMessage) Descriptor() ([]byte, []int) {
- return fileDescriptor_4b4d3f52be8fcd98, []int{1}
-}
-
-func (m *SimpleMessage) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_SimpleMessage.Unmarshal(m, b)
-}
-func (m *SimpleMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_SimpleMessage.Marshal(b, m, deterministic)
-}
-func (m *SimpleMessage) XXX_Merge(src proto.Message) {
- xxx_messageInfo_SimpleMessage.Merge(m, src)
-}
-func (m *SimpleMessage) XXX_Size() int {
- return xxx_messageInfo_SimpleMessage.Size(m)
-}
-func (m *SimpleMessage) XXX_DiscardUnknown() {
- xxx_messageInfo_SimpleMessage.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_SimpleMessage proto.InternalMessageInfo
-
-func (m *SimpleMessage) GetId() string {
- if m != nil {
- return m.Id
- }
- return ""
-}
-
-func (m *SimpleMessage) GetNum() int64 {
- if m != nil {
- return m.Num
- }
- return 0
-}
-
-type isSimpleMessage_Code interface {
- isSimpleMessage_Code()
-}
-
-type SimpleMessage_LineNum struct {
- LineNum int64 `protobuf:"varint,3,opt,name=line_num,json=lineNum,proto3,oneof"`
-}
-
-type SimpleMessage_Lang struct {
- Lang string `protobuf:"bytes,4,opt,name=lang,proto3,oneof"`
-}
-
-func (*SimpleMessage_LineNum) isSimpleMessage_Code() {}
-
-func (*SimpleMessage_Lang) isSimpleMessage_Code() {}
-
-func (m *SimpleMessage) GetCode() isSimpleMessage_Code {
- if m != nil {
- return m.Code
- }
- return nil
-}
-
-func (m *SimpleMessage) GetLineNum() int64 {
- if x, ok := m.GetCode().(*SimpleMessage_LineNum); ok {
- return x.LineNum
- }
- return 0
-}
-
-func (m *SimpleMessage) GetLang() string {
- if x, ok := m.GetCode().(*SimpleMessage_Lang); ok {
- return x.Lang
- }
- return ""
-}
-
-func (m *SimpleMessage) GetStatus() *Embedded {
- if m != nil {
- return m.Status
- }
- return nil
-}
-
-type isSimpleMessage_Ext interface {
- isSimpleMessage_Ext()
-}
-
-type SimpleMessage_En struct {
- En int64 `protobuf:"varint,6,opt,name=en,proto3,oneof"`
-}
-
-type SimpleMessage_No struct {
- No *Embedded `protobuf:"bytes,7,opt,name=no,proto3,oneof"`
-}
-
-func (*SimpleMessage_En) isSimpleMessage_Ext() {}
-
-func (*SimpleMessage_No) isSimpleMessage_Ext() {}
-
-func (m *SimpleMessage) GetExt() isSimpleMessage_Ext {
- if m != nil {
- return m.Ext
- }
- return nil
-}
-
-func (m *SimpleMessage) GetEn() int64 {
- if x, ok := m.GetExt().(*SimpleMessage_En); ok {
- return x.En
- }
- return 0
-}
-
-func (m *SimpleMessage) GetNo() *Embedded {
- if x, ok := m.GetExt().(*SimpleMessage_No); ok {
- return x.No
- }
- return nil
-}
-
-// XXX_OneofWrappers is for the internal use of the proto package.
-func (*SimpleMessage) XXX_OneofWrappers() []interface{} {
- return []interface{}{
- (*SimpleMessage_LineNum)(nil),
- (*SimpleMessage_Lang)(nil),
- (*SimpleMessage_En)(nil),
- (*SimpleMessage_No)(nil),
- }
-}
-
-func init() {
- proto.RegisterType((*Embedded)(nil), "ease.gateway.examples.proto.Embedded")
- proto.RegisterType((*SimpleMessage)(nil), "ease.gateway.examples.proto.SimpleMessage")
-}
-
-func init() { proto.RegisterFile("examples/proto/echo_service.proto", fileDescriptor_4b4d3f52be8fcd98) }
-
-var fileDescriptor_4b4d3f52be8fcd98 = []byte{
- // 489 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x52, 0x41, 0x6b, 0x13, 0x41,
- 0x14, 0xee, 0x6c, 0xb6, 0x49, 0x3a, 0x45, 0x29, 0x83, 0xd2, 0x35, 0xb1, 0x92, 0x06, 0x85, 0x90,
- 0xc3, 0x0e, 0x89, 0x01, 0x41, 0xf0, 0x12, 0xac, 0xf4, 0xa2, 0x87, 0xed, 0x2d, 0x97, 0x30, 0xc9,
- 0x3c, 0xb7, 0x8b, 0xbb, 0x33, 0xcb, 0xce, 0x6c, 0x6d, 0x58, 0x72, 0xd1, 0xbf, 0xa0, 0x7f, 0xc3,
- 0x8b, 0xe0, 0x8f, 0x08, 0xfe, 0x12, 0xaf, 0x39, 0x4b, 0x65, 0x66, 0x37, 0x82, 0xb6, 0x04, 0x7a,
- 0xe8, 0x69, 0xe6, 0x7d, 0xef, 0x7b, 0xef, 0x7b, 0xef, 0x9b, 0xc1, 0xc7, 0x70, 0xc9, 0x92, 0x34,
- 0x06, 0x45, 0xd3, 0x4c, 0x6a, 0x49, 0x61, 0x7e, 0x2e, 0xa7, 0x0a, 0xb2, 0x8b, 0x68, 0x0e, 0xbe,
- 0x85, 0x48, 0x1b, 0x98, 0x02, 0x3f, 0x64, 0x1a, 0x3e, 0xb2, 0x85, 0xbf, 0xe1, 0x97, 0xc9, 0xd6,
- 0x71, 0x85, 0x53, 0x99, 0xea, 0x48, 0x0a, 0x45, 0x99, 0x10, 0x52, 0x33, 0x7b, 0x2f, 0x29, 0xdd,
- 0x37, 0xb8, 0x79, 0x92, 0xcc, 0x80, 0x73, 0xe0, 0xe4, 0x31, 0x6e, 0xa6, 0x99, 0x0c, 0x33, 0x50,
- 0xca, 0x43, 0x1d, 0xd4, 0xab, 0x9d, 0xee, 0x04, 0x7f, 0x11, 0xf2, 0x00, 0xbb, 0x42, 0x6a, 0xf0,
- 0x9c, 0x0e, 0xea, 0xed, 0x9d, 0xee, 0x04, 0x36, 0x1a, 0xd7, 0xb1, 0x9b, 0xb0, 0xec, 0x43, 0xf7,
- 0x37, 0xc2, 0xf7, 0xce, 0x22, 0x23, 0xfe, 0x16, 0x94, 0x62, 0x21, 0x90, 0xfb, 0xd8, 0x89, 0xb8,
- 0xed, 0xb3, 0x17, 0x38, 0x11, 0x27, 0x07, 0xb8, 0x26, 0xf2, 0xc4, 0x96, 0xd7, 0x02, 0x73, 0x25,
- 0x6d, 0xdc, 0x8c, 0x23, 0x01, 0x53, 0x03, 0xd7, 0x2a, 0xbd, 0x86, 0x41, 0xde, 0xe5, 0x89, 0x91,
- 0x8b, 0x99, 0x08, 0x3d, 0x77, 0x23, 0x67, 0x22, 0xf2, 0x0a, 0xd7, 0x95, 0x66, 0x3a, 0x57, 0xde,
- 0x6e, 0x07, 0xf5, 0xf6, 0x87, 0xcf, 0xfc, 0x2d, 0xfb, 0xfb, 0x9b, 0xcd, 0x82, 0xaa, 0x88, 0x1c,
- 0x60, 0x07, 0x84, 0x57, 0xb7, 0x5a, 0x28, 0x70, 0x40, 0x90, 0x17, 0xd8, 0x11, 0xd2, 0x6b, 0xdc,
- 0xa2, 0x99, 0x29, 0x14, 0xd2, 0x2c, 0x3e, 0x97, 0x1c, 0xc6, 0xbb, 0xb8, 0x06, 0x97, 0x7a, 0xf8,
- 0xd3, 0xc5, 0xfb, 0x27, 0xf3, 0x73, 0x79, 0x56, 0xbe, 0x0e, 0xf9, 0xe2, 0x60, 0xd7, 0xc4, 0xa4,
- 0xbf, 0xb5, 0xe9, 0x3f, 0x96, 0xb5, 0x6e, 0xc1, 0xed, 0x7e, 0x47, 0xab, 0xf5, 0xe8, 0x1b, 0xea,
- 0x3e, 0xa4, 0x17, 0x03, 0x5a, 0x31, 0xed, 0x07, 0xa1, 0x45, 0xc4, 0x97, 0x93, 0x23, 0xd2, 0xbe,
- 0x31, 0x41, 0x0b, 0x91, 0x27, 0xcb, 0xc9, 0x53, 0xd2, 0xdd, 0x92, 0xa6, 0x85, 0x31, 0x7b, 0x39,
- 0x19, 0x10, 0xfa, 0x3f, 0x6b, 0x50, 0xd1, 0x36, 0x0f, 0xb7, 0xa4, 0x45, 0xe9, 0xad, 0x6f, 0xbe,
- 0xc3, 0x8d, 0xba, 0x43, 0x5a, 0x08, 0x59, 0xa6, 0xc9, 0x27, 0x84, 0x9b, 0xc6, 0x96, 0xb1, 0xe4,
- 0x8b, 0x3b, 0xb3, 0xe6, 0xc9, 0x6a, 0x3d, 0x6a, 0x5d, 0x37, 0x66, 0x3a, 0x93, 0x7c, 0xf1, 0x12,
- 0xf5, 0xc9, 0x67, 0x84, 0xb1, 0x19, 0xe2, 0x35, 0xc4, 0xa0, 0xe1, 0xce, 0xc6, 0x38, 0x5a, 0xad,
- 0x47, 0x8f, 0xfa, 0x87, 0xd7, 0xc6, 0xe0, 0x56, 0xb6, 0xd5, 0xfe, 0xb5, 0x1e, 0x1d, 0x36, 0x7f,
- 0x7c, 0xbd, 0xba, 0x6a, 0x10, 0x37, 0xcc, 0xd2, 0x79, 0xab, 0xc1, 0xe1, 0x3d, 0xcb, 0x63, 0xdd,
- 0x41, 0xe3, 0xc6, 0x64, 0xd7, 0xb6, 0x9c, 0xd5, 0xed, 0xf1, 0xfc, 0x4f, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x35, 0x06, 0x8b, 0xf6, 0x0b, 0x04, 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
-
-// EchoServiceClient is the client API for EchoService service.
-//
-// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
-type EchoServiceClient interface {
- Echo(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error)
- EchoBody(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error)
- EchoDelete(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error)
-}
-
-type echoServiceClient struct {
- cc *grpc.ClientConn
-}
-
-func NewEchoServiceClient(cc *grpc.ClientConn) EchoServiceClient {
- return &echoServiceClient{cc}
-}
-
-func (c *echoServiceClient) Echo(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error) {
- out := new(SimpleMessage)
- err := c.cc.Invoke(ctx, "/ease.gateway.examples.proto.EchoService/Echo", in, out, opts...)
- if err != nil {
- return nil, err
- }
- return out, nil
-}
-
-func (c *echoServiceClient) EchoBody(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error) {
- out := new(SimpleMessage)
- err := c.cc.Invoke(ctx, "/ease.gateway.examples.proto.EchoService/EchoBody", in, out, opts...)
- if err != nil {
- return nil, err
- }
- return out, nil
-}
-
-func (c *echoServiceClient) EchoDelete(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error) {
- out := new(SimpleMessage)
- err := c.cc.Invoke(ctx, "/ease.gateway.examples.proto.EchoService/EchoDelete", in, out, opts...)
- if err != nil {
- return nil, err
- }
- return out, nil
-}
-
-// EchoServiceServer is the server API for EchoService service.
-type EchoServiceServer interface {
- Echo(context.Context, *SimpleMessage) (*SimpleMessage, error)
- EchoBody(context.Context, *SimpleMessage) (*SimpleMessage, error)
- EchoDelete(context.Context, *SimpleMessage) (*SimpleMessage, error)
-}
-
-func RegisterEchoServiceServer(s *grpc.Server, srv EchoServiceServer) {
- s.RegisterService(&_EchoService_serviceDesc, srv)
-}
-
-func _EchoService_Echo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
- in := new(SimpleMessage)
- if err := dec(in); err != nil {
- return nil, err
- }
- if interceptor == nil {
- return srv.(EchoServiceServer).Echo(ctx, in)
- }
- info := &grpc.UnaryServerInfo{
- Server: srv,
- FullMethod: "/ease.gateway.examples.proto.EchoService/Echo",
- }
- handler := func(ctx context.Context, req interface{}) (interface{}, error) {
- return srv.(EchoServiceServer).Echo(ctx, req.(*SimpleMessage))
- }
- return interceptor(ctx, in, info, handler)
-}
-
-func _EchoService_EchoBody_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
- in := new(SimpleMessage)
- if err := dec(in); err != nil {
- return nil, err
- }
- if interceptor == nil {
- return srv.(EchoServiceServer).EchoBody(ctx, in)
- }
- info := &grpc.UnaryServerInfo{
- Server: srv,
- FullMethod: "/ease.gateway.examples.proto.EchoService/EchoBody",
- }
- handler := func(ctx context.Context, req interface{}) (interface{}, error) {
- return srv.(EchoServiceServer).EchoBody(ctx, req.(*SimpleMessage))
- }
- return interceptor(ctx, in, info, handler)
-}
-
-func _EchoService_EchoDelete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
- in := new(SimpleMessage)
- if err := dec(in); err != nil {
- return nil, err
- }
- if interceptor == nil {
- return srv.(EchoServiceServer).EchoDelete(ctx, in)
- }
- info := &grpc.UnaryServerInfo{
- Server: srv,
- FullMethod: "/ease.gateway.examples.proto.EchoService/EchoDelete",
- }
- handler := func(ctx context.Context, req interface{}) (interface{}, error) {
- return srv.(EchoServiceServer).EchoDelete(ctx, req.(*SimpleMessage))
- }
- return interceptor(ctx, in, info, handler)
-}
-
-var _EchoService_serviceDesc = grpc.ServiceDesc{
- ServiceName: "ease.gateway.examples.proto.EchoService",
- HandlerType: (*EchoServiceServer)(nil),
- Methods: []grpc.MethodDesc{
- {
- MethodName: "Echo",
- Handler: _EchoService_Echo_Handler,
- },
- {
- MethodName: "EchoBody",
- Handler: _EchoService_EchoBody_Handler,
- },
- {
- MethodName: "EchoDelete",
- Handler: _EchoService_EchoDelete_Handler,
- },
- },
- Streams: []grpc.StreamDesc{},
- Metadata: "examples/proto/echo_service.proto",
-}
diff --git a/examples/proto/echo_service.pb.gw.go b/examples/proto/echo_service.pb.gw.go
deleted file mode 100755
index 15fa4c1..0000000
--- a/examples/proto/echo_service.pb.gw.go
+++ /dev/null
@@ -1,869 +0,0 @@
-// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
-// source: examples/proto/echo_service.proto
-
-/*
-Package proto is a reverse proxy.
-
-It translates gRPC into RESTful JSON APIs.
-*/
-package proto
-
-import (
- "context"
- "io"
- "net/http"
- "regexp"
- "strings"
- "sync"
- "unicode/utf8"
-
- "github.com/binchencoder/ease-gateway/gateway/runtime"
- vexpb "github.com/binchencoder/gateway-proto/data"
- fpb "github.com/binchencoder/gateway-proto/frontend"
- lgr "github.com/binchencoder/letsgo/grpc"
- "github.com/binchencoder/skylb-api/balancer"
- "github.com/binchencoder/skylb-api/client"
- "github.com/binchencoder/skylb-api/client/option"
- skypb "github.com/binchencoder/skylb-api/proto"
- "github.com/golang/protobuf/proto"
- "github.com/grpc-ecosystem/grpc-gateway/utilities"
- "google.golang.org/grpc"
- "google.golang.org/grpc/codes"
- "google.golang.org/grpc/naming"
- "google.golang.org/grpc/status"
-)
-
-var _ codes.Code
-var _ io.Reader
-var _ status.Status
-var _ = runtime.String
-var _ = utilities.NewDoubleArray
-var _ sync.RWMutex
-var _ proto.Message
-var _ context.Context
-var _ grpc.ClientConn
-var _ client.ServiceCli
-var _ vexpb.ServiceId
-var _ = http.MethodGet
-var _ regexp.Regexp
-var _ = balancer.ConsistentHashing
-var _ option.BalancerCreator
-var _ naming.Resolver
-var _ strings.Reader
-var _ = utf8.UTFMax
-
-// TODO (jiezmo): check if there is any rule before create this var.
-var examples_proto_echo_service_error = lgr.ToGrpcError(codes.InvalidArgument, &fpb.Error{Code: fpb.ErrorCode_BADPARAM_ERROR, Params: []string{"Validation error"}})
-
-// Validation methods start
-
-// Validation methods done
-
-var (
- filter_EchoService_Echo_0 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
-)
-
-func request_EchoService_Echo_0(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
- var protoReq SimpleMessage
- var metadata runtime.ServerMetadata
- spec := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec
-
- var (
- val string
- ok bool
- err error
- _ = err
- )
-
- val, ok = pathParams["id"]
- if !ok {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
- }
-
- protoReq.Id, err = runtime.String(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
- }
-
- if err := req.ParseForm(); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
- if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_Echo_0); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
-
- // Only hook up for non-stream call for now.
-
- runtime.RequestParsed(ctx, spec, "EchoService", "Echo", &protoReq, &metadata)
- ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
- msg, err := client.Echo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", msg, &metadata, err)
- return msg, metadata, err
-
-}
-
-var (
- filter_EchoService_Echo_1 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0, "num": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}}
-)
-
-func request_EchoService_Echo_1(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
- var protoReq SimpleMessage
- var metadata runtime.ServerMetadata
- spec := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec
-
- var (
- val string
- ok bool
- err error
- _ = err
- )
-
- val, ok = pathParams["id"]
- if !ok {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
- }
-
- protoReq.Id, err = runtime.String(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
- }
-
- val, ok = pathParams["num"]
- if !ok {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "num")
- }
-
- protoReq.Num, err = runtime.Int64(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "num", err)
- }
-
- if err := req.ParseForm(); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
- if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_Echo_1); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
-
- // Only hook up for non-stream call for now.
-
- runtime.RequestParsed(ctx, spec, "EchoService", "Echo", &protoReq, &metadata)
- ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
- msg, err := client.Echo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", msg, &metadata, err)
- return msg, metadata, err
-
-}
-
-var (
- filter_EchoService_Echo_2 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0, "num": 1, "lang": 2}, Base: []int{1, 1, 2, 3, 0, 0, 0}, Check: []int{0, 1, 1, 1, 2, 3, 4}}
-)
-
-func request_EchoService_Echo_2(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
- var protoReq SimpleMessage
- var metadata runtime.ServerMetadata
- spec := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec
-
- var (
- val string
- ok bool
- err error
- _ = err
- )
-
- val, ok = pathParams["id"]
- if !ok {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
- }
-
- protoReq.Id, err = runtime.String(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
- }
-
- val, ok = pathParams["num"]
- if !ok {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "num")
- }
-
- protoReq.Num, err = runtime.Int64(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "num", err)
- }
-
- val, ok = pathParams["lang"]
- if !ok {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "lang")
- }
-
- if protoReq.Code == nil {
- protoReq.Code = &SimpleMessage_Lang{}
- } else if _, ok := protoReq.Code.(*SimpleMessage_Lang); !ok {
- return nil, metadata, grpc.Errorf(codes.InvalidArgument, "expect type: *SimpleMessage_Lang, but: %t\n", protoReq.Code)
- }
- protoReq.Code.(*SimpleMessage_Lang).Lang, err = runtime.String(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "lang", err)
- }
-
- if err := req.ParseForm(); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
- if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_Echo_2); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
-
- // Only hook up for non-stream call for now.
-
- runtime.RequestParsed(ctx, spec, "EchoService", "Echo", &protoReq, &metadata)
- ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
- msg, err := client.Echo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", msg, &metadata, err)
- return msg, metadata, err
-
-}
-
-var (
- filter_EchoService_Echo_3 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0, "line_num": 1, "status": 2, "note": 3}, Base: []int{1, 1, 2, 1, 3, 0, 0, 0}, Check: []int{0, 1, 1, 1, 4, 2, 3, 5}}
-)
-
-func request_EchoService_Echo_3(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
- var protoReq SimpleMessage
- var metadata runtime.ServerMetadata
- spec := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec
-
- var (
- val string
- ok bool
- err error
- _ = err
- )
-
- val, ok = pathParams["id"]
- if !ok {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
- }
-
- protoReq.Id, err = runtime.String(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
- }
-
- val, ok = pathParams["line_num"]
- if !ok {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "line_num")
- }
-
- if protoReq.Code == nil {
- protoReq.Code = &SimpleMessage_LineNum{}
- } else if _, ok := protoReq.Code.(*SimpleMessage_LineNum); !ok {
- return nil, metadata, grpc.Errorf(codes.InvalidArgument, "expect type: *SimpleMessage_LineNum, but: %t\n", protoReq.Code)
- }
- protoReq.Code.(*SimpleMessage_LineNum).LineNum, err = runtime.Int64(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "line_num", err)
- }
-
- val, ok = pathParams["status.note"]
- if !ok {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "status.note")
- }
-
- err = runtime.PopulateFieldFromPath(&protoReq, "status.note", val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "status.note", err)
- }
-
- if err := req.ParseForm(); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
- if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_Echo_3); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
-
- // Only hook up for non-stream call for now.
-
- runtime.RequestParsed(ctx, spec, "EchoService", "Echo", &protoReq, &metadata)
- ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
- msg, err := client.Echo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", msg, &metadata, err)
- return msg, metadata, err
-
-}
-
-var (
- filter_EchoService_Echo_4 = &utilities.DoubleArray{Encoding: map[string]int{"no": 0, "note": 1}, Base: []int{1, 1, 1, 0}, Check: []int{0, 1, 2, 3}}
-)
-
-func request_EchoService_Echo_4(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
- var protoReq SimpleMessage
- var metadata runtime.ServerMetadata
- spec := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec
-
- var (
- val string
- ok bool
- err error
- _ = err
- )
-
- val, ok = pathParams["no.note"]
- if !ok {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "no.note")
- }
-
- err = runtime.PopulateFieldFromPath(&protoReq, "no.note", val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "no.note", err)
- }
-
- if err := req.ParseForm(); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
- if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_Echo_4); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
-
- // Only hook up for non-stream call for now.
-
- runtime.RequestParsed(ctx, spec, "EchoService", "Echo", &protoReq, &metadata)
- ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
- msg, err := client.Echo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", msg, &metadata, err)
- return msg, metadata, err
-
-}
-
-func request_EchoService_EchoBody_0(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
- var protoReq SimpleMessage
- var metadata runtime.ServerMetadata
- spec := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec
-
- newReader, berr := utilities.IOReaderFactory(req.Body)
- if berr != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
- }
- if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
- runtime.RequestHandled(ctx, spec, "EchoService", "EchoBody", nil, &metadata, err)
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
-
- // Only hook up for non-stream call for now.
-
- runtime.RequestParsed(ctx, spec, "EchoService", "EchoBody", &protoReq, &metadata)
- ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
- msg, err := client.EchoBody(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
- runtime.RequestHandled(ctx, spec, "EchoService", "EchoBody", msg, &metadata, err)
- return msg, metadata, err
-
-}
-
-var (
- filter_EchoService_EchoDelete_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
-)
-
-func request_EchoService_EchoDelete_0(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
- var protoReq SimpleMessage
- var metadata runtime.ServerMetadata
- spec := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec
-
- if err := req.ParseForm(); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
- if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_EchoDelete_0); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
-
- // Only hook up for non-stream call for now.
-
- runtime.RequestParsed(ctx, spec, "EchoService", "EchoDelete", &protoReq, &metadata)
- ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
- msg, err := client.EchoDelete(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
- runtime.RequestHandled(ctx, spec, "EchoService", "EchoDelete", msg, &metadata, err)
- return msg, metadata, err
-
-}
-
-// Register itself to runtime.
-func init() {
- var s *runtime.Service
- var spec *skypb.ServiceSpec
-
- _ = s
- _ = spec
-
- spec = internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec
- s = &runtime.Service{
- Spec: *spec,
- Name: "EchoService",
- Register: RegisterEchoServiceHandlerFromEndpoint,
- Enable: EnableEchoService_Service,
- Disable: DisableEchoService_Service,
- }
-
- runtime.AddService(s, Enable_CUSTOM_EASE_GATEWAY_TEST__default__grpc_ServiceGroup, Disable_CUSTOM_EASE_GATEWAY_TEST__default__grpc_ServiceGroup)
-
-}
-
-// RegisterEchoServiceHandlerFromEndpoint is same as RegisterEchoServiceHandler but
-// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
-func RegisterEchoServiceHandlerFromEndpoint(mux *runtime.ServeMux) (err error) {
- // conn, err := grpc.Dial(endpoint, opts...)
- // if err != nil {
- // return err
- // }
- // defer func() {
- // if err != nil {
- // if cerr := conn.Close(); cerr != nil {
- // grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
- // }
- // return
- // }
- // go func() {
- // <-ctx.Done()
- // if cerr := conn.Close(); cerr != nil {
- // grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
- // }
- // }()
- // }()
-
- // return RegisterEchoServiceHandler(ctx, mux, conn)
- return RegisterEchoServiceHandler(nil, mux, nil)
-}
-
-// RegisterEchoServiceHandler registers the http handlers for service EchoService to "mux".
-// The handlers forward requests to the grpc endpoint over "conn".
-func RegisterEchoServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
- return RegisterEchoServiceHandlerClient(ctx, mux, NewEchoServiceClient(conn))
-}
-
-// RegisterEchoServiceHandlerClient registers the http handlers for service EchoService
-// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "EchoServiceClient".
-// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "EchoServiceClient"
-// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
-// "EchoServiceClient" to call the correct interceptors.
-func RegisterEchoServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client EchoServiceClient) error {
- spec := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec
-
- runtime.AddMethod(spec, "EchoService", "Echo", "/v1/example/echo/{id}", "POST", true, false, false, "UNSPECIFIED", "EASE_GATEWAY", "EASE_AUTH_TOKEN", "")
- mux.Handle("POST", pattern_EchoService_Echo_0, vexpb.ServiceId_CUSTOM_EASE_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
- // TODO(mojz): review all locking/unlocking logic.
- // internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RLock()
- // defer internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RUnlock()
- cli := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_client
- if cli == nil {
- runtime.DefaultOtherErrorHandler(w, req, "service disabled", http.StatusInternalServerError)
- return
- }
-
- ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec, "EchoService", "Echo", w, req)
- if err != nil {
- runtime.DefaultHTTPError(ctx, nil, &runtime.JSONBuiltin{}, w, req, err)
- return
- }
-
- ctx, cancel := context.WithCancel(req.Context())
- defer cancel()
- if cn, ok := w.(http.CloseNotifier); ok {
- go func(done <-chan struct{}, closed <-chan bool) {
- select {
- case <-done:
- case <-closed:
- cancel()
- }
- }(ctx.Done(), cn.CloseNotify())
- }
- inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
- rctx, err := runtime.AnnotateContext(ctx, mux, req)
- if err != nil {
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
- resp, md, err := request_EchoService_Echo_0(rctx, inboundMarshaler, cli, req, pathParams)
- ctx = runtime.NewServerMetadataContext(ctx, md)
- if err != nil {
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
-
- forward_EchoService_Echo_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
- })
-
- runtime.AddMethod(spec, "EchoService", "Echo", "/v1/example/echo/{id}/{num}", "GET", true, false, false, "UNSPECIFIED", "EASE_GATEWAY", "EASE_AUTH_TOKEN", "")
- mux.Handle("GET", pattern_EchoService_Echo_1, vexpb.ServiceId_CUSTOM_EASE_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
- // TODO(mojz): review all locking/unlocking logic.
- // internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RLock()
- // defer internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RUnlock()
- cli := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_client
- if cli == nil {
- runtime.DefaultOtherErrorHandler(w, req, "service disabled", http.StatusInternalServerError)
- return
- }
-
- ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec, "EchoService", "Echo", w, req)
- if err != nil {
- runtime.DefaultHTTPError(ctx, nil, &runtime.JSONBuiltin{}, w, req, err)
- return
- }
-
- ctx, cancel := context.WithCancel(req.Context())
- defer cancel()
- if cn, ok := w.(http.CloseNotifier); ok {
- go func(done <-chan struct{}, closed <-chan bool) {
- select {
- case <-done:
- case <-closed:
- cancel()
- }
- }(ctx.Done(), cn.CloseNotify())
- }
- inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
- rctx, err := runtime.AnnotateContext(ctx, mux, req)
- if err != nil {
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
- resp, md, err := request_EchoService_Echo_1(rctx, inboundMarshaler, cli, req, pathParams)
- ctx = runtime.NewServerMetadataContext(ctx, md)
- if err != nil {
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
-
- forward_EchoService_Echo_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
- })
-
- runtime.AddMethod(spec, "EchoService", "Echo", "/v1/example/echo/{id}/{num}/{lang}", "GET", true, false, false, "UNSPECIFIED", "EASE_GATEWAY", "EASE_AUTH_TOKEN", "")
- mux.Handle("GET", pattern_EchoService_Echo_2, vexpb.ServiceId_CUSTOM_EASE_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
- // TODO(mojz): review all locking/unlocking logic.
- // internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RLock()
- // defer internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RUnlock()
- cli := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_client
- if cli == nil {
- runtime.DefaultOtherErrorHandler(w, req, "service disabled", http.StatusInternalServerError)
- return
- }
-
- ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec, "EchoService", "Echo", w, req)
- if err != nil {
- runtime.DefaultHTTPError(ctx, nil, &runtime.JSONBuiltin{}, w, req, err)
- return
- }
-
- ctx, cancel := context.WithCancel(req.Context())
- defer cancel()
- if cn, ok := w.(http.CloseNotifier); ok {
- go func(done <-chan struct{}, closed <-chan bool) {
- select {
- case <-done:
- case <-closed:
- cancel()
- }
- }(ctx.Done(), cn.CloseNotify())
- }
- inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
- rctx, err := runtime.AnnotateContext(ctx, mux, req)
- if err != nil {
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
- resp, md, err := request_EchoService_Echo_2(rctx, inboundMarshaler, cli, req, pathParams)
- ctx = runtime.NewServerMetadataContext(ctx, md)
- if err != nil {
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
-
- forward_EchoService_Echo_2(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
- })
-
- runtime.AddMethod(spec, "EchoService", "Echo", "/v1/example/echo1/{id}/{line_num}/{status.note}", "GET", true, false, false, "UNSPECIFIED", "EASE_GATEWAY", "EASE_AUTH_TOKEN", "")
- mux.Handle("GET", pattern_EchoService_Echo_3, vexpb.ServiceId_CUSTOM_EASE_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
- // TODO(mojz): review all locking/unlocking logic.
- // internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RLock()
- // defer internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RUnlock()
- cli := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_client
- if cli == nil {
- runtime.DefaultOtherErrorHandler(w, req, "service disabled", http.StatusInternalServerError)
- return
- }
-
- ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec, "EchoService", "Echo", w, req)
- if err != nil {
- runtime.DefaultHTTPError(ctx, nil, &runtime.JSONBuiltin{}, w, req, err)
- return
- }
-
- ctx, cancel := context.WithCancel(req.Context())
- defer cancel()
- if cn, ok := w.(http.CloseNotifier); ok {
- go func(done <-chan struct{}, closed <-chan bool) {
- select {
- case <-done:
- case <-closed:
- cancel()
- }
- }(ctx.Done(), cn.CloseNotify())
- }
- inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
- rctx, err := runtime.AnnotateContext(ctx, mux, req)
- if err != nil {
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
- resp, md, err := request_EchoService_Echo_3(rctx, inboundMarshaler, cli, req, pathParams)
- ctx = runtime.NewServerMetadataContext(ctx, md)
- if err != nil {
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
-
- forward_EchoService_Echo_3(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
- })
-
- runtime.AddMethod(spec, "EchoService", "Echo", "/v1/example/echo2/{no.note}", "GET", true, false, false, "UNSPECIFIED", "EASE_GATEWAY", "EASE_AUTH_TOKEN", "")
- mux.Handle("GET", pattern_EchoService_Echo_4, vexpb.ServiceId_CUSTOM_EASE_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
- // TODO(mojz): review all locking/unlocking logic.
- // internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RLock()
- // defer internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RUnlock()
- cli := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_client
- if cli == nil {
- runtime.DefaultOtherErrorHandler(w, req, "service disabled", http.StatusInternalServerError)
- return
- }
-
- ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec, "EchoService", "Echo", w, req)
- if err != nil {
- runtime.DefaultHTTPError(ctx, nil, &runtime.JSONBuiltin{}, w, req, err)
- return
- }
-
- ctx, cancel := context.WithCancel(req.Context())
- defer cancel()
- if cn, ok := w.(http.CloseNotifier); ok {
- go func(done <-chan struct{}, closed <-chan bool) {
- select {
- case <-done:
- case <-closed:
- cancel()
- }
- }(ctx.Done(), cn.CloseNotify())
- }
- inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
- rctx, err := runtime.AnnotateContext(ctx, mux, req)
- if err != nil {
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
- resp, md, err := request_EchoService_Echo_4(rctx, inboundMarshaler, cli, req, pathParams)
- ctx = runtime.NewServerMetadataContext(ctx, md)
- if err != nil {
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
-
- forward_EchoService_Echo_4(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
- })
-
- runtime.AddMethod(spec, "EchoService", "EchoBody", "/v1/example/echo_body", "POST", true, false, false, "UNSPECIFIED", "EASE_GATEWAY", "EASE_AUTH_TOKEN", "")
- mux.Handle("POST", pattern_EchoService_EchoBody_0, vexpb.ServiceId_CUSTOM_EASE_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
- // TODO(mojz): review all locking/unlocking logic.
- // internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RLock()
- // defer internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RUnlock()
- cli := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_client
- if cli == nil {
- runtime.DefaultOtherErrorHandler(w, req, "service disabled", http.StatusInternalServerError)
- return
- }
-
- ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec, "EchoService", "EchoBody", w, req)
- if err != nil {
- runtime.DefaultHTTPError(ctx, nil, &runtime.JSONBuiltin{}, w, req, err)
- return
- }
-
- ctx, cancel := context.WithCancel(req.Context())
- defer cancel()
- if cn, ok := w.(http.CloseNotifier); ok {
- go func(done <-chan struct{}, closed <-chan bool) {
- select {
- case <-done:
- case <-closed:
- cancel()
- }
- }(ctx.Done(), cn.CloseNotify())
- }
- inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
- rctx, err := runtime.AnnotateContext(ctx, mux, req)
- if err != nil {
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
- resp, md, err := request_EchoService_EchoBody_0(rctx, inboundMarshaler, cli, req, pathParams)
- ctx = runtime.NewServerMetadataContext(ctx, md)
- if err != nil {
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
-
- forward_EchoService_EchoBody_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
- })
-
- runtime.AddMethod(spec, "EchoService", "EchoDelete", "/v1/example/echo_delete", "DELETE", true, false, false, "UNSPECIFIED", "EASE_GATEWAY", "EASE_AUTH_TOKEN", "")
- mux.Handle("DELETE", pattern_EchoService_EchoDelete_0, vexpb.ServiceId_CUSTOM_EASE_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
- // TODO(mojz): review all locking/unlocking logic.
- // internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RLock()
- // defer internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RUnlock()
- cli := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_client
- if cli == nil {
- runtime.DefaultOtherErrorHandler(w, req, "service disabled", http.StatusInternalServerError)
- return
- }
-
- ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec, "EchoService", "EchoDelete", w, req)
- if err != nil {
- runtime.DefaultHTTPError(ctx, nil, &runtime.JSONBuiltin{}, w, req, err)
- return
- }
-
- ctx, cancel := context.WithCancel(req.Context())
- defer cancel()
- if cn, ok := w.(http.CloseNotifier); ok {
- go func(done <-chan struct{}, closed <-chan bool) {
- select {
- case <-done:
- case <-closed:
- cancel()
- }
- }(ctx.Done(), cn.CloseNotify())
- }
- inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
- rctx, err := runtime.AnnotateContext(ctx, mux, req)
- if err != nil {
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
- resp, md, err := request_EchoService_EchoDelete_0(rctx, inboundMarshaler, cli, req, pathParams)
- ctx = runtime.NewServerMetadataContext(ctx, md)
- if err != nil {
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
-
- forward_EchoService_EchoDelete_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
- })
-
- return nil
-}
-
-func Disable_CUSTOM_EASE_GATEWAY_TEST__default__grpc_ServiceGroup() {
- // internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.Lock()
- // defer internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.Unlock()
- if internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_skycli != nil {
- spec := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec
- sg := runtime.GetServiceGroup(spec)
- for _, svc := range sg.Services {
- svc.Disable()
- }
-
- internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_client = nil
- internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_skycli.Shutdown()
- internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_skycli = nil
- }
-}
-
-func Enable_CUSTOM_EASE_GATEWAY_TEST__default__grpc_ServiceGroup() {
- // internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.Lock()
- // defer internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.Unlock()
-
- internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_skycli = client.NewServiceCli(runtime.CallerServiceId)
-
- // Resolve service
- spec := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec
-
- internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_skycli.Resolve(spec)
-
- internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_skycli.EnableResolveFullEps()
- internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_skycli.Start(func(spec *skypb.ServiceSpec, conn *grpc.ClientConn) {
- sg := runtime.GetServiceGroup(spec)
- for _, svc := range sg.Services {
- svc.Enable(spec, conn)
- }
- })
-}
-
-func EnableEchoService_Service(spec *skypb.ServiceSpec, conn *grpc.ClientConn) {
- internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_client = NewEchoServiceClient(conn)
-}
-
-func DisableEchoService_Service() {
- internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_client = nil
-}
-
-var (
- pattern_EchoService_Echo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "example", "echo", "id"}, "", runtime.AssumeColonVerbOpt(true)))
-
- pattern_EchoService_Echo_1 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4}, []string{"v1", "example", "echo", "id", "num"}, "", runtime.AssumeColonVerbOpt(true)))
-
- pattern_EchoService_Echo_2 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"v1", "example", "echo", "id", "num", "lang"}, "", runtime.AssumeColonVerbOpt(true)))
-
- pattern_EchoService_Echo_3 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"v1", "example", "echo1", "id", "line_num", "status.note"}, "", runtime.AssumeColonVerbOpt(true)))
-
- pattern_EchoService_Echo_4 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "example", "echo2", "no.note"}, "", runtime.AssumeColonVerbOpt(true)))
-
- pattern_EchoService_EchoBody_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "example", "echo_body"}, "", runtime.AssumeColonVerbOpt(true)))
-
- pattern_EchoService_EchoDelete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "example", "echo_delete"}, "", runtime.AssumeColonVerbOpt(true)))
-)
-
-var (
- forward_EchoService_Echo_0 = runtime.ForwardResponseMessage
-
- forward_EchoService_Echo_1 = runtime.ForwardResponseMessage
-
- forward_EchoService_Echo_2 = runtime.ForwardResponseMessage
-
- forward_EchoService_Echo_3 = runtime.ForwardResponseMessage
-
- forward_EchoService_Echo_4 = runtime.ForwardResponseMessage
-
- forward_EchoService_EchoBody_0 = runtime.ForwardResponseMessage
-
- forward_EchoService_EchoDelete_0 = runtime.ForwardResponseMessage
-)
-
-var (
- internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec = client.NewServiceSpec("default", vexpb.ServiceId_CUSTOM_EASE_GATEWAY_TEST, "grpc")
- internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_client EchoServiceClient
-
- internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_skycli client.ServiceCli
-
- internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock = sync.RWMutex{}
-)
diff --git a/examples/proto/echo_service.proto b/examples/proto/echo_service.proto
deleted file mode 100644
index 75777b1..0000000
--- a/examples/proto/echo_service.proto
+++ /dev/null
@@ -1,80 +0,0 @@
-syntax = "proto3";
-option go_package = "proto";
-
-// Echo Service
-//
-// Echo Service API consists of a single service which returns
-// a message.
-package ease.gateway.examples.proto;
-
-// import "google/api/annotations.proto";
-import "httpoptions/annotations.proto";
-
-// Embedded represents a message embedded in SimpleMessage.
-message Embedded {
- oneof mark {
- int64 progress = 1;
- string note = 2;
- }
-}
-
-// SimpleMessage represents a simple message sent to the Echo service.
-message SimpleMessage {
- // Id represents the message identifier.
- string id = 1;
- int64 num = 2;
- oneof code {
- int64 line_num = 3;
- string lang = 4;
- }
- Embedded status = 5;
- oneof ext {
- int64 en = 6;
- Embedded no = 7;
- }
-}
-
-// Echo service responds to incoming echo requests.
-service EchoService {
- option (ease.api.service_spec) = {
- service_id: CUSTOM_EASE_GATEWAY_TEST
- port_name : "grpc"
- namespace : "default"
- gen_controller: true
- };
-
- // Echo method receives a simple message and returns it.
- //
- // The message posted as the id parameter will also be
- // returned.
- rpc Echo(SimpleMessage) returns (SimpleMessage) {
- option (ease.api.http) = {
- post: "/v1/example/echo/{id}"
- additional_bindings {
- get: "/v1/example/echo/{id}/{num}"
- }
- additional_bindings {
- get: "/v1/example/echo/{id}/{num}/{lang}"
- }
- additional_bindings {
- get: "/v1/example/echo1/{id}/{line_num}/{status.note}"
- }
- additional_bindings {
- get: "/v1/example/echo2/{no.note}"
- }
- };
- }
- // EchoBody method receives a simple message and returns it.
- rpc EchoBody(SimpleMessage) returns (SimpleMessage) {
- option (ease.api.http) = {
- post: "/v1/example/echo_body"
- body: "*"
- };
- }
- // EchoDelete method receives a simple message and returns it.
- rpc EchoDelete(SimpleMessage) returns (SimpleMessage) {
- option (ease.api.http) = {
- delete: "/v1/example/echo_delete"
- };
- }
-}
diff --git a/examples/server/BUILD.bazel b/examples/server/BUILD.bazel
deleted file mode 100644
index 8de0df1..0000000
--- a/examples/server/BUILD.bazel
+++ /dev/null
@@ -1,18 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library")
-
-package(default_visibility = ["//visibility:public"])
-
-go_library(
- name = "go_default_library",
- srcs = [
- "echo.go",
- "main.go",
- ],
- importpath = "github.com/binchencoder/ease-gateway/examples/server",
- deps = [
- "//examples/proto:go_default_library",
- "@com_github_golang_glog//:go_default_library",
- "@org_golang_google_grpc//:go_default_library",
- "@org_golang_google_grpc//metadata:go_default_library",
- ],
-)
diff --git a/examples/server/main.go b/examples/server/main.go
deleted file mode 100644
index dd12155..0000000
--- a/examples/server/main.go
+++ /dev/null
@@ -1,33 +0,0 @@
-package server
-
-import (
- "context"
- "net"
-
- examples "github.com/binchencoder/ease-gateway/examples/proto"
- "github.com/golang/glog"
- "google.golang.org/grpc"
-)
-
-// Run starts the example gRPC service.
-// "network" and "address" are passed to net.Listen.
-func Run(ctx context.Context, network, address string) error {
- l, err := net.Listen(network, address)
- if err != nil {
- return err
- }
- defer func() {
- if err := l.Close(); err != nil {
- glog.Errorf("Failed to close %s %s: %v", network, address, err)
- }
- }()
-
- s := grpc.NewServer()
- examples.RegisterEchoServiceServer(s, NewEchoServer())
-
- go func() {
- defer s.GracefulStop()
- <-ctx.Done()
- }()
- return s.Serve(l)
-}
diff --git a/gateway/HISTORY.md b/gateway/HISTORY.md
index 1cfc441..633565c 100644
--- a/gateway/HISTORY.md
+++ b/gateway/HISTORY.md
@@ -9,6 +9,22 @@ Hosted on https://github.com/grpc-ecosystem/grpc-gateway.
## Update History
+### 2020/05/25
+
+Based on commit ID [58a91c2b3020ee25e5d3cf49cf7d342544ab773d](https://github.com/grpc-ecosystem/grpc-gateway/commit/7988867d3206f7e90ca3e8d4ab67e060734a297a)
+
+Commit message
+
+```
+commit 7988867d3206f7e90ca3e8d4ab67e060734a297a (HEAD, tag: v2.0.0-beta.2, tag: v1.14.6)
+Author: Johan Brandhorst
+Date: Mon May 25 11:42:27 2020 +0100
+
+ Generate changelog for 1.14.6
+
+ Fixed the issue where it would include v2 merges
+```
+
### 2019/11/03
Based on commit ID 58a91c2b3020ee25e5d3cf49cf7d342544ab773d
@@ -53,7 +69,7 @@ Pull message
更新 fdf0635..b6e6efb
Fast-forward
docs/_docs/customizingyourgateway.md | 22 ++++++++++++++++++++++
- protoc-gen-swagger/genswagger/BUILD.bazel | 1 +
- protoc-gen-swagger/genswagger/template.go | 34 +++++++++++++++++++++++++++++-----
- protoc-gen-swagger/genswagger/template_test.go | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
+ protoc-gen-openapiv2/internal/genopenapi/BUILD.bazel | 1 +
+ protoc-gen-openapiv2/internal/genopenapi/template.go | 34 +++++++++++++++++++++++++++++-----
+ protoc-gen-openapiv2/internal/genopenapi/template_test.go | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
```
\ No newline at end of file
diff --git a/gateway/README.md b/gateway/README.md
index 031b4d9..0318594 100644
--- a/gateway/README.md
+++ b/gateway/README.md
@@ -2,28 +2,19 @@
grpc-gateway 是一款非常优秀的网关服务器,负责转化和代理转发。让```RESTful API ```和 ```gRPC```可以相互转化,这样可以实现一套```gRPC```接口提供两种接口服务(提供内部的```gRPC```服务和外部```RESTful API```服务),大大提高了开发效率。
-但是官方提供的版本还是单机版的,还不支持集群,所以并不能直接运行在生产环境中。```ease-gateway```就是为了解决这些问题应运而生的,在```grpc-gateway```的基础上增加了新的feature
+但是官方提供的版本还是单机版的,还不支持集群,所以并不能直接运行在生产环境中。```janus-gateway```就是为了解决这些问题应运而生的,在```grpc-gateway```的基础上增加了新的feature
- 支持自定义的loadbalancer
- 支持网关层的parameter validation
- 支持自定义的annotaion
-为了支持这些新feature,我不得不将grpc-gateway的源码拷贝到ease-gateway中并进行大量的修改,```//gateway``` 目录下就是从grpc-gateway中拷贝的部分源码
+为了支持这些新feature,我不得不将grpc-gateway的源码拷贝到janus-gateway中并进行大量的修改,```//gateway``` 目录下就是从grpc-gateway中拷贝的部分源码
-# 修改内容
+# Changed History
以下详细说明了我基于grpc-gateway修改了哪些目录下的代码
-## codegenerator
-
-Link [grpc-ecosystem/grpc-gateway/codegenerator](https://github.com/grpc-ecosystem/grpc-gateway/tree/master/codegenerator)
-
-这个目录下没有修改核心代码,只修改path
-
-- package default_visibility
-- import "github.com/binchencoder/ease-gateway/gateway/codegenerator" => "github.com/grpc-ecosystem/grpc-gateway/codegenerator"
-
-## options
+## httpoptions
这个目录下的内容并不是grpc-gateway的源码,是基于[Google
// APIs](https://github.com/googleapis/googleapis) 修改的,为了支持:
@@ -32,7 +23,7 @@ Link [grpc-ecosystem/grpc-gateway/codegenerator](https://github.com/grpc-ecosys
- loadbalancer
- parameter validation(定义validation rules)
-> **NOTE :** 移到根目录下 => httpoptions
+> **NOTE :** 这是新增加的目录
## protoc-gen-grpc-gateway
@@ -71,7 +62,7 @@ protoc -I/usr/local/include -I. \
- BUILD.bazel
- generator.go (只修改import path)
-### gengateway
+### internal/gengateway
**这个目录下改动比较大**, 修改文件:
@@ -81,25 +72,11 @@ protoc -I/usr/local/include -I. \
- template_test.go
- template.go
-### httprule
-
-Link [grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule](https://github.com/grpc-ecosystem/grpc-gateway/tree/master/protoc-gen-grpc-gateway/httprule)
-
-该目录下没有修改代码,直接拷贝的。原因是 grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule package visibility 只能在本项目内依赖
-
-```
-package(default_visibility = ["//:generators"])
-```
-
-修改文件:
-
-- BUILD.bazel
-
-## protoc-gen-swagger
+## protoc-gen-openapiv2
-Link [grpc-ecosystem/grpc-gateway/protoc-gen-swagger](https://github.com/grpc-ecosystem/grpc-gateway/tree/master/protoc-gen-swagger)
+Link [grpc-ecosystem/grpc-gateway/protoc-gen-openapiv2](https://github.com/grpc-ecosystem/grpc-gateway/tree/master/protoc-gen-openapiv2)
-```protoc-gen-swagger``` 是生成swagger API定义的工具
+```protoc-gen-openapiv2``` 是生成swagger API定义的工具
修改文件:
@@ -136,6 +113,8 @@ Link [grpc-ecosystem/grpc-gateway/runtime](https://github.com/grpc-ecosystem/g
- service.go
- balancer_test.go
- balancer.go
+- hook.go
+- hook_test.go
删除文件:
@@ -145,8 +124,6 @@ Link [grpc-ecosystem/grpc-gateway/runtime](https://github.com/grpc-ecosystem/g
修改文件:
-- add hook_test.go
-- add hook.go
- BUILD.bazel
- context_test.go
- error_test.go
@@ -157,6 +134,63 @@ Link [grpc-ecosystem/grpc-gateway/runtime](https://github.com/grpc-ecosystem/g
- mux.go
- query_test.go
+## Upgrade issues
+
+### 输出error.code 为字符串
+
+```
+{
+ "error": {
+ "code": "BAD_REQUEST",
+ "params": [
+ "Validation error"
+ ]
+ },
+ "code": 3,
+ "message": "{\"code\":100006,\"params\":[\"Validation error\"]}"
+}
+```
+
+> 升级之后response body中 error.code为字符串, 期望是Integer
+
+```
+{
+ "error": {
+ "code": 100006,
+ "params": [
+ "Validation error"
+ ]
+ },
+ "code": 3,
+ "message": "{\"code\":100006,\"params\":[\"Validation error\"]}"
+}
+```
+问题出在 //gateway/runtime/marshaler_registry.go 文件中, EnumsAsInts应该设置为true
+```
+var (
+ acceptHeader = http.CanonicalHeaderKey("Accept")
+ contentTypeHeader = http.CanonicalHeaderKey("Content-Type")
+
+ defaultMarshaler = &JSONPb{
+ OrigName: true,
+ EnumsAsInts: true,
+ }
+)
+```
+
+### panic: can't resolve swagger ref from typename '.frontend.Error'
+
+运行一下命令就会出现panic
+```
+bazel build proto/...
+```
+
+问题出在以下代码
+```
+runtimeError, swgRef, err := lookupMsgAndSwaggerName(".grpc.gateway.runtime", "Error", p.reg)
+```
+如果有package name定义为 grpc.gateway.runtime的就有可能会出现这种错误
+
## grpc-ecosystem/grpc-gateway
grpc-ecosystem/grpc-gateway: grpc-gateway is a plugin of protoc. It reads
diff --git a/gateway/codegenerator/BUILD.bazel b/gateway/codegenerator/BUILD.bazel
deleted file mode 100644
index a865f97..0000000
--- a/gateway/codegenerator/BUILD.bazel
+++ /dev/null
@@ -1,26 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-
-package(default_visibility = ["//visibility:public"])
-
-go_library(
- name = "go_default_library",
- srcs = [
- "doc.go",
- "parse_req.go",
- ],
- importpath = "github.com/binchencoder/ease-gateway/gateway/codegenerator",
- deps = [
- "@com_github_golang_protobuf//proto:go_default_library",
- "@io_bazel_rules_go//proto/wkt:compiler_plugin_go_proto",
- ],
-)
-
-go_test(
- name = "go_default_test",
- srcs = ["parse_req_test.go"],
- embed = [":go_default_library"],
- deps = [
- "@com_github_golang_protobuf//proto:go_default_library",
- "@io_bazel_rules_go//proto/wkt:compiler_plugin_go_proto",
- ],
-)
diff --git a/gateway/codegenerator/doc.go b/gateway/codegenerator/doc.go
deleted file mode 100644
index 3645317..0000000
--- a/gateway/codegenerator/doc.go
+++ /dev/null
@@ -1,4 +0,0 @@
-/*
-Package codegenerator contains reusable functions used by the code generators.
-*/
-package codegenerator
diff --git a/gateway/codegenerator/parse_req.go b/gateway/codegenerator/parse_req.go
deleted file mode 100644
index e74575b..0000000
--- a/gateway/codegenerator/parse_req.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package codegenerator
-
-import (
- "fmt"
- "io"
- "io/ioutil"
-
- "github.com/golang/protobuf/proto"
- plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
-)
-
-// ParseRequest parses a code generator request from a proto Message.
-func ParseRequest(r io.Reader) (*plugin.CodeGeneratorRequest, error) {
- input, err := ioutil.ReadAll(r)
- if err != nil {
- return nil, fmt.Errorf("failed to read code generator request: %v", err)
- }
- req := new(plugin.CodeGeneratorRequest)
- if err = proto.Unmarshal(input, req); err != nil {
- return nil, fmt.Errorf("failed to unmarshal code generator request: %v", err)
- }
- return req, nil
-}
diff --git a/gateway/codegenerator/parse_req_test.go b/gateway/codegenerator/parse_req_test.go
deleted file mode 100644
index 7f0da0a..0000000
--- a/gateway/codegenerator/parse_req_test.go
+++ /dev/null
@@ -1,69 +0,0 @@
-package codegenerator_test
-
-import (
- "bytes"
- "fmt"
- "io"
- "reflect"
- "strings"
- "testing"
-
- "github.com/golang/protobuf/proto"
- plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
- "github.com/binchencoder/ease-gateway/gateway/codegenerator"
-)
-
-var parseReqTests = []struct {
- name string
- in io.Reader
- out *plugin.CodeGeneratorRequest
- err error
-}{
- {
- "Empty input should produce empty output",
- mustGetReader(&plugin.CodeGeneratorRequest{}),
- &plugin.CodeGeneratorRequest{},
- nil,
- },
- {
- "Invalid reader should produce error",
- &invalidReader{},
- nil,
- fmt.Errorf("failed to read code generator request: invalid reader"),
- },
- {
- "Invalid proto message should produce error",
- strings.NewReader("{}"),
- nil,
- fmt.Errorf("failed to unmarshal code generator request: unexpected EOF"),
- },
-}
-
-func TestParseRequest(t *testing.T) {
- for _, tt := range parseReqTests {
- t.Run(tt.name, func(t *testing.T) {
- out, err := codegenerator.ParseRequest(tt.in)
- if !reflect.DeepEqual(err, tt.err) {
- t.Errorf("got %v, want %v", err, tt.err)
- }
- if err == nil && !reflect.DeepEqual(*out, *tt.out) {
- t.Errorf("got %v, want %v", *out, *tt.out)
- }
- })
- }
-}
-
-func mustGetReader(pb proto.Message) io.Reader {
- b, err := proto.Marshal(pb)
- if err != nil {
- panic(err)
- }
- return bytes.NewBuffer(b)
-}
-
-type invalidReader struct {
-}
-
-func (*invalidReader) Read(p []byte) (int, error) {
- return 0, fmt.Errorf("invalid reader")
-}
diff --git a/gateway/internal/BUILD.bazel b/gateway/internal/BUILD.bazel
new file mode 100644
index 0000000..8d84966
--- /dev/null
+++ b/gateway/internal/BUILD.bazel
@@ -0,0 +1,32 @@
+load("@rules_proto//proto:defs.bzl", "proto_library")
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
+
+package(default_visibility = ["//visibility:public"])
+
+proto_library(
+ name = "internal_proto",
+ srcs = ["errors.proto"],
+ deps = [
+ "@com_github_binchencoder_gateway_proto//frontend:error_proto",
+ "@com_google_protobuf//:any_proto",
+ ],
+)
+
+go_proto_library(
+ name = "internal_go_proto",
+ importpath = "github.com/binchencoder/janus-gateway/gateway/internal",
+ proto = ":internal_proto",
+ deps = [
+ "@com_github_binchencoder_gateway_proto//frontend:error_go_proto",
+ ]
+)
+
+go_library(
+ name = "go_default_library",
+ embed = [":internal_go_proto"],
+ importpath = "github.com/binchencoder/janus-gateway/gateway/internal",
+ deps = [
+ "@com_github_binchencoder_gateway_proto//frontend:go_default_library",
+ ]
+)
diff --git a/gateway/internal/casing/BUILD.bazel b/gateway/internal/casing/BUILD.bazel
new file mode 100644
index 0000000..5876df8
--- /dev/null
+++ b/gateway/internal/casing/BUILD.bazel
@@ -0,0 +1,14 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "casing",
+ srcs = ["camel.go"],
+ importpath = "github.com/binchencoder/janus-gateway/gateway/internal/casing",
+ visibility = ["//:__subpackages__"],
+)
+
+alias(
+ name = "go_default_library",
+ actual = ":casing",
+ visibility = ["//:__subpackages__"],
+)
diff --git a/gateway/internal/casing/LICENSE.md b/gateway/internal/casing/LICENSE.md
new file mode 100644
index 0000000..0f64693
--- /dev/null
+++ b/gateway/internal/casing/LICENSE.md
@@ -0,0 +1,28 @@
+Copyright 2010 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/gateway/internal/casing/README.md b/gateway/internal/casing/README.md
new file mode 100644
index 0000000..8811446
--- /dev/null
+++ b/gateway/internal/casing/README.md
@@ -0,0 +1,5 @@
+# Case conversion
+
+This package contains a single function, copied from the
+`github.com/golang/protobuf/protoc-gen-go/generator` package. That
+modules LICENSE is referenced in its entirety in this package.
diff --git a/gateway/internal/casing/camel.go b/gateway/internal/casing/camel.go
new file mode 100644
index 0000000..8cfef4b
--- /dev/null
+++ b/gateway/internal/casing/camel.go
@@ -0,0 +1,63 @@
+package casing
+
+// Camel returns the CamelCased name.
+//
+// This was moved from the now deprecated github.com/golang/protobuf/protoc-gen-go/generator package
+//
+// If there is an interior underscore followed by a lower case letter,
+// drop the underscore and convert the letter to upper case.
+// There is a remote possibility of this rewrite causing a name collision,
+// but it's so remote we're prepared to pretend it's nonexistent - since the
+// C++ generator lowercases names, it's extremely unlikely to have two fields
+// with different capitalizations.
+// In short, _my_field_name_2 becomes XMyFieldName_2.
+func Camel(s string) string {
+ if s == "" {
+ return ""
+ }
+ t := make([]byte, 0, 32)
+ i := 0
+ if s[0] == '_' {
+ // Need a capital letter; drop the '_'.
+ t = append(t, 'X')
+ i++
+ }
+ // Invariant: if the next letter is lower case, it must be converted
+ // to upper case.
+ // That is, we process a word at a time, where words are marked by _ or
+ // upper case letter. Digits are treated as words.
+ for ; i < len(s); i++ {
+ c := s[i]
+ if c == '_' && i+1 < len(s) && isASCIILower(s[i+1]) {
+ continue // Skip the underscore in s.
+ }
+ if isASCIIDigit(c) {
+ t = append(t, c)
+ continue
+ }
+ // Assume we have a letter now - if not, it's a bogus identifier.
+ // The next word is a sequence of characters that must start upper case.
+ if isASCIILower(c) {
+ c ^= ' ' // Make it a capital letter.
+ }
+ t = append(t, c) // Guaranteed not lower case.
+ // Accept lower case sequence that follows.
+ for i+1 < len(s) && isASCIILower(s[i+1]) {
+ i++
+ t = append(t, s[i])
+ }
+ }
+ return string(t)
+}
+
+// And now lots of helper functions.
+
+// Is c an ASCII lower-case letter?
+func isASCIILower(c byte) bool {
+ return 'a' <= c && c <= 'z'
+}
+
+// Is c an ASCII digit?
+func isASCIIDigit(c byte) bool {
+ return '0' <= c && c <= '9'
+}
diff --git a/gateway/internal/descriptor/BUILD.bazel b/gateway/internal/descriptor/BUILD.bazel
new file mode 100644
index 0000000..4f836d9
--- /dev/null
+++ b/gateway/internal/descriptor/BUILD.bazel
@@ -0,0 +1,63 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+
+package(default_visibility = ["//visibility:public"])
+
+go_library(
+ name = "descriptor",
+ srcs = [
+ "grpc_api_configuration.go",
+ "openapi_configuration.go",
+ "registry.go",
+ "services.go",
+ "types.go",
+ ],
+ importpath = "github.com/binchencoder/janus-gateway/gateway/internal/descriptor",
+ deps = [
+ "//gateway/internal/casing",
+ "@com_github_grpc_ecosystem_grpc_gateway//internal/codegenerator",
+ "//gateway/internal/descriptor/apiconfig",
+ "//gateway/internal/descriptor/openapiconfig",
+ "//httpoptions",
+ "//gateway/protoc-gen-openapiv2/options",
+
+ "@com_github_binchencoder_gateway_proto//data:go_default_library",
+ "@com_github_golang_glog//:glog",
+ "@com_github_grpc_ecosystem_grpc_gateway//internal/httprule",
+ "@go_googleapis//google/api:annotations_go_proto",
+ "@io_k8s_sigs_yaml//:yaml",
+ "@org_golang_google_protobuf//compiler/protogen",
+ "@org_golang_google_protobuf//encoding/protojson",
+ "@org_golang_google_protobuf//proto",
+ "@org_golang_google_protobuf//types/descriptorpb",
+ "@org_golang_google_protobuf//types/pluginpb",
+ ],
+)
+
+go_test(
+ name = "descriptor_test",
+ size = "small",
+ srcs = [
+ "grpc_api_configuration_test.go",
+ "openapi_configuration_test.go",
+ "registry_test.go",
+ "services_test.go",
+ "types_test.go",
+ ],
+ embed = [":descriptor"],
+ deps = [
+ "//gateway/internal/descriptor/openapiconfig",
+ "@com_github_grpc_ecosystem_grpc_gateway//internal/httprule",
+ "@com_github_grpc_ecosystem_grpc_gateway//protoc-gen-openapiv2/options",
+ "@org_golang_google_protobuf//compiler/protogen",
+ "@org_golang_google_protobuf//encoding/prototext",
+ "@org_golang_google_protobuf//proto",
+ "@org_golang_google_protobuf//types/descriptorpb",
+ "@org_golang_google_protobuf//types/pluginpb",
+ ],
+)
+
+alias(
+ name = "go_default_library",
+ actual = ":descriptor",
+ visibility = ["//:__subpackages__"],
+)
diff --git a/gateway/internal/descriptor/apiconfig/BUILD.bazel b/gateway/internal/descriptor/apiconfig/BUILD.bazel
new file mode 100644
index 0000000..2f40350
--- /dev/null
+++ b/gateway/internal/descriptor/apiconfig/BUILD.bazel
@@ -0,0 +1,35 @@
+load("@rules_proto//proto:defs.bzl", "proto_library")
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
+
+package(default_visibility = ["//visibility:public"])
+
+proto_library(
+ name = "apiconfig_proto",
+ srcs = [
+ "apiconfig.proto",
+ ],
+ deps = [
+ "//httpoptions:options_proto",
+ ],
+)
+
+go_proto_library(
+ name = "apiconfig_go_proto",
+ compilers = ["//:go_apiv2"],
+ importpath = "github.com/binchencoder/janus-gateway/gateway/internal/descriptor/apiconfig",
+ proto = ":apiconfig_proto",
+ deps = ["//httpoptions"],
+)
+
+go_library(
+ name = "apiconfig",
+ embed = [":apiconfig_go_proto"],
+ importpath = "github.com/binchencoder/janus-gateway/gateway/internal/descriptor/apiconfig",
+)
+
+alias(
+ name = "go_default_library",
+ actual = ":apiconfig",
+ visibility = ["//:__subpackages__"],
+)
diff --git a/gateway/internal/descriptor/apiconfig/apiconfig.pb.go b/gateway/internal/descriptor/apiconfig/apiconfig.pb.go
new file mode 100644
index 0000000..1abad8b
--- /dev/null
+++ b/gateway/internal/descriptor/apiconfig/apiconfig.pb.go
@@ -0,0 +1,171 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.23.0
+// protoc v3.12.3
+// source: gateway/internal/descriptor/apiconfig/apiconfig.proto
+
+package apiconfig
+
+import (
+ proto "github.com/golang/protobuf/proto"
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ httpoptions "httpoptions"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// This is a compile-time assertion that a sufficiently up-to-date version
+// of the legacy proto package is being used.
+const _ = proto.ProtoPackageIsVersion4
+
+// GrpcAPIService represents a stripped down version of google.api.Service .
+// Compare to https://github.com/googleapis/googleapis/blob/master/google/api/service.proto
+// The original imports 23 other protobuf files we are not interested in. If a significant
+// subset (>50%) of these start being reproduced in this file we should swap to using the
+// full generated version instead.
+//
+// For the purposes of the gateway generator we only consider a small subset of all
+// available features google supports in their service descriptions. Thanks to backwards
+// compatibility guarantees by protobuf it is safe for us to remove the other fields.
+type GrpcAPIService struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Http Rule.
+ Http *httpoptions.Http `protobuf:"bytes,1,opt,name=http,proto3" json:"http,omitempty"`
+}
+
+func (x *GrpcAPIService) Reset() {
+ *x = GrpcAPIService{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_internal_descriptor_apiconfig_apiconfig_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *GrpcAPIService) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GrpcAPIService) ProtoMessage() {}
+
+func (x *GrpcAPIService) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_internal_descriptor_apiconfig_apiconfig_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use GrpcAPIService.ProtoReflect.Descriptor instead.
+func (*GrpcAPIService) Descriptor() ([]byte, []int) {
+ return file_gateway_internal_descriptor_apiconfig_apiconfig_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *GrpcAPIService) GetHttp() *httpoptions.Http {
+ if x != nil {
+ return x.Http
+ }
+ return nil
+}
+
+var File_gateway_internal_descriptor_apiconfig_apiconfig_proto protoreflect.FileDescriptor
+
+var file_gateway_internal_descriptor_apiconfig_apiconfig_proto_rawDesc = []byte{
+ 0x0a, 0x35, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
+ 0x61, 0x6c, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x70,
+ 0x69, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x2a, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61,
+ 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x64,
+ 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x1a, 0x16, 0x68, 0x74, 0x74, 0x70, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+ 0x2f, 0x68, 0x74, 0x74, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x34, 0x0a, 0x0e, 0x47,
+ 0x72, 0x70, 0x63, 0x41, 0x50, 0x49, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x22, 0x0a,
+ 0x04, 0x68, 0x74, 0x74, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x65, 0x61,
+ 0x73, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x52, 0x04, 0x68, 0x74, 0x74,
+ 0x70, 0x42, 0x4b, 0x5a, 0x49, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+ 0x62, 0x69, 0x6e, 0x63, 0x68, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x65, 0x61, 0x73,
+ 0x65, 0x2d, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61,
+ 0x79, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
+ 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x62, 0x06,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_gateway_internal_descriptor_apiconfig_apiconfig_proto_rawDescOnce sync.Once
+ file_gateway_internal_descriptor_apiconfig_apiconfig_proto_rawDescData = file_gateway_internal_descriptor_apiconfig_apiconfig_proto_rawDesc
+)
+
+func file_gateway_internal_descriptor_apiconfig_apiconfig_proto_rawDescGZIP() []byte {
+ file_gateway_internal_descriptor_apiconfig_apiconfig_proto_rawDescOnce.Do(func() {
+ file_gateway_internal_descriptor_apiconfig_apiconfig_proto_rawDescData = protoimpl.X.CompressGZIP(file_gateway_internal_descriptor_apiconfig_apiconfig_proto_rawDescData)
+ })
+ return file_gateway_internal_descriptor_apiconfig_apiconfig_proto_rawDescData
+}
+
+var file_gateway_internal_descriptor_apiconfig_apiconfig_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_gateway_internal_descriptor_apiconfig_apiconfig_proto_goTypes = []interface{}{
+ (*GrpcAPIService)(nil), // 0: grpc.gateway.internal.descriptor.apiconfig.GrpcAPIService
+ (*httpoptions.Http)(nil), // 1: janus.api.Http
+}
+var file_gateway_internal_descriptor_apiconfig_apiconfig_proto_depIdxs = []int32{
+ 1, // 0: grpc.gateway.internal.descriptor.apiconfig.GrpcAPIService.http:type_name -> janus.api.Http
+ 1, // [1:1] is the sub-list for method output_type
+ 1, // [1:1] is the sub-list for method input_type
+ 1, // [1:1] is the sub-list for extension type_name
+ 1, // [1:1] is the sub-list for extension extendee
+ 0, // [0:1] is the sub-list for field type_name
+}
+
+func init() { file_gateway_internal_descriptor_apiconfig_apiconfig_proto_init() }
+func file_gateway_internal_descriptor_apiconfig_apiconfig_proto_init() {
+ if File_gateway_internal_descriptor_apiconfig_apiconfig_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_gateway_internal_descriptor_apiconfig_apiconfig_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*GrpcAPIService); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_gateway_internal_descriptor_apiconfig_apiconfig_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 1,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_gateway_internal_descriptor_apiconfig_apiconfig_proto_goTypes,
+ DependencyIndexes: file_gateway_internal_descriptor_apiconfig_apiconfig_proto_depIdxs,
+ MessageInfos: file_gateway_internal_descriptor_apiconfig_apiconfig_proto_msgTypes,
+ }.Build()
+ File_gateway_internal_descriptor_apiconfig_apiconfig_proto = out.File
+ file_gateway_internal_descriptor_apiconfig_apiconfig_proto_rawDesc = nil
+ file_gateway_internal_descriptor_apiconfig_apiconfig_proto_goTypes = nil
+ file_gateway_internal_descriptor_apiconfig_apiconfig_proto_depIdxs = nil
+}
diff --git a/gateway/internal/descriptor/apiconfig/apiconfig.proto b/gateway/internal/descriptor/apiconfig/apiconfig.proto
new file mode 100644
index 0000000..2ffc0ed
--- /dev/null
+++ b/gateway/internal/descriptor/apiconfig/apiconfig.proto
@@ -0,0 +1,21 @@
+syntax = "proto3";
+
+package grpc.gateway.internal.descriptor.apiconfig;
+
+option go_package = "github.com/binchencoder/janus-gateway/gatewayinternal/descriptor/apiconfig";
+
+import "httpoptions/http.proto";
+
+// GrpcAPIService represents a stripped down version of google.api.Service .
+// Compare to https://github.com/googleapis/googleapis/blob/master/google/api/service.proto
+// The original imports 23 other protobuf files we are not interested in. If a significant
+// subset (>50%) of these start being reproduced in this file we should swap to using the
+// full generated version instead.
+//
+// For the purposes of the gateway generator we only consider a small subset of all
+// available features google supports in their service descriptions. Thanks to backwards
+// compatibility guarantees by protobuf it is safe for us to remove the other fields.
+message GrpcAPIService {
+ // Http Rule.
+ janus.api.Http http = 1;
+}
diff --git a/gateway/protoc-gen-grpc-gateway/descriptor/grpc_api_configuration.go b/gateway/internal/descriptor/grpc_api_configuration.go
similarity index 63%
rename from gateway/protoc-gen-grpc-gateway/descriptor/grpc_api_configuration.go
rename to gateway/internal/descriptor/grpc_api_configuration.go
index ca68ed7..dd59a30 100644
--- a/gateway/protoc-gen-grpc-gateway/descriptor/grpc_api_configuration.go
+++ b/gateway/internal/descriptor/grpc_api_configuration.go
@@ -1,44 +1,45 @@
package descriptor
import (
- "bytes"
"fmt"
"io/ioutil"
"strings"
- "github.com/ghodss/yaml"
- "github.com/golang/protobuf/jsonpb"
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor/apiconfig"
+ "github.com/binchencoder/janus-gateway/gateway/internal/descriptor/apiconfig"
+ "google.golang.org/protobuf/encoding/protojson"
+ "sigs.k8s.io/yaml"
)
-func loadGrpcAPIServiceFromYAML(yamlFileContents []byte, yamlSourceLogName string) (*GrpcAPIService, error) {
+func loadGrpcAPIServiceFromYAML(yamlFileContents []byte, yamlSourceLogName string) (*apiconfig.GrpcAPIService, error) {
jsonContents, err := yaml.YAMLToJSON(yamlFileContents)
if err != nil {
- return nil, fmt.Errorf("Failed to convert gRPC API Configuration from YAML in '%v' to JSON: %v", yamlSourceLogName, err)
+ return nil, fmt.Errorf("failed to convert gRPC API Configuration from YAML in '%v' to JSON: %v", yamlSourceLogName, err)
}
- // As our GrpcAPIService is incomplete accept unkown fields.
- unmarshaler := jsonpb.Unmarshaler{
- AllowUnknownFields: true,
+ // As our GrpcAPIService is incomplete, accept unknown fields.
+ unmarshaler := protojson.UnmarshalOptions{
+ DiscardUnknown: true,
}
- serviceConfiguration := GrpcAPIService{}
- if err := unmarshaler.Unmarshal(bytes.NewReader(jsonContents), &serviceConfiguration); err != nil {
- return nil, fmt.Errorf("Failed to parse gRPC API Configuration from YAML in '%v': %v", yamlSourceLogName, err)
+ serviceConfiguration := apiconfig.GrpcAPIService{}
+ if err := unmarshaler.Unmarshal(jsonContents, &serviceConfiguration); err != nil {
+ return nil, fmt.Errorf("failed to parse gRPC API Configuration from YAML in '%v': %v", yamlSourceLogName, err)
}
return &serviceConfiguration, nil
}
-func registerHTTPRulesFromGrpcAPIService(registry *Registry, service *GrpcAPIService, sourceLogName string) error {
- if service.HTTP == nil {
+func registerHTTPRulesFromGrpcAPIService(registry *Registry, service *apiconfig.GrpcAPIService, sourceLogName string) error {
+ if service.Http == nil {
// Nothing to do
return nil
}
- for _, rule := range service.HTTP.GetRules() {
+ for _, rule := range service.Http.GetRules() {
selector := "." + strings.Trim(rule.GetSelector(), " ")
if strings.ContainsAny(selector, "*, ") {
- return fmt.Errorf("Selector '%v' in %v must specify a single service method without wildcards", rule.GetSelector(), sourceLogName)
+ return fmt.Errorf("selector '%v' in %v must specify a single service method without wildcards", rule.GetSelector(), sourceLogName)
}
registry.AddExternalHTTPRule(selector, rule)
@@ -59,7 +60,7 @@ func registerHTTPRulesFromGrpcAPIService(registry *Registry, service *GrpcAPISer
func (r *Registry) LoadGrpcAPIServiceFromYAML(yamlFile string) error {
yamlFileContents, err := ioutil.ReadFile(yamlFile)
if err != nil {
- return fmt.Errorf("Failed to read gRPC API Configuration description from '%v': %v", yamlFile, err)
+ return fmt.Errorf("failed to read gRPC API Configuration description from '%v': %v", yamlFile, err)
}
service, err := loadGrpcAPIServiceFromYAML(yamlFileContents, yamlFile)
diff --git a/gateway/protoc-gen-grpc-gateway/descriptor/grpc_api_configuration_test.go b/gateway/internal/descriptor/grpc_api_configuration_test.go
similarity index 84%
rename from gateway/protoc-gen-grpc-gateway/descriptor/grpc_api_configuration_test.go
rename to gateway/internal/descriptor/grpc_api_configuration_test.go
index cc6cb44..09cf0a8 100644
--- a/gateway/protoc-gen-grpc-gateway/descriptor/grpc_api_configuration_test.go
+++ b/gateway/internal/descriptor/grpc_api_configuration_test.go
@@ -1,164 +1,149 @@
-package descriptor
-
-import (
- "strings"
- "testing"
-)
-
-func TestLoadGrpcAPIServiceFromYAMLEmpty(t *testing.T) {
- service, err := loadGrpcAPIServiceFromYAML([]byte(``), "empty")
- if err != nil {
- t.Fatal(err)
- }
-
- if service == nil {
- t.Fatal("No service returned")
- }
-
- if service.HTTP != nil {
- t.Fatal("HTTP not empty")
- }
-}
-
-func TestLoadGrpcAPIServiceFromYAMLInvalidType(t *testing.T) {
- // Ideally this would fail but for now this test documents that it doesn't
- service, err := loadGrpcAPIServiceFromYAML([]byte(`type: not.the.right.type`), "invalidtype")
- if err != nil {
- t.Fatal(err)
- }
-
- if service == nil {
- t.Fatal("No service returned")
- }
-}
-
-func TestLoadGrpcAPIServiceFromYAMLSingleRule(t *testing.T) {
- service, err := loadGrpcAPIServiceFromYAML([]byte(`
-type: google.api.Service
-config_version: 3
-
-http:
- rules:
- - selector: grpctest.YourService.Echo
- post: /v1/myecho
- body: "*"
-`), "example")
- if err != nil {
- t.Fatal(err)
- }
-
- if service.HTTP == nil {
- t.Fatal("HTTP is empty")
- }
-
- if len(service.HTTP.GetRules()) != 1 {
- t.Fatalf("Have %v rules instead of one. Got: %v", len(service.HTTP.GetRules()), service.HTTP.GetRules())
- }
-
- rule := service.HTTP.GetRules()[0]
- if rule.GetSelector() != "grpctest.YourService.Echo" {
- t.Errorf("Rule has unexpected selector '%v'", rule.GetSelector())
- }
- if rule.GetPost() != "/v1/myecho" {
- t.Errorf("Rule has unexpected post '%v'", rule.GetPost())
- }
- if rule.GetBody() != "*" {
- t.Errorf("Rule has unexpected body '%v'", rule.GetBody())
- }
-}
-
-func TestLoadGrpcAPIServiceFromYAMLRejectInvalidYAML(t *testing.T) {
- service, err := loadGrpcAPIServiceFromYAML([]byte(`
-type: google.api.Service
-config_version: 3
-
-http:
- rules:
- - selector: grpctest.YourService.Echo
- - post: thislinebreakstheselectorblockabovewiththeleadingdash
- body: "*"
-`), "invalidyaml")
- if err == nil {
- t.Fatal(err)
- }
-
- if !strings.Contains(err.Error(), "line 7") {
- t.Errorf("Expected yaml error to be detected in line 7. Got other error: %v", err)
- }
-
- if service != nil {
- t.Fatal("Service returned")
- }
-}
-
-func TestLoadGrpcAPIServiceFromYAMLMultipleWithAdditionalBindings(t *testing.T) {
- service, err := loadGrpcAPIServiceFromYAML([]byte(`
-type: google.api.Service
-config_version: 3
-
-http:
- rules:
- - selector: first.selector
- post: /my/post/path
- body: "*"
- additional_bindings:
- - post: /additional/post/path
- - put: /additional/put/{value}/path
- - delete: "{value}"
- - patch: "/additional/patch/{value}"
- - selector: some.other.service
- delete: foo
-`), "example")
- if err != nil {
- t.Fatalf("Failed to load service description from YAML: %v", err)
- }
-
- if service == nil {
- t.Fatal("No service returned")
- }
-
- if service.HTTP == nil {
- t.Fatal("HTTP is empty")
- }
-
- if len(service.HTTP.GetRules()) != 2 {
- t.Fatalf("%v service(s) returned when two were expected. Got: %v", len(service.HTTP.GetRules()), service.HTTP)
- }
-
- first := service.HTTP.GetRules()[0]
- if first.GetSelector() != "first.selector" {
- t.Errorf("first.selector has unexpected selector '%v'", first.GetSelector())
- }
- if first.GetBody() != "*" {
- t.Errorf("first.selector has unexpected body '%v'", first.GetBody())
- }
- if first.GetPost() != "/my/post/path" {
- t.Errorf("first.selector has unexpected post '%v'", first.GetPost())
- }
- if len(first.GetAdditionalBindings()) != 4 {
- t.Fatalf("first.selector has unexpected number of bindings %v instead of four. Got: %v", len(first.GetAdditionalBindings()), first.GetAdditionalBindings())
- }
- if first.GetAdditionalBindings()[0].GetPost() != "/additional/post/path" {
- t.Errorf("first.selector additional binding 0 has unexpected post '%v'", first.GetAdditionalBindings()[0].GetPost())
- }
- if first.GetAdditionalBindings()[1].GetPut() != "/additional/put/{value}/path" {
- t.Errorf("first.selector additional binding 1 has unexpected put '%v'", first.GetAdditionalBindings()[0].GetPost())
- }
- if first.GetAdditionalBindings()[2].GetDelete() != "{value}" {
- t.Errorf("first.selector additional binding 2 has unexpected delete '%v'", first.GetAdditionalBindings()[0].GetPost())
- }
- if first.GetAdditionalBindings()[3].GetPatch() != "/additional/patch/{value}" {
- t.Errorf("first.selector additional binding 3 has unexpected patch '%v'", first.GetAdditionalBindings()[0].GetPost())
- }
-
- second := service.HTTP.GetRules()[1]
- if second.GetSelector() != "some.other.service" {
- t.Errorf("some.other.service has unexpected selector '%v'", second.GetSelector())
- }
- if second.GetDelete() != "foo" {
- t.Errorf("some.other.service has unexpected delete '%v'", second.GetDelete())
- }
- if len(second.GetAdditionalBindings()) != 0 {
- t.Errorf("some.other.service has %v additional bindings when it should not have any. Got: %v", len(second.GetAdditionalBindings()), second.GetAdditionalBindings())
- }
-}
+package descriptor
+
+import (
+ "strings"
+ "testing"
+)
+
+func TestLoadGrpcAPIServiceFromYAMLInvalidType(t *testing.T) {
+ // Ideally this would fail but for now this test documents that it doesn't
+ service, err := loadGrpcAPIServiceFromYAML([]byte(`type: not.the.right.type`), "invalidtype")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if service == nil {
+ t.Fatal("No service returned")
+ }
+}
+
+func TestLoadGrpcAPIServiceFromYAMLSingleRule(t *testing.T) {
+ service, err := loadGrpcAPIServiceFromYAML([]byte(`
+type: google.api.Service
+config_version: 3
+
+http:
+ rules:
+ - selector: grpctest.YourService.Echo
+ post: /v1/myecho
+ body: "*"
+`), "example")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if service.Http == nil {
+ t.Fatal("HTTP is empty")
+ }
+
+ if len(service.Http.GetRules()) != 1 {
+ t.Fatalf("Have %v rules instead of one. Got: %v", len(service.Http.GetRules()), service.Http.GetRules())
+ }
+
+ rule := service.Http.GetRules()[0]
+ if rule.GetSelector() != "grpctest.YourService.Echo" {
+ t.Errorf("Rule has unexpected selector '%v'", rule.GetSelector())
+ }
+ if rule.GetPost() != "/v1/myecho" {
+ t.Errorf("Rule has unexpected post '%v'", rule.GetPost())
+ }
+ if rule.GetBody() != "*" {
+ t.Errorf("Rule has unexpected body '%v'", rule.GetBody())
+ }
+}
+
+func TestLoadGrpcAPIServiceFromYAMLRejectInvalidYAML(t *testing.T) {
+ service, err := loadGrpcAPIServiceFromYAML([]byte(`
+type: google.api.Service
+config_version: 3
+
+http:
+ rules:
+ - selector: grpctest.YourService.Echo
+ - post: thislinebreakstheselectorblockabovewiththeleadingdash
+ body: "*"
+`), "invalidyaml")
+ if err == nil {
+ t.Fatal(err)
+ }
+
+ if !strings.Contains(err.Error(), "line 7") {
+ t.Errorf("Expected yaml error to be detected in line 7. Got other error: %v", err)
+ }
+
+ if service != nil {
+ t.Fatal("Service returned")
+ }
+}
+
+func TestLoadGrpcAPIServiceFromYAMLMultipleWithAdditionalBindings(t *testing.T) {
+ service, err := loadGrpcAPIServiceFromYAML([]byte(`
+type: google.api.Service
+config_version: 3
+
+http:
+ rules:
+ - selector: first.selector
+ post: /my/post/path
+ body: "*"
+ additional_bindings:
+ - post: /additional/post/path
+ - put: /additional/put/{value}/path
+ - delete: "{value}"
+ - patch: "/additional/patch/{value}"
+ - selector: some.other.service
+ delete: foo
+`), "example")
+ if err != nil {
+ t.Fatalf("Failed to load service description from YAML: %v", err)
+ }
+
+ if service == nil {
+ t.Fatal("No service returned")
+ }
+
+ if service.Http == nil {
+ t.Fatal("HTTP is empty")
+ }
+
+ if len(service.Http.GetRules()) != 2 {
+ t.Fatalf("%v service(s) returned when two were expected. Got: %v", len(service.Http.GetRules()), service.Http)
+ }
+
+ first := service.Http.GetRules()[0]
+ if first.GetSelector() != "first.selector" {
+ t.Errorf("first.selector has unexpected selector '%v'", first.GetSelector())
+ }
+ if first.GetBody() != "*" {
+ t.Errorf("first.selector has unexpected body '%v'", first.GetBody())
+ }
+ if first.GetPost() != "/my/post/path" {
+ t.Errorf("first.selector has unexpected post '%v'", first.GetPost())
+ }
+ if len(first.GetAdditionalBindings()) != 4 {
+ t.Fatalf("first.selector has unexpected number of bindings %v instead of four. Got: %v", len(first.GetAdditionalBindings()), first.GetAdditionalBindings())
+ }
+ if first.GetAdditionalBindings()[0].GetPost() != "/additional/post/path" {
+ t.Errorf("first.selector additional binding 0 has unexpected post '%v'", first.GetAdditionalBindings()[0].GetPost())
+ }
+ if first.GetAdditionalBindings()[1].GetPut() != "/additional/put/{value}/path" {
+ t.Errorf("first.selector additional binding 1 has unexpected put '%v'", first.GetAdditionalBindings()[0].GetPost())
+ }
+ if first.GetAdditionalBindings()[2].GetDelete() != "{value}" {
+ t.Errorf("first.selector additional binding 2 has unexpected delete '%v'", first.GetAdditionalBindings()[0].GetPost())
+ }
+ if first.GetAdditionalBindings()[3].GetPatch() != "/additional/patch/{value}" {
+ t.Errorf("first.selector additional binding 3 has unexpected patch '%v'", first.GetAdditionalBindings()[0].GetPost())
+ }
+
+ second := service.Http.GetRules()[1]
+ if second.GetSelector() != "some.other.service" {
+ t.Errorf("some.other.service has unexpected selector '%v'", second.GetSelector())
+ }
+ if second.GetDelete() != "foo" {
+ t.Errorf("some.other.service has unexpected delete '%v'", second.GetDelete())
+ }
+ if len(second.GetAdditionalBindings()) != 0 {
+ t.Errorf("some.other.service has %v additional bindings when it should not have any. Got: %v", len(second.GetAdditionalBindings()), second.GetAdditionalBindings())
+ }
+}
diff --git a/gateway/internal/descriptor/openapi_configuration.go b/gateway/internal/descriptor/openapi_configuration.go
new file mode 100644
index 0000000..ebbaf6b
--- /dev/null
+++ b/gateway/internal/descriptor/openapi_configuration.go
@@ -0,0 +1,59 @@
+package descriptor
+
+import (
+ "fmt"
+ "io/ioutil"
+
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor/openapiconfig"
+ "github.com/binchencoder/janus-gateway/gateway/internal/descriptor/openapiconfig"
+ "google.golang.org/protobuf/encoding/protojson"
+ "sigs.k8s.io/yaml"
+)
+
+func loadOpenAPIConfigFromYAML(yamlFileContents []byte, yamlSourceLogName string) (*openapiconfig.OpenAPIConfig, error) {
+ jsonContents, err := yaml.YAMLToJSON(yamlFileContents)
+ if err != nil {
+ return nil, fmt.Errorf("failed to convert OpenAPI Configuration from YAML in '%v' to JSON: %v", yamlSourceLogName, err)
+ }
+
+ // Reject unknown fields because OpenAPIConfig is only used here
+ unmarshaler := protojson.UnmarshalOptions{
+ DiscardUnknown: false,
+ }
+
+ openapiConfiguration := openapiconfig.OpenAPIConfig{}
+ if err := unmarshaler.Unmarshal(jsonContents, &openapiConfiguration); err != nil {
+ return nil, fmt.Errorf("failed to parse gRPC API Configuration from YAML in '%v': %v", yamlSourceLogName, err)
+ }
+
+ return &openapiConfiguration, nil
+}
+
+func registerOpenAPIOptions(registry *Registry, openAPIConfig *openapiconfig.OpenAPIConfig, yamlSourceLogName string) error {
+ if openAPIConfig.OpenapiOptions == nil {
+ // Nothing to do
+ return nil
+ }
+
+ if err := registry.RegisterOpenAPIOptions(openAPIConfig.OpenapiOptions); err != nil {
+ return fmt.Errorf("failed to register option in %s: %s", yamlSourceLogName, err)
+ }
+ return nil
+}
+
+// LoadOpenAPIConfigFromYAML loads an OpenAPI Configuration from the given YAML file
+// and registers the OpenAPI options the given registry.
+// This must be done after loading the proto file.
+func (r *Registry) LoadOpenAPIConfigFromYAML(yamlFile string) error {
+ yamlFileContents, err := ioutil.ReadFile(yamlFile)
+ if err != nil {
+ return fmt.Errorf("failed to read gRPC API Configuration description from '%v': %v", yamlFile, err)
+ }
+
+ config, err := loadOpenAPIConfigFromYAML(yamlFileContents, yamlFile)
+ if err != nil {
+ return err
+ }
+
+ return registerOpenAPIOptions(r, config, yamlFile)
+}
diff --git a/gateway/internal/descriptor/openapi_configuration_test.go b/gateway/internal/descriptor/openapi_configuration_test.go
new file mode 100644
index 0000000..6dcec93
--- /dev/null
+++ b/gateway/internal/descriptor/openapi_configuration_test.go
@@ -0,0 +1,115 @@
+package descriptor
+
+import (
+ "strings"
+ "testing"
+
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
+ "github.com/binchencoder/janus-gateway/gateway/protoc-gen-openapiv2/options"
+)
+
+func TestLoadOpenAPIConfigFromYAMLRejectInvalidYAML(t *testing.T) {
+ config, err := loadOpenAPIConfigFromYAML([]byte(`
+openapiOptions:
+file:
+- file: test.proto
+ - option:
+ schemes:
+ - HTTP
+ - HTTPS
+ - WSS
+ securityDefinitions:
+ security:
+ ApiKeyAuth:
+ type: TYPE_API_KEY
+ in: IN_HEADER
+ name: "X-API-Key"
+`), "invalidyaml")
+ if err == nil {
+ t.Fatal(err)
+ }
+
+ if !strings.Contains(err.Error(), "line 4") {
+ t.Errorf("Expected yaml error to be detected in line 4. Got other error: %v", err)
+ }
+
+ if config != nil {
+ t.Fatal("Config returned")
+ }
+}
+
+func TestLoadOpenAPIConfigFromYAML(t *testing.T) {
+ config, err := loadOpenAPIConfigFromYAML([]byte(`
+openapiOptions:
+ file:
+ - file: test.proto
+ option:
+ schemes:
+ - HTTP
+ - HTTPS
+ - WSS
+ securityDefinitions:
+ security:
+ ApiKeyAuth:
+ type: TYPE_API_KEY
+ in: IN_HEADER
+ name: "X-API-Key"
+`), "openapi_options")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if config.OpenapiOptions == nil {
+ t.Fatal("OpenAPIOptions is empty")
+ }
+
+ opts := config.OpenapiOptions
+ if numFileOpts := len(opts.File); numFileOpts != 1 {
+ t.Fatalf("expected 1 file option but got %d", numFileOpts)
+ }
+
+ fileOpt := opts.File[0]
+
+ if fileOpt.File != "test.proto" {
+ t.Fatalf("file option has unexpected binding %s", fileOpt.File)
+ }
+
+ swaggerOpt := fileOpt.Option
+
+ if swaggerOpt == nil {
+ t.Fatal("expected option to be set")
+ }
+
+ if numSchemes := len(swaggerOpt.Schemes); numSchemes != 3 {
+ t.Fatalf("expected 3 schemes but got %d", numSchemes)
+ }
+ if swaggerOpt.Schemes[0] != options.Scheme_HTTP {
+ t.Fatalf("expected first scheme to be HTTP but got %s", swaggerOpt.Schemes[0])
+ }
+ if swaggerOpt.Schemes[1] != options.Scheme_HTTPS {
+ t.Fatalf("expected second scheme to be HTTPS but got %s", swaggerOpt.Schemes[1])
+ }
+ if swaggerOpt.Schemes[2] != options.Scheme_WSS {
+ t.Fatalf("expected third scheme to be WSS but got %s", swaggerOpt.Schemes[2])
+ }
+
+ if swaggerOpt.SecurityDefinitions == nil {
+ t.Fatal("expected securityDefinitions to be set")
+ }
+ if numSecOpts := len(swaggerOpt.SecurityDefinitions.Security); numSecOpts != 1 {
+ t.Fatalf("expected 1 security option but got %d", numSecOpts)
+ }
+ secOpt, ok := swaggerOpt.SecurityDefinitions.Security["ApiKeyAuth"]
+ if !ok {
+ t.Fatal("no SecurityScheme for key \"ApiKeyAuth\"")
+ }
+ if secOpt.Type != options.SecurityScheme_TYPE_API_KEY {
+ t.Fatalf("expected scheme type to be TYPE_API_KEY but got %s", secOpt.Type)
+ }
+ if secOpt.In != options.SecurityScheme_IN_HEADER {
+ t.Fatalf("expected scheme in to be IN_HEADER but got %s", secOpt.In)
+ }
+ if secOpt.Name != "X-API-Key" {
+ t.Fatalf("expected name to be X-API-Key but got %s", secOpt.Name)
+ }
+}
diff --git a/gateway/internal/descriptor/openapiconfig/BUILD.bazel b/gateway/internal/descriptor/openapiconfig/BUILD.bazel
new file mode 100644
index 0000000..60d2a9a
--- /dev/null
+++ b/gateway/internal/descriptor/openapiconfig/BUILD.bazel
@@ -0,0 +1,32 @@
+load("@rules_proto//proto:defs.bzl", "proto_library")
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
+
+proto_library(
+ name = "openapiconfig_proto",
+ srcs = ["openapiconfig.proto"],
+ visibility = ["//:__subpackages__"],
+ deps = ["//gateway/protoc-gen-openapiv2/options:options_proto"],
+)
+
+go_proto_library(
+ name = "openapiconfig_go_proto",
+ compilers = ["//:go_apiv2"],
+ importpath = "github.com/binchencoder/janus-gateway/gateway/internal/descriptor/openapiconfig",
+ proto = ":openapiconfig_proto",
+ visibility = ["//:__subpackages__"],
+ deps = ["//gateway/protoc-gen-openapiv2/options"],
+)
+
+go_library(
+ name = "openapiconfig",
+ embed = [":openapiconfig_go_proto"],
+ importpath = "github.com/binchencoder/janus-gateway/gateway/internal/descriptor/openapiconfig",
+ visibility = ["//:__subpackages__"],
+)
+
+alias(
+ name = "go_default_library",
+ actual = ":openapiconfig",
+ visibility = ["//:__subpackages__"],
+)
diff --git a/gateway/internal/descriptor/openapiconfig/openapiconfig.pb.go b/gateway/internal/descriptor/openapiconfig/openapiconfig.pb.go
new file mode 100755
index 0000000..405ef9b
--- /dev/null
+++ b/gateway/internal/descriptor/openapiconfig/openapiconfig.pb.go
@@ -0,0 +1,677 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.27.1
+// protoc v3.19.4
+// source: gateway/internal/descriptor/openapiconfig/openapiconfig.proto
+
+package openapiconfig
+
+import (
+ options "github.com/binchencoder/janus-gateway/gateway/protoc-gen-openapiv2/options"
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type OpenAPIFileOption struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ File string `protobuf:"bytes,1,opt,name=file,proto3" json:"file,omitempty"`
+ Option *options.Swagger `protobuf:"bytes,2,opt,name=option,proto3" json:"option,omitempty"`
+}
+
+func (x *OpenAPIFileOption) Reset() {
+ *x = OpenAPIFileOption{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *OpenAPIFileOption) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*OpenAPIFileOption) ProtoMessage() {}
+
+func (x *OpenAPIFileOption) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use OpenAPIFileOption.ProtoReflect.Descriptor instead.
+func (*OpenAPIFileOption) Descriptor() ([]byte, []int) {
+ return file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *OpenAPIFileOption) GetFile() string {
+ if x != nil {
+ return x.File
+ }
+ return ""
+}
+
+func (x *OpenAPIFileOption) GetOption() *options.Swagger {
+ if x != nil {
+ return x.Option
+ }
+ return nil
+}
+
+type OpenAPIMethodOption struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Method string `protobuf:"bytes,1,opt,name=method,proto3" json:"method,omitempty"`
+ Option *options.Operation `protobuf:"bytes,2,opt,name=option,proto3" json:"option,omitempty"`
+}
+
+func (x *OpenAPIMethodOption) Reset() {
+ *x = OpenAPIMethodOption{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *OpenAPIMethodOption) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*OpenAPIMethodOption) ProtoMessage() {}
+
+func (x *OpenAPIMethodOption) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use OpenAPIMethodOption.ProtoReflect.Descriptor instead.
+func (*OpenAPIMethodOption) Descriptor() ([]byte, []int) {
+ return file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *OpenAPIMethodOption) GetMethod() string {
+ if x != nil {
+ return x.Method
+ }
+ return ""
+}
+
+func (x *OpenAPIMethodOption) GetOption() *options.Operation {
+ if x != nil {
+ return x.Option
+ }
+ return nil
+}
+
+type OpenAPIMessageOption struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
+ Option *options.Schema `protobuf:"bytes,2,opt,name=option,proto3" json:"option,omitempty"`
+}
+
+func (x *OpenAPIMessageOption) Reset() {
+ *x = OpenAPIMessageOption{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *OpenAPIMessageOption) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*OpenAPIMessageOption) ProtoMessage() {}
+
+func (x *OpenAPIMessageOption) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use OpenAPIMessageOption.ProtoReflect.Descriptor instead.
+func (*OpenAPIMessageOption) Descriptor() ([]byte, []int) {
+ return file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *OpenAPIMessageOption) GetMessage() string {
+ if x != nil {
+ return x.Message
+ }
+ return ""
+}
+
+func (x *OpenAPIMessageOption) GetOption() *options.Schema {
+ if x != nil {
+ return x.Option
+ }
+ return nil
+}
+
+type OpenAPIServiceOption struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
+ Option *options.Tag `protobuf:"bytes,2,opt,name=option,proto3" json:"option,omitempty"`
+}
+
+func (x *OpenAPIServiceOption) Reset() {
+ *x = OpenAPIServiceOption{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *OpenAPIServiceOption) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*OpenAPIServiceOption) ProtoMessage() {}
+
+func (x *OpenAPIServiceOption) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use OpenAPIServiceOption.ProtoReflect.Descriptor instead.
+func (*OpenAPIServiceOption) Descriptor() ([]byte, []int) {
+ return file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *OpenAPIServiceOption) GetService() string {
+ if x != nil {
+ return x.Service
+ }
+ return ""
+}
+
+func (x *OpenAPIServiceOption) GetOption() *options.Tag {
+ if x != nil {
+ return x.Option
+ }
+ return nil
+}
+
+type OpenAPIFieldOption struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Field string `protobuf:"bytes,1,opt,name=field,proto3" json:"field,omitempty"`
+ Option *options.JSONSchema `protobuf:"bytes,2,opt,name=option,proto3" json:"option,omitempty"`
+}
+
+func (x *OpenAPIFieldOption) Reset() {
+ *x = OpenAPIFieldOption{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *OpenAPIFieldOption) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*OpenAPIFieldOption) ProtoMessage() {}
+
+func (x *OpenAPIFieldOption) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[4]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use OpenAPIFieldOption.ProtoReflect.Descriptor instead.
+func (*OpenAPIFieldOption) Descriptor() ([]byte, []int) {
+ return file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *OpenAPIFieldOption) GetField() string {
+ if x != nil {
+ return x.Field
+ }
+ return ""
+}
+
+func (x *OpenAPIFieldOption) GetOption() *options.JSONSchema {
+ if x != nil {
+ return x.Option
+ }
+ return nil
+}
+
+type OpenAPIOptions struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ File []*OpenAPIFileOption `protobuf:"bytes,1,rep,name=file,proto3" json:"file,omitempty"`
+ Method []*OpenAPIMethodOption `protobuf:"bytes,2,rep,name=method,proto3" json:"method,omitempty"`
+ Message []*OpenAPIMessageOption `protobuf:"bytes,3,rep,name=message,proto3" json:"message,omitempty"`
+ Service []*OpenAPIServiceOption `protobuf:"bytes,4,rep,name=service,proto3" json:"service,omitempty"`
+ Field []*OpenAPIFieldOption `protobuf:"bytes,5,rep,name=field,proto3" json:"field,omitempty"`
+}
+
+func (x *OpenAPIOptions) Reset() {
+ *x = OpenAPIOptions{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *OpenAPIOptions) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*OpenAPIOptions) ProtoMessage() {}
+
+func (x *OpenAPIOptions) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[5]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use OpenAPIOptions.ProtoReflect.Descriptor instead.
+func (*OpenAPIOptions) Descriptor() ([]byte, []int) {
+ return file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *OpenAPIOptions) GetFile() []*OpenAPIFileOption {
+ if x != nil {
+ return x.File
+ }
+ return nil
+}
+
+func (x *OpenAPIOptions) GetMethod() []*OpenAPIMethodOption {
+ if x != nil {
+ return x.Method
+ }
+ return nil
+}
+
+func (x *OpenAPIOptions) GetMessage() []*OpenAPIMessageOption {
+ if x != nil {
+ return x.Message
+ }
+ return nil
+}
+
+func (x *OpenAPIOptions) GetService() []*OpenAPIServiceOption {
+ if x != nil {
+ return x.Service
+ }
+ return nil
+}
+
+func (x *OpenAPIOptions) GetField() []*OpenAPIFieldOption {
+ if x != nil {
+ return x.Field
+ }
+ return nil
+}
+
+type OpenAPIConfig struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ OpenapiOptions *OpenAPIOptions `protobuf:"bytes,1,opt,name=openapi_options,json=openapiOptions,proto3" json:"openapi_options,omitempty"`
+}
+
+func (x *OpenAPIConfig) Reset() {
+ *x = OpenAPIConfig{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[6]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *OpenAPIConfig) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*OpenAPIConfig) ProtoMessage() {}
+
+func (x *OpenAPIConfig) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[6]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use OpenAPIConfig.ProtoReflect.Descriptor instead.
+func (*OpenAPIConfig) Descriptor() ([]byte, []int) {
+ return file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *OpenAPIConfig) GetOpenapiOptions() *OpenAPIOptions {
+ if x != nil {
+ return x.OpenapiOptions
+ }
+ return nil
+}
+
+var File_gateway_internal_descriptor_openapiconfig_openapiconfig_proto protoreflect.FileDescriptor
+
+var file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_rawDesc = []byte{
+ 0x0a, 0x3d, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
+ 0x61, 0x6c, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x6f, 0x70,
+ 0x65, 0x6e, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x70, 0x65, 0x6e,
+ 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
+ 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x69, 0x6e,
+ 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f,
+ 0x72, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a,
+ 0x34, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d,
+ 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2f, 0x6f, 0x70,
+ 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x73, 0x0a, 0x11, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49,
+ 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69,
+ 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x4a,
+ 0x0a, 0x06, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32,
+ 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,
+ 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x77, 0x61, 0x67, 0x67,
+ 0x65, 0x72, 0x52, 0x06, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x7b, 0x0a, 0x13, 0x4f, 0x70,
+ 0x65, 0x6e, 0x41, 0x50, 0x49, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f,
+ 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x4c, 0x0a, 0x06, 0x6f, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x67, 0x72, 0x70, 0x63,
+ 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f,
+ 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70,
+ 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+ 0x06, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x7b, 0x0a, 0x14, 0x4f, 0x70, 0x65, 0x6e, 0x41,
+ 0x50, 0x49, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12,
+ 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x49, 0x0a, 0x06, 0x6f, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x67, 0x72, 0x70, 0x63,
+ 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f,
+ 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70,
+ 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x06, 0x6f, 0x70,
+ 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x78, 0x0a, 0x14, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x53,
+ 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07,
+ 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73,
+ 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x46, 0x0a, 0x06, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61,
+ 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e,
+ 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f,
+ 0x6e, 0x73, 0x2e, 0x54, 0x61, 0x67, 0x52, 0x06, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x79,
+ 0x0a, 0x12, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70,
+ 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x4d, 0x0a, 0x06, 0x6f, 0x70,
+ 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x67, 0x72, 0x70,
+ 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63,
+ 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f,
+ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4a, 0x53, 0x4f, 0x4e, 0x53, 0x63, 0x68, 0x65, 0x6d,
+ 0x61, 0x52, 0x06, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xde, 0x03, 0x0a, 0x0e, 0x4f, 0x70,
+ 0x65, 0x6e, 0x41, 0x50, 0x49, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x55, 0x0a, 0x04,
+ 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x67, 0x72, 0x70,
+ 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
+ 0x61, 0x6c, 0x2e, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x6f, 0x70,
+ 0x65, 0x6e, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4f, 0x70, 0x65, 0x6e,
+ 0x41, 0x50, 0x49, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x66,
+ 0x69, 0x6c, 0x65, 0x12, 0x5b, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20,
+ 0x03, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77,
+ 0x61, 0x79, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x64, 0x65, 0x73, 0x63,
+ 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x63, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x4d, 0x65, 0x74, 0x68,
+ 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64,
+ 0x12, 0x5e, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28,
+ 0x0b, 0x32, 0x44, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
+ 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
+ 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6e, 0x66,
+ 0x69, 0x67, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
+ 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+ 0x12, 0x5e, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28,
+ 0x0b, 0x32, 0x44, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
+ 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
+ 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6e, 0x66,
+ 0x69, 0x67, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
+ 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+ 0x12, 0x58, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32,
+ 0x42, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x69,
+ 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
+ 0x6f, 0x72, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+ 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x22, 0x78, 0x0a, 0x0d, 0x4f, 0x70,
+ 0x65, 0x6e, 0x41, 0x50, 0x49, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x67, 0x0a, 0x0f, 0x6f,
+ 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65,
+ 0x77, 0x61, 0x79, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x64, 0x65, 0x73,
+ 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x63,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x4f, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x4f, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x50, 0x5a, 0x4e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x2f, 0x62, 0x69, 0x6e, 0x63, 0x68, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f,
+ 0x65, 0x61, 0x73, 0x65, 0x2d, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2f, 0x67, 0x61, 0x74,
+ 0x65, 0x77, 0x61, 0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x64, 0x65,
+ 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,
+ 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescOnce sync.Once
+ file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescData = file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_rawDesc
+)
+
+func file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescGZIP() []byte {
+ file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescOnce.Do(func() {
+ file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescData = protoimpl.X.CompressGZIP(file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescData)
+ })
+ return file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescData
+}
+
+var file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
+var file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_goTypes = []interface{}{
+ (*OpenAPIFileOption)(nil), // 0: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIFileOption
+ (*OpenAPIMethodOption)(nil), // 1: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIMethodOption
+ (*OpenAPIMessageOption)(nil), // 2: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIMessageOption
+ (*OpenAPIServiceOption)(nil), // 3: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIServiceOption
+ (*OpenAPIFieldOption)(nil), // 4: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIFieldOption
+ (*OpenAPIOptions)(nil), // 5: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIOptions
+ (*OpenAPIConfig)(nil), // 6: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIConfig
+ (*options.Swagger)(nil), // 7: grpc.gateway.protoc_gen_openapiv2.options.Swagger
+ (*options.Operation)(nil), // 8: grpc.gateway.protoc_gen_openapiv2.options.Operation
+ (*options.Schema)(nil), // 9: grpc.gateway.protoc_gen_openapiv2.options.Schema
+ (*options.Tag)(nil), // 10: grpc.gateway.protoc_gen_openapiv2.options.Tag
+ (*options.JSONSchema)(nil), // 11: grpc.gateway.protoc_gen_openapiv2.options.JSONSchema
+}
+var file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_depIdxs = []int32{
+ 7, // 0: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIFileOption.option:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Swagger
+ 8, // 1: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIMethodOption.option:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Operation
+ 9, // 2: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIMessageOption.option:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Schema
+ 10, // 3: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIServiceOption.option:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Tag
+ 11, // 4: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIFieldOption.option:type_name -> grpc.gateway.protoc_gen_openapiv2.options.JSONSchema
+ 0, // 5: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIOptions.file:type_name -> grpc.gateway.internal.descriptor.openapiconfig.OpenAPIFileOption
+ 1, // 6: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIOptions.method:type_name -> grpc.gateway.internal.descriptor.openapiconfig.OpenAPIMethodOption
+ 2, // 7: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIOptions.message:type_name -> grpc.gateway.internal.descriptor.openapiconfig.OpenAPIMessageOption
+ 3, // 8: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIOptions.service:type_name -> grpc.gateway.internal.descriptor.openapiconfig.OpenAPIServiceOption
+ 4, // 9: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIOptions.field:type_name -> grpc.gateway.internal.descriptor.openapiconfig.OpenAPIFieldOption
+ 5, // 10: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIConfig.openapi_options:type_name -> grpc.gateway.internal.descriptor.openapiconfig.OpenAPIOptions
+ 11, // [11:11] is the sub-list for method output_type
+ 11, // [11:11] is the sub-list for method input_type
+ 11, // [11:11] is the sub-list for extension type_name
+ 11, // [11:11] is the sub-list for extension extendee
+ 0, // [0:11] is the sub-list for field type_name
+}
+
+func init() { file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_init() }
+func file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_init() {
+ if File_gateway_internal_descriptor_openapiconfig_openapiconfig_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*OpenAPIFileOption); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*OpenAPIMethodOption); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*OpenAPIMessageOption); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*OpenAPIServiceOption); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*OpenAPIFieldOption); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*OpenAPIOptions); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*OpenAPIConfig); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 7,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_goTypes,
+ DependencyIndexes: file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_depIdxs,
+ MessageInfos: file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes,
+ }.Build()
+ File_gateway_internal_descriptor_openapiconfig_openapiconfig_proto = out.File
+ file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_rawDesc = nil
+ file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_goTypes = nil
+ file_gateway_internal_descriptor_openapiconfig_openapiconfig_proto_depIdxs = nil
+}
diff --git a/gateway/internal/descriptor/openapiconfig/openapiconfig.proto b/gateway/internal/descriptor/openapiconfig/openapiconfig.proto
new file mode 100644
index 0000000..f65a649
--- /dev/null
+++ b/gateway/internal/descriptor/openapiconfig/openapiconfig.proto
@@ -0,0 +1,51 @@
+syntax = "proto3";
+
+package grpc.gateway.internal.descriptor.openapiconfig;
+
+option go_package = "github.com/binchencoder/janus-gateway/gateway/internal/descriptor/openapiconfig";
+
+import "gateway/protoc-gen-openapiv2/options/openapiv2.proto";
+
+// OpenAPIFileOption represents OpenAPI options on a file
+message OpenAPIFileOption {
+ string file = 1;
+ grpc.gateway.protoc_gen_openapiv2.options.Swagger option = 2;
+}
+
+// OpenAPIMethodOption represents OpenAPI options on a method
+message OpenAPIMethodOption {
+ string method = 1;
+ grpc.gateway.protoc_gen_openapiv2.options.Operation option = 2;
+}
+
+// OpenAPIMessageOption represents OpenAPI options on a message
+message OpenAPIMessageOption {
+ string message = 1;
+ grpc.gateway.protoc_gen_openapiv2.options.Schema option = 2;
+}
+
+// OpenAPIServiceOption represents OpenAPI options on a service
+message OpenAPIServiceOption {
+ string service = 1; // ex: Service
+ grpc.gateway.protoc_gen_openapiv2.options.Tag option = 2;
+}
+
+// OpenAPIFieldOption represents OpenAPI options on a field
+message OpenAPIFieldOption {
+ string field = 1;
+ grpc.gateway.protoc_gen_openapiv2.options.JSONSchema option = 2;
+}
+
+// OpenAPIOptions represents OpenAPI protobuf options
+message OpenAPIOptions {
+ repeated OpenAPIFileOption file = 1;
+ repeated OpenAPIMethodOption method = 2;
+ repeated OpenAPIMessageOption message = 3;
+ repeated OpenAPIServiceOption service = 4;
+ repeated OpenAPIFieldOption field = 5;
+}
+
+// OpenAPIConfig represents a set of OpenAPI options
+message OpenAPIConfig {
+ OpenAPIOptions openapi_options = 1;
+}
diff --git a/gateway/internal/descriptor/registry.go b/gateway/internal/descriptor/registry.go
new file mode 100644
index 0000000..73a67fe
--- /dev/null
+++ b/gateway/internal/descriptor/registry.go
@@ -0,0 +1,769 @@
+package descriptor
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/golang/glog"
+ "github.com/grpc-ecosystem/grpc-gateway/v2/internal/codegenerator"
+
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor/openapiconfig"
+ "github.com/binchencoder/janus-gateway/gateway/internal/descriptor/openapiconfig"
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
+ "github.com/binchencoder/janus-gateway/gateway/protoc-gen-openapiv2/options"
+ // "google.golang.org/genproto/googleapis/api/annotations"
+ annotations "github.com/binchencoder/janus-gateway/httpoptions"
+ "google.golang.org/protobuf/compiler/protogen"
+ "google.golang.org/protobuf/types/descriptorpb"
+ "google.golang.org/protobuf/types/pluginpb"
+)
+
+// Registry is a registry of information extracted from pluginpb.CodeGeneratorRequest.
+type Registry struct {
+ // msgs is a mapping from fully-qualified message name to descriptor
+ msgs map[string]*Message
+
+ // enums is a mapping from fully-qualified enum name to descriptor
+ enums map[string]*Enum
+
+ // files is a mapping from file path to descriptor
+ files map[string]*File
+
+ // prefix is a prefix to be inserted to golang package paths generated from proto package names.
+ prefix string
+
+ // pkgMap is a user-specified mapping from file path to proto package.
+ pkgMap map[string]string
+
+ // pkgAliases is a mapping from package aliases to package paths in go which are already taken.
+ pkgAliases map[string]string
+
+ // allowDeleteBody permits http delete methods to have a body
+ allowDeleteBody bool
+
+ // externalHttpRules is a mapping from fully qualified service method names to additional HttpRules applicable besides the ones found in annotations.
+ externalHTTPRules map[string][]*annotations.HttpRule
+
+ // allowMerge generation one OpenAPI file out of multiple protos
+ allowMerge bool
+
+ // mergeFileName target OpenAPI file name after merge
+ mergeFileName string
+
+ // allowRepeatedFieldsInBody permits repeated field in body field path of `google.api.http` annotation option
+ allowRepeatedFieldsInBody bool
+
+ // includePackageInTags controls whether the package name defined in the `package` directive
+ // in the proto file can be prepended to the gRPC service name in the `Tags` field of every operation.
+ includePackageInTags bool
+
+ // repeatedPathParamSeparator specifies how path parameter repeated fields are separated
+ repeatedPathParamSeparator repeatedFieldSeparator
+
+ // useJSONNamesForFields if true json tag name is used for generating fields in OpenAPI definitions,
+ // otherwise the original proto name is used. It's helpful for synchronizing the OpenAPI definition
+ // with gRPC-Gateway response, if it uses json tags for marshaling.
+ useJSONNamesForFields bool
+
+ // openAPINamingStrategy is the naming strategy to use for assigning OpenAPI field and parameter names. This can be one of the following:
+ // - `legacy`: use the legacy naming strategy from protoc-gen-swagger, that generates unique but not necessarily
+ // maximally concise names. Components are concatenated directly, e.g., `MyOuterMessageMyNestedMessage`.
+ // - `simple`: use a simple heuristic for generating unique and concise names. Components are concatenated using
+ // dots as a separator, e.g., `MyOuterMesage.MyNestedMessage` (if `MyNestedMessage` alone is unique,
+ // `MyNestedMessage` will be used as the OpenAPI name).
+ // - `fqn`: always use the fully-qualified name of the proto message (leading dot removed) as the OpenAPI
+ // name.
+ openAPINamingStrategy string
+
+ // visibilityRestrictionSelectors is a map of selectors for `google.api.VisibilityRule`s that will be included in the OpenAPI output.
+ visibilityRestrictionSelectors map[string]bool
+
+ // useGoTemplate determines whether you want to use GO templates
+ // in your protofile comments
+ useGoTemplate bool
+
+ // enumsAsInts render enum as integer, as opposed to string
+ enumsAsInts bool
+
+ // omitEnumDefaultValue omits default value of enum
+ omitEnumDefaultValue bool
+
+ // disableDefaultErrors disables the generation of the default error types.
+ // This is useful for users who have defined custom error handling.
+ disableDefaultErrors bool
+
+ // simpleOperationIDs removes the service prefix from the generated
+ // operationIDs. This risks generating duplicate operationIDs.
+ simpleOperationIDs bool
+
+ standalone bool
+ // warnOnUnboundMethods causes the registry to emit warning logs if an RPC method
+ // has no HttpRule annotation.
+ warnOnUnboundMethods bool
+
+ // proto3OptionalNullable specifies whether Proto3 Optional fields should be marked as x-nullable.
+ proto3OptionalNullable bool
+
+ // fileOptions is a mapping of file name to additional OpenAPI file options
+ fileOptions map[string]*options.Swagger
+
+ // methodOptions is a mapping of fully-qualified method name to additional OpenAPI method options
+ methodOptions map[string]*options.Operation
+
+ // messageOptions is a mapping of fully-qualified message name to additional OpenAPI message options
+ messageOptions map[string]*options.Schema
+
+ //serviceOptions is a mapping of fully-qualified service name to additional OpenAPI service options
+ serviceOptions map[string]*options.Tag
+
+ // fieldOptions is a mapping of the fully-qualified name of the parent message concat
+ // field name and a period to additional OpenAPI field options
+ fieldOptions map[string]*options.JSONSchema
+
+ // generateUnboundMethods causes the registry to generate proxy methods even for
+ // RPC methods that have no HttpRule annotation.
+ generateUnboundMethods bool
+
+ // omitPackageDoc, if false, causes a package comment to be included in the generated code.
+ omitPackageDoc bool
+
+ // recursiveDepth sets the maximum depth of a field parameter
+ recursiveDepth int
+
+ // annotationMap is used to check for duplicate HTTP annotations
+ annotationMap map[annotationIdentifier]struct{}
+}
+
+type repeatedFieldSeparator struct {
+ name string
+ sep rune
+}
+
+type annotationIdentifier struct {
+ method string
+ pathTemplate string
+ service *Service
+}
+
+var (
+ // Reg is the global dictionary.
+ Reg *Registry
+)
+
+// NewRegistry returns a new Registry.
+func NewRegistry() *Registry {
+ return &Registry{
+ msgs: make(map[string]*Message),
+ enums: make(map[string]*Enum),
+ files: make(map[string]*File),
+ pkgMap: make(map[string]string),
+ pkgAliases: make(map[string]string),
+ externalHTTPRules: make(map[string][]*annotations.HttpRule),
+ openAPINamingStrategy: "legacy",
+ visibilityRestrictionSelectors: make(map[string]bool),
+ repeatedPathParamSeparator: repeatedFieldSeparator{
+ name: "csv",
+ sep: ',',
+ },
+ fileOptions: make(map[string]*options.Swagger),
+ methodOptions: make(map[string]*options.Operation),
+ messageOptions: make(map[string]*options.Schema),
+ serviceOptions: make(map[string]*options.Tag),
+ fieldOptions: make(map[string]*options.JSONSchema),
+ annotationMap: make(map[annotationIdentifier]struct{}),
+ recursiveDepth: 1000,
+ }
+}
+
+// Load loads definitions of services, methods, messages, enumerations and fields from "req".
+func (r *Registry) Load(req *pluginpb.CodeGeneratorRequest) error {
+ gen, err := protogen.Options{}.New(req)
+ if err != nil {
+ return err
+ }
+ // Note: keep in mind that this might be not enough because
+ // protogen.Plugin is used only to load files here.
+ // The support for features must be set on the pluginpb.CodeGeneratorResponse.
+ codegenerator.SetSupportedFeaturesOnPluginGen(gen)
+ return r.load(gen)
+}
+
+func (r *Registry) LoadFromPlugin(gen *protogen.Plugin) error {
+ return r.load(gen)
+}
+
+func (r *Registry) load(gen *protogen.Plugin) error {
+ for filePath, f := range gen.FilesByPath {
+ r.loadFile(filePath, f)
+ }
+
+ for filePath, f := range gen.FilesByPath {
+ if !f.Generate {
+ continue
+ }
+ file := r.files[filePath]
+ if err := r.loadServices(file); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// loadFile loads messages, enumerations and fields from "file".
+// It does not loads services and methods in "file". You need to call
+// loadServices after loadFiles is called for all files to load services and methods.
+func (r *Registry) loadFile(filePath string, file *protogen.File) {
+ pkg := GoPackage{
+ Path: string(file.GoImportPath),
+ Name: string(file.GoPackageName),
+ }
+ if r.standalone {
+ pkg.Alias = "ext" + strings.Title(pkg.Name)
+ }
+
+ if err := r.ReserveGoPackageAlias(pkg.Name, pkg.Path); err != nil {
+ for i := 0; ; i++ {
+ alias := fmt.Sprintf("%s_%d", pkg.Name, i)
+ if err := r.ReserveGoPackageAlias(alias, pkg.Path); err == nil {
+ pkg.Alias = alias
+ break
+ }
+ }
+ }
+ f := &File{
+ FileDescriptorProto: file.Proto,
+ GoPkg: pkg,
+ GeneratedFilenamePrefix: file.GeneratedFilenamePrefix,
+ }
+
+ r.files[filePath] = f
+ r.registerMsg(f, nil, file.Proto.MessageType)
+ r.registerEnum(f, nil, file.Proto.EnumType)
+}
+
+func (r *Registry) registerMsg(file *File, outerPath []string, msgs []*descriptorpb.DescriptorProto) {
+ for i, md := range msgs {
+ m := &Message{
+ File: file,
+ Outers: outerPath,
+ DescriptorProto: md,
+ Index: i,
+ ForcePrefixedName: r.standalone,
+ }
+ for _, fd := range md.GetField() {
+ rule, _ := extractFieldRules(fd)
+ var rules []*Rule
+ if rule != nil {
+ for _, r := range rule.Rules {
+ rules = append(rules, &Rule{rule: r})
+ }
+ }
+ m.Fields = append(m.Fields, &Field{
+ Message: m,
+ FieldDescriptorProto: fd,
+ ForcePrefixedName: r.standalone,
+ Rules: rules,
+ })
+ }
+ file.Messages = append(file.Messages, m)
+ r.msgs[m.FQMN()] = m
+ glog.V(1).Infof("register name: %s", m.FQMN())
+
+ var outers []string
+ outers = append(outers, outerPath...)
+ outers = append(outers, m.GetName())
+ r.registerMsg(file, outers, m.GetNestedType())
+ r.registerEnum(file, outers, m.GetEnumType())
+ }
+}
+
+func (r *Registry) registerEnum(file *File, outerPath []string, enums []*descriptorpb.EnumDescriptorProto) {
+ for i, ed := range enums {
+ e := &Enum{
+ File: file,
+ Outers: outerPath,
+ EnumDescriptorProto: ed,
+ Index: i,
+ ForcePrefixedName: r.standalone,
+ }
+ file.Enums = append(file.Enums, e)
+ r.enums[e.FQEN()] = e
+ glog.V(1).Infof("register enum name: %s", e.FQEN())
+ }
+}
+
+// LookupMsg looks up a message type by "name".
+// It tries to resolve "name" from "location" if "name" is a relative message name.
+func (r *Registry) LookupMsg(location, name string) (*Message, error) {
+ glog.V(1).Infof("lookup %s from %s", name, location)
+ if strings.HasPrefix(name, ".") {
+ m, ok := r.msgs[name]
+ if !ok {
+ return nil, fmt.Errorf("no message found: %s", name)
+ }
+ return m, nil
+ }
+
+ if !strings.HasPrefix(location, ".") {
+ location = fmt.Sprintf(".%s", location)
+ }
+ components := strings.Split(location, ".")
+ for len(components) > 0 {
+ fqmn := strings.Join(append(components, name), ".")
+ if m, ok := r.msgs[fqmn]; ok {
+ return m, nil
+ }
+ components = components[:len(components)-1]
+ }
+ return nil, fmt.Errorf("no message found: %s", name)
+}
+
+// LookupEnum looks up a enum type by "name".
+// It tries to resolve "name" from "location" if "name" is a relative enum name.
+func (r *Registry) LookupEnum(location, name string) (*Enum, error) {
+ glog.V(1).Infof("lookup enum %s from %s", name, location)
+ if strings.HasPrefix(name, ".") {
+ e, ok := r.enums[name]
+ if !ok {
+ return nil, fmt.Errorf("no enum found: %s", name)
+ }
+ return e, nil
+ }
+
+ if !strings.HasPrefix(location, ".") {
+ location = fmt.Sprintf(".%s", location)
+ }
+ components := strings.Split(location, ".")
+ for len(components) > 0 {
+ fqen := strings.Join(append(components, name), ".")
+ if e, ok := r.enums[fqen]; ok {
+ return e, nil
+ }
+ components = components[:len(components)-1]
+ }
+ return nil, fmt.Errorf("no enum found: %s", name)
+}
+
+// LookupFile looks up a file by name.
+func (r *Registry) LookupFile(name string) (*File, error) {
+ f, ok := r.files[name]
+ if !ok {
+ return nil, fmt.Errorf("no such file given: %s", name)
+ }
+ return f, nil
+}
+
+// LookupExternalHTTPRules looks up external http rules by fully qualified service method name
+func (r *Registry) LookupExternalHTTPRules(qualifiedMethodName string) []*annotations.HttpRule {
+ return r.externalHTTPRules[qualifiedMethodName]
+}
+
+// AddExternalHTTPRule adds an external http rule for the given fully qualified service method name
+func (r *Registry) AddExternalHTTPRule(qualifiedMethodName string, rule *annotations.HttpRule) {
+ r.externalHTTPRules[qualifiedMethodName] = append(r.externalHTTPRules[qualifiedMethodName], rule)
+}
+
+// UnboundExternalHTTPRules returns the list of External HTTPRules
+// which does not have a matching method in the registry
+func (r *Registry) UnboundExternalHTTPRules() []string {
+ allServiceMethods := make(map[string]struct{})
+ for _, f := range r.files {
+ for _, s := range f.GetService() {
+ svc := &Service{File: f, ServiceDescriptorProto: s}
+ for _, m := range s.GetMethod() {
+ method := &Method{Service: svc, MethodDescriptorProto: m}
+ allServiceMethods[method.FQMN()] = struct{}{}
+ }
+ }
+ }
+
+ var missingMethods []string
+ for httpRuleMethod := range r.externalHTTPRules {
+ if _, ok := allServiceMethods[httpRuleMethod]; !ok {
+ missingMethods = append(missingMethods, httpRuleMethod)
+ }
+ }
+ return missingMethods
+}
+
+// AddPkgMap adds a mapping from a .proto file to proto package name.
+func (r *Registry) AddPkgMap(file, protoPkg string) {
+ r.pkgMap[file] = protoPkg
+}
+
+// SetPrefix registers the prefix to be added to go package paths generated from proto package names.
+func (r *Registry) SetPrefix(prefix string) {
+ r.prefix = prefix
+}
+
+// SetStandalone registers standalone flag to control package prefix
+func (r *Registry) SetStandalone(standalone bool) {
+ r.standalone = standalone
+}
+
+// SetRecursiveDepth records the max recursion count
+func (r *Registry) SetRecursiveDepth(count int) {
+ r.recursiveDepth = count
+}
+
+// GetRecursiveDepth returns the max recursion count
+func (r *Registry) GetRecursiveDepth() int {
+ return r.recursiveDepth
+}
+
+// ReserveGoPackageAlias reserves the unique alias of go package.
+// If succeeded, the alias will be never used for other packages in generated go files.
+// If failed, the alias is already taken by another package, so you need to use another
+// alias for the package in your go files.
+func (r *Registry) ReserveGoPackageAlias(alias, pkgpath string) error {
+ if taken, ok := r.pkgAliases[alias]; ok {
+ if taken == pkgpath {
+ return nil
+ }
+ return fmt.Errorf("package name %s is already taken. Use another alias", alias)
+ }
+ r.pkgAliases[alias] = pkgpath
+ return nil
+}
+
+// GetAllFQMNs returns a list of all FQMNs
+func (r *Registry) GetAllFQMNs() []string {
+ var keys []string
+ for k := range r.msgs {
+ keys = append(keys, k)
+ }
+ return keys
+}
+
+// GetAllFQENs returns a list of all FQENs
+func (r *Registry) GetAllFQENs() []string {
+ var keys []string
+ for k := range r.enums {
+ keys = append(keys, k)
+ }
+ return keys
+}
+
+// SetAllowDeleteBody controls whether http delete methods may have a
+// body or fail loading if encountered.
+func (r *Registry) SetAllowDeleteBody(allow bool) {
+ r.allowDeleteBody = allow
+}
+
+// SetAllowMerge controls whether generation one OpenAPI file out of multiple protos
+func (r *Registry) SetAllowMerge(allow bool) {
+ r.allowMerge = allow
+}
+
+// IsAllowMerge whether generation one OpenAPI file out of multiple protos
+func (r *Registry) IsAllowMerge() bool {
+ return r.allowMerge
+}
+
+// SetMergeFileName controls the target OpenAPI file name out of multiple protos
+func (r *Registry) SetMergeFileName(mergeFileName string) {
+ r.mergeFileName = mergeFileName
+}
+
+// SetAllowRepeatedFieldsInBody controls whether repeated field can be used
+// in `body` and `response_body` (`google.api.http` annotation option) field path or not
+func (r *Registry) SetAllowRepeatedFieldsInBody(allow bool) {
+ r.allowRepeatedFieldsInBody = allow
+}
+
+// IsAllowRepeatedFieldsInBody checks if repeated field can be used
+// in `body` and `response_body` (`google.api.http` annotation option) field path or not
+func (r *Registry) IsAllowRepeatedFieldsInBody() bool {
+ return r.allowRepeatedFieldsInBody
+}
+
+// SetIncludePackageInTags controls whether the package name defined in the `package` directive
+// in the proto file can be prepended to the gRPC service name in the `Tags` field of every operation.
+func (r *Registry) SetIncludePackageInTags(allow bool) {
+ r.includePackageInTags = allow
+}
+
+// IsIncludePackageInTags checks whether the package name defined in the `package` directive
+// in the proto file can be prepended to the gRPC service name in the `Tags` field of every operation.
+func (r *Registry) IsIncludePackageInTags() bool {
+ return r.includePackageInTags
+}
+
+// GetRepeatedPathParamSeparator returns a rune spcifying how
+// path parameter repeated fields are separated.
+func (r *Registry) GetRepeatedPathParamSeparator() rune {
+ return r.repeatedPathParamSeparator.sep
+}
+
+// GetRepeatedPathParamSeparatorName returns the name path parameter repeated
+// fields repeatedFieldSeparator. I.e. 'csv', 'pipe', 'ssv' or 'tsv'
+func (r *Registry) GetRepeatedPathParamSeparatorName() string {
+ return r.repeatedPathParamSeparator.name
+}
+
+// SetRepeatedPathParamSeparator sets how path parameter repeated fields are
+// separated. Allowed names are 'csv', 'pipe', 'ssv' and 'tsv'.
+func (r *Registry) SetRepeatedPathParamSeparator(name string) error {
+ var sep rune
+ switch name {
+ case "csv":
+ sep = ','
+ case "pipes":
+ sep = '|'
+ case "ssv":
+ sep = ' '
+ case "tsv":
+ sep = '\t'
+ default:
+ return fmt.Errorf("unknown repeated path parameter separator: %s", name)
+ }
+ r.repeatedPathParamSeparator = repeatedFieldSeparator{
+ name: name,
+ sep: sep,
+ }
+ return nil
+}
+
+// SetUseJSONNamesForFields sets useJSONNamesForFields
+func (r *Registry) SetUseJSONNamesForFields(use bool) {
+ r.useJSONNamesForFields = use
+}
+
+// GetUseJSONNamesForFields returns useJSONNamesForFields
+func (r *Registry) GetUseJSONNamesForFields() bool {
+ return r.useJSONNamesForFields
+}
+
+// SetUseFQNForOpenAPIName sets useFQNForOpenAPIName
+// Deprecated: use SetOpenAPINamingStrategy instead.
+func (r *Registry) SetUseFQNForOpenAPIName(use bool) {
+ r.openAPINamingStrategy = "fqn"
+}
+
+// GetUseFQNForOpenAPIName returns useFQNForOpenAPIName
+// Deprecated: Use GetOpenAPINamingStrategy().
+func (r *Registry) GetUseFQNForOpenAPIName() bool {
+ return r.openAPINamingStrategy == "fqn"
+}
+
+// GetMergeFileName return the target merge OpenAPI file name
+func (r *Registry) GetMergeFileName() string {
+ return r.mergeFileName
+}
+
+// SetOpenAPINamingStrategy sets the naming strategy to be used.
+func (r *Registry) SetOpenAPINamingStrategy(strategy string) {
+ r.openAPINamingStrategy = strategy
+}
+
+// GetOpenAPINamingStrategy retrieves the naming strategy that is in use.
+func (r *Registry) GetOpenAPINamingStrategy() string {
+ return r.openAPINamingStrategy
+}
+
+// SetUseGoTemplate sets useGoTemplate
+func (r *Registry) SetUseGoTemplate(use bool) {
+ r.useGoTemplate = use
+}
+
+// GetUseGoTemplate returns useGoTemplate
+func (r *Registry) GetUseGoTemplate() bool {
+ return r.useGoTemplate
+}
+
+// SetEnumsAsInts set enumsAsInts
+func (r *Registry) SetEnumsAsInts(enumsAsInts bool) {
+ r.enumsAsInts = enumsAsInts
+}
+
+// GetEnumsAsInts returns enumsAsInts
+func (r *Registry) GetEnumsAsInts() bool {
+ return r.enumsAsInts
+}
+
+// SetOmitEnumDefaultValue sets omitEnumDefaultValue
+func (r *Registry) SetOmitEnumDefaultValue(omit bool) {
+ r.omitEnumDefaultValue = omit
+}
+
+// GetOmitEnumDefaultValue returns omitEnumDefaultValue
+func (r *Registry) GetOmitEnumDefaultValue() bool {
+ return r.omitEnumDefaultValue
+}
+
+// SetVisibilityRestrictionSelectors sets the visibility restriction selectors.
+func (r *Registry) SetVisibilityRestrictionSelectors(selectors []string) {
+ r.visibilityRestrictionSelectors = make(map[string]bool)
+ for _, selector := range selectors {
+ r.visibilityRestrictionSelectors[strings.TrimSpace(selector)] = true
+ }
+}
+
+// GetVisibilityRestrictionSelectors retrieves he visibility restriction selectors.
+func (r *Registry) GetVisibilityRestrictionSelectors() map[string]bool {
+ return r.visibilityRestrictionSelectors
+}
+
+// SetDisableDefaultErrors sets disableDefaultErrors
+func (r *Registry) SetDisableDefaultErrors(use bool) {
+ r.disableDefaultErrors = use
+}
+
+// GetDisableDefaultErrors returns disableDefaultErrors
+func (r *Registry) GetDisableDefaultErrors() bool {
+ return r.disableDefaultErrors
+}
+
+// SetSimpleOperationIDs sets simpleOperationIDs
+func (r *Registry) SetSimpleOperationIDs(use bool) {
+ r.simpleOperationIDs = use
+}
+
+// GetSimpleOperationIDs returns simpleOperationIDs
+func (r *Registry) GetSimpleOperationIDs() bool {
+ return r.simpleOperationIDs
+}
+
+// SetWarnOnUnboundMethods sets warnOnUnboundMethods
+func (r *Registry) SetWarnOnUnboundMethods(warn bool) {
+ r.warnOnUnboundMethods = warn
+}
+
+// SetGenerateUnboundMethods sets generateUnboundMethods
+func (r *Registry) SetGenerateUnboundMethods(generate bool) {
+ r.generateUnboundMethods = generate
+}
+
+// SetOmitPackageDoc controls whether the generated code contains a package comment (if set to false, it will contain one)
+func (r *Registry) SetOmitPackageDoc(omit bool) {
+ r.omitPackageDoc = omit
+}
+
+// GetOmitPackageDoc returns whether a package comment will be omitted from the generated code
+func (r *Registry) GetOmitPackageDoc() bool {
+ return r.omitPackageDoc
+}
+
+// SetProto3OptionalNullable set proto3OtionalNullable
+func (r *Registry) SetProto3OptionalNullable(proto3OtionalNullable bool) {
+ r.proto3OptionalNullable = proto3OtionalNullable
+}
+
+// GetProto3OptionalNullable returns proto3OtionalNullable
+func (r *Registry) GetProto3OptionalNullable() bool {
+ return r.proto3OptionalNullable
+}
+
+// RegisterOpenAPIOptions registers OpenAPI options
+func (r *Registry) RegisterOpenAPIOptions(opts *openapiconfig.OpenAPIOptions) error {
+ if opts == nil {
+ return nil
+ }
+
+ for _, opt := range opts.File {
+ if _, ok := r.files[opt.File]; !ok {
+ return fmt.Errorf("no file %s found", opt.File)
+ }
+ r.fileOptions[opt.File] = opt.Option
+ }
+
+ // build map of all registered methods
+ methods := make(map[string]struct{})
+ services := make(map[string]struct{})
+ for _, f := range r.files {
+ for _, s := range f.Services {
+ services[s.FQSN()] = struct{}{}
+ for _, m := range s.Methods {
+ methods[m.FQMN()] = struct{}{}
+ }
+ }
+ }
+
+ for _, opt := range opts.Method {
+ qualifiedMethod := "." + opt.Method
+ if _, ok := methods[qualifiedMethod]; !ok {
+ return fmt.Errorf("no method %s found", opt.Method)
+ }
+ r.methodOptions[qualifiedMethod] = opt.Option
+ }
+
+ for _, opt := range opts.Message {
+ qualifiedMessage := "." + opt.Message
+ if _, ok := r.msgs[qualifiedMessage]; !ok {
+ return fmt.Errorf("no message %s found", opt.Message)
+ }
+ r.messageOptions[qualifiedMessage] = opt.Option
+ }
+
+ for _, opt := range opts.Service {
+ qualifiedService := "." + opt.Service
+ if _, ok := services[qualifiedService]; !ok {
+ return fmt.Errorf("no service %s found", opt.Service)
+ }
+ r.serviceOptions[qualifiedService] = opt.Option
+ }
+
+ // build map of all registered fields
+ fields := make(map[string]struct{})
+ for _, m := range r.msgs {
+ for _, f := range m.Fields {
+ fields[f.FQFN()] = struct{}{}
+ }
+ }
+ for _, opt := range opts.Field {
+ qualifiedField := "." + opt.Field
+ if _, ok := fields[qualifiedField]; !ok {
+ return fmt.Errorf("no field %s found", opt.Field)
+ }
+ r.fieldOptions[qualifiedField] = opt.Option
+ }
+ return nil
+}
+
+// GetOpenAPIFileOption returns a registered OpenAPI option for a file
+func (r *Registry) GetOpenAPIFileOption(file string) (*options.Swagger, bool) {
+ opt, ok := r.fileOptions[file]
+ return opt, ok
+}
+
+// GetOpenAPIMethodOption returns a registered OpenAPI option for a method
+func (r *Registry) GetOpenAPIMethodOption(qualifiedMethod string) (*options.Operation, bool) {
+ opt, ok := r.methodOptions[qualifiedMethod]
+ return opt, ok
+}
+
+// GetOpenAPIMessageOption returns a registered OpenAPI option for a message
+func (r *Registry) GetOpenAPIMessageOption(qualifiedMessage string) (*options.Schema, bool) {
+ opt, ok := r.messageOptions[qualifiedMessage]
+ return opt, ok
+}
+
+// GetOpenAPIServiceOption returns a registered OpenAPI option for a service
+func (r *Registry) GetOpenAPIServiceOption(qualifiedService string) (*options.Tag, bool) {
+ opt, ok := r.serviceOptions[qualifiedService]
+ return opt, ok
+}
+
+// GetOpenAPIFieldOption returns a registered OpenAPI option for a field
+func (r *Registry) GetOpenAPIFieldOption(qualifiedField string) (*options.JSONSchema, bool) {
+ opt, ok := r.fieldOptions[qualifiedField]
+ return opt, ok
+}
+
+func (r *Registry) FieldName(f *Field) string {
+ if r.useJSONNamesForFields {
+ return f.GetJsonName()
+ }
+ return f.GetName()
+}
+
+func (r *Registry) CheckDuplicateAnnotation(httpMethod string, httpTemplate string, svc *Service) error {
+ a := annotationIdentifier{method: httpMethod, pathTemplate: httpTemplate, service: svc}
+ _, ok := r.annotationMap[a]
+ if ok {
+ return fmt.Errorf("duplicate annotation: method=%s, template=%s", httpMethod, httpTemplate)
+ }
+ r.annotationMap[a] = struct{}{}
+ return nil
+}
diff --git a/gateway/protoc-gen-grpc-gateway/descriptor/registry_test.go b/gateway/internal/descriptor/registry_test.go
similarity index 53%
rename from gateway/protoc-gen-grpc-gateway/descriptor/registry_test.go
rename to gateway/internal/descriptor/registry_test.go
index 16e7665..a87be10 100644
--- a/gateway/protoc-gen-grpc-gateway/descriptor/registry_test.go
+++ b/gateway/internal/descriptor/registry_test.go
@@ -3,26 +3,44 @@ package descriptor
import (
"testing"
- "github.com/golang/protobuf/proto"
- descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
- plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor/openapiconfig"
+ "github.com/binchencoder/janus-gateway/gateway/internal/descriptor/openapiconfig"
+ "google.golang.org/protobuf/compiler/protogen"
+ "google.golang.org/protobuf/encoding/prototext"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/types/descriptorpb"
+ "google.golang.org/protobuf/types/pluginpb"
)
-func loadFile(t *testing.T, reg *Registry, src string) *descriptor.FileDescriptorProto {
- var file descriptor.FileDescriptorProto
- if err := proto.UnmarshalText(src, &file); err != nil {
- t.Fatalf("proto.UnmarshalText(%s, &file) failed with %v; want success", src, err)
+func newGeneratorFromSources(req *pluginpb.CodeGeneratorRequest, sources ...string) (*protogen.Plugin, error) {
+ for _, src := range sources {
+ var fd descriptorpb.FileDescriptorProto
+ if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
+ return nil, err
+ }
+ req.FileToGenerate = append(req.FileToGenerate, fd.GetName())
+ req.ProtoFile = append(req.ProtoFile, &fd)
}
- reg.loadFile(&file)
- return &file
+ return protogen.Options{}.New(req)
}
-func load(t *testing.T, reg *Registry, src string) error {
- var req plugin.CodeGeneratorRequest
- if err := proto.UnmarshalText(src, &req); err != nil {
- t.Fatalf("proto.UnmarshalText(%s, &file) failed with %v; want success", src, err)
+func loadFileWithCodeGeneratorRequest(t *testing.T, reg *Registry, req *pluginpb.CodeGeneratorRequest, sources ...string) []*descriptorpb.FileDescriptorProto {
+ t.Helper()
+ plugin, err := newGeneratorFromSources(req, sources...)
+ if err != nil {
+ t.Fatalf("failed to create a generator: %v", err)
+ }
+ err = reg.LoadFromPlugin(plugin)
+ if err != nil {
+ t.Fatalf("failed to Registry.LoadFromPlugin(): %v", err)
}
- return reg.Load(&req)
+ return plugin.Request.ProtoFile
+}
+
+func loadFile(t *testing.T, reg *Registry, src string) *descriptorpb.FileDescriptorProto {
+ t.Helper()
+ fds := loadFileWithCodeGeneratorRequest(t, reg, &pluginpb.CodeGeneratorRequest{}, src)
+ return fds[0]
}
func TestLoadFile(t *testing.T) {
@@ -30,6 +48,7 @@ func TestLoadFile(t *testing.T) {
fd := loadFile(t, reg, `
name: 'example.proto'
package: 'example'
+ options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example' >
message_type <
name: 'ExampleMessage'
field <
@@ -46,7 +65,7 @@ func TestLoadFile(t *testing.T) {
t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
return
}
- wantPkg := GoPackage{Path: ".", Name: "example"}
+ wantPkg := GoPackage{Path: "github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example", Name: "example"}
if got, want := file.GoPkg, wantPkg; got != want {
t.Errorf("file.GoPkg = %#v; want %#v", got, want)
}
@@ -86,6 +105,7 @@ func TestLoadFileNestedPackage(t *testing.T) {
loadFile(t, reg, `
name: 'example.proto'
package: 'example.nested.nested2'
+ options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example.nested.nested2' >
`)
file := reg.files["example.proto"]
@@ -93,7 +113,7 @@ func TestLoadFileNestedPackage(t *testing.T) {
t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
return
}
- wantPkg := GoPackage{Path: ".", Name: "example_nested_nested2"}
+ wantPkg := GoPackage{Path: "github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example.nested.nested2", Name: "example_nested_nested2"}
if got, want := file.GoPkg, wantPkg; got != want {
t.Errorf("file.GoPkg = %#v; want %#v", got, want)
}
@@ -104,6 +124,7 @@ func TestLoadFileWithDir(t *testing.T) {
loadFile(t, reg, `
name: 'path/to/example.proto'
package: 'example'
+ options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example' >
`)
file := reg.files["path/to/example.proto"]
@@ -111,7 +132,7 @@ func TestLoadFileWithDir(t *testing.T) {
t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
return
}
- wantPkg := GoPackage{Path: "path/to", Name: "example"}
+ wantPkg := GoPackage{Path: "github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example", Name: "example"}
if got, want := file.GoPkg, wantPkg; got != want {
t.Errorf("file.GoPkg = %#v; want %#v", got, want)
}
@@ -121,6 +142,7 @@ func TestLoadFileWithoutPackage(t *testing.T) {
reg := NewRegistry()
loadFile(t, reg, `
name: 'path/to/example_file.proto'
+ options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example_file' >
`)
file := reg.files["path/to/example_file.proto"]
@@ -128,7 +150,7 @@ func TestLoadFileWithoutPackage(t *testing.T) {
t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
return
}
- wantPkg := GoPackage{Path: "path/to", Name: "example_file"}
+ wantPkg := GoPackage{Path: "github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example_file", Name: "example_file"}
if got, want := file.GoPkg, wantPkg; got != want {
t.Errorf("file.GoPkg = %#v; want %#v", got, want)
}
@@ -136,10 +158,12 @@ func TestLoadFileWithoutPackage(t *testing.T) {
func TestLoadFileWithMapping(t *testing.T) {
reg := NewRegistry()
- reg.AddPkgMap("path/to/example.proto", "example.com/proj/example/proto")
- loadFile(t, reg, `
+ loadFileWithCodeGeneratorRequest(t, reg, &pluginpb.CodeGeneratorRequest{
+ Parameter: proto.String("Mpath/to/example.proto=example.com/proj/example/proto"),
+ }, `
name: 'path/to/example.proto'
package: 'example'
+ options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example' >
`)
file := reg.files["path/to/example.proto"]
@@ -158,10 +182,12 @@ func TestLoadFileWithPackageNameCollision(t *testing.T) {
loadFile(t, reg, `
name: 'path/to/another.proto'
package: 'example'
+ options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example' >
`)
loadFile(t, reg, `
name: 'path/to/example.proto'
package: 'example'
+ options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example' >
`)
if err := reg.ReserveGoPackageAlias("ioutil", "io/ioutil"); err != nil {
t.Fatalf("reg.ReserveGoPackageAlias(%q) failed with %v; want success", "ioutil", err)
@@ -169,6 +195,7 @@ func TestLoadFileWithPackageNameCollision(t *testing.T) {
loadFile(t, reg, `
name: 'path/to/ioutil.proto'
package: 'ioutil'
+ options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/ioutil' >
`)
file := reg.files["path/to/another.proto"]
@@ -176,7 +203,7 @@ func TestLoadFileWithPackageNameCollision(t *testing.T) {
t.Errorf("reg.files[%q] = nil; want non-nil", "path/to/another.proto")
return
}
- wantPkg := GoPackage{Path: "path/to", Name: "example"}
+ wantPkg := GoPackage{Path: "github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example", Name: "example"}
if got, want := file.GoPkg, wantPkg; got != want {
t.Errorf("file.GoPkg = %#v; want %#v", got, want)
}
@@ -186,7 +213,7 @@ func TestLoadFileWithPackageNameCollision(t *testing.T) {
t.Errorf("reg.files[%q] = nil; want non-nil", "path/to/example.proto")
return
}
- wantPkg = GoPackage{Path: "path/to", Name: "example", Alias: ""}
+ wantPkg = GoPackage{Path: "github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example", Name: "example", Alias: ""}
if got, want := file.GoPkg, wantPkg; got != want {
t.Errorf("file.GoPkg = %#v; want %#v", got, want)
}
@@ -196,7 +223,7 @@ func TestLoadFileWithPackageNameCollision(t *testing.T) {
t.Errorf("reg.files[%q] = nil; want non-nil", "path/to/ioutil.proto")
return
}
- wantPkg = GoPackage{Path: "path/to", Name: "ioutil", Alias: "ioutil_0"}
+ wantPkg = GoPackage{Path: "github.com/grpc-ecosystem/grpc-gateway/runtime/internal/ioutil", Name: "ioutil", Alias: "ioutil_0"}
if got, want := file.GoPkg, wantPkg; got != want {
t.Errorf("file.GoPkg = %#v; want %#v", got, want)
}
@@ -204,15 +231,16 @@ func TestLoadFileWithPackageNameCollision(t *testing.T) {
func TestLoadFileWithIdenticalGoPkg(t *testing.T) {
reg := NewRegistry()
- reg.AddPkgMap("path/to/another.proto", "example.com/example")
- reg.AddPkgMap("path/to/example.proto", "example.com/example")
- loadFile(t, reg, `
+ loadFileWithCodeGeneratorRequest(t, reg, &pluginpb.CodeGeneratorRequest{
+ Parameter: proto.String("Mpath/to/another.proto=example.com/example,Mpath/to/example.proto=example.com/example"),
+ }, `
name: 'path/to/another.proto'
package: 'example'
- `)
- loadFile(t, reg, `
+ options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example' >
+ `, `
name: 'path/to/example.proto'
package: 'example'
+ options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example' >
`)
file := reg.files["path/to/example.proto"]
@@ -236,29 +264,14 @@ func TestLoadFileWithIdenticalGoPkg(t *testing.T) {
}
}
-func TestLoadFileWithPrefix(t *testing.T) {
- reg := NewRegistry()
- reg.SetPrefix("third_party")
- loadFile(t, reg, `
- name: 'path/to/example.proto'
- package: 'example'
- `)
-
- file := reg.files["path/to/example.proto"]
- if file == nil {
- t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
- return
- }
- wantPkg := GoPackage{Path: "third_party/path/to", Name: "example"}
- if got, want := file.GoPkg, wantPkg; got != want {
- t.Errorf("file.GoPkg = %#v; want %#v", got, want)
- }
-}
-
+// TestLookupMsgWithoutPackage tests a case when there is no "package" directive.
+// In Go, it is required to have a generated package so we rely on
+// google.golang.org/protobuf/compiler/protogen to provide it.
func TestLookupMsgWithoutPackage(t *testing.T) {
reg := NewRegistry()
fd := loadFile(t, reg, `
name: 'example.proto'
+ options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example' >
message_type <
name: 'ExampleMessage'
field <
@@ -285,6 +298,7 @@ func TestLookupMsgWithNestedPackage(t *testing.T) {
fd := loadFile(t, reg, `
name: 'example.proto'
package: 'nested.nested2.mypackage'
+ options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example' >
message_type <
name: 'ExampleMessage'
field <
@@ -359,84 +373,6 @@ func TestLoadWithInconsistentTargetPackage(t *testing.T) {
req string
consistent bool
}{
- // root package, no explicit go package
- {
- req: `
- file_to_generate: 'a.proto'
- file_to_generate: 'b.proto'
- proto_file <
- name: 'a.proto'
- message_type < name: 'A' >
- service <
- name: "AService"
- method <
- name: "Meth"
- input_type: "A"
- output_type: "A"
- options <
- [google.api.http] < post: "/v1/a" body: "*" >
- >
- >
- >
- >
- proto_file <
- name: 'b.proto'
- message_type < name: 'B' >
- service <
- name: "BService"
- method <
- name: "Meth"
- input_type: "B"
- output_type: "B"
- options <
- [google.api.http] < post: "/v1/b" body: "*" >
- >
- >
- >
- >
- `,
- consistent: false,
- },
- // named package, no explicit go package
- {
- req: `
- file_to_generate: 'a.proto'
- file_to_generate: 'b.proto'
- proto_file <
- name: 'a.proto'
- package: 'example.foo'
- message_type < name: 'A' >
- service <
- name: "AService"
- method <
- name: "Meth"
- input_type: "A"
- output_type: "A"
- options <
- [google.api.http] < post: "/v1/a" body: "*" >
- >
- >
- >
- >
- proto_file <
- name: 'b.proto'
- package: 'example.foo'
- message_type < name: 'B' >
- service <
- name: "BService"
- method <
- name: "Meth"
- input_type: "B"
- output_type: "B"
- options <
- [google.api.http] < post: "/v1/b" body: "*" >
- >
- >
- >
- >
- `,
- consistent: true,
- },
// root package, explicit go package
{
req: `
@@ -444,7 +380,7 @@ func TestLoadWithInconsistentTargetPackage(t *testing.T) {
file_to_generate: 'b.proto'
proto_file <
name: 'a.proto'
- options < go_package: 'foo' >
+ options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example.foo' >
message_type < name: 'A' >
service <
name: "AService"
@@ -460,7 +396,7 @@ func TestLoadWithInconsistentTargetPackage(t *testing.T) {
>
proto_file <
name: 'b.proto'
- options < go_package: 'foo' >
+ options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example.foo' >
message_type < name: 'B' >
service <
name: "BService"
@@ -485,7 +421,7 @@ func TestLoadWithInconsistentTargetPackage(t *testing.T) {
proto_file <
name: 'a.proto'
package: 'example.foo'
- options < go_package: 'foo' >
+ options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example.foo' >
message_type < name: 'A' >
service <
name: "AService"
@@ -502,7 +438,7 @@ func TestLoadWithInconsistentTargetPackage(t *testing.T) {
proto_file <
name: 'b.proto'
package: 'example.foo'
- options < go_package: 'foo' >
+ options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example.foo' >
message_type < name: 'B' >
service <
name: "BService"
@@ -520,8 +456,11 @@ func TestLoadWithInconsistentTargetPackage(t *testing.T) {
consistent: true,
},
} {
- reg := NewRegistry()
- err := load(t, reg, spec.req)
+ var req pluginpb.CodeGeneratorRequest
+ if err := prototext.Unmarshal([]byte(spec.req), &req); err != nil {
+ t.Fatalf("proto.UnmarshalText(%s, &file) failed with %v; want success", spec.req, err)
+ }
+ _, err := newGeneratorFromSources(&req)
if got, want := err == nil, spec.consistent; got != want {
if want {
t.Errorf("reg.Load(%s) failed with %v; want success", spec.req, err)
@@ -532,7 +471,7 @@ func TestLoadWithInconsistentTargetPackage(t *testing.T) {
}
}
-func TestLoadOverridedPackageName(t *testing.T) {
+func TestLoadOverriddenPackageName(t *testing.T) {
reg := NewRegistry()
loadFile(t, reg, `
name: 'example.proto'
@@ -550,39 +489,231 @@ func TestLoadOverridedPackageName(t *testing.T) {
}
}
-func TestLoadSetInputPath(t *testing.T) {
+func TestLoadWithStandalone(t *testing.T) {
reg := NewRegistry()
- reg.SetImportPath("foo/examplepb")
+ reg.SetStandalone(true)
loadFile(t, reg, `
name: 'example.proto'
package: 'example'
+ options < go_package: 'example.com/xyz;pb' >
`)
file := reg.files["example.proto"]
if file == nil {
t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
return
}
- wantPkg := GoPackage{Path: ".", Name: "examplepb"}
+ wantPkg := GoPackage{Path: "example.com/xyz", Name: "pb", Alias: "extPb"}
if got, want := file.GoPkg, wantPkg; got != want {
t.Errorf("file.GoPkg = %#v; want %#v", got, want)
}
}
-func TestLoadGoPackageInputPath(t *testing.T) {
+func TestUnboundExternalHTTPRules(t *testing.T) {
reg := NewRegistry()
- reg.SetImportPath("examplepb")
+ methodName := ".example.ExampleService.Echo"
+ reg.AddExternalHTTPRule(methodName, nil)
+ assertStringSlice(t, "unbound external HTTP rules", reg.UnboundExternalHTTPRules(), []string{methodName})
loadFile(t, reg, `
- name: 'example.proto'
- package: 'example'
- options < go_package: 'example.com/xyz;pb' >
+ name: "path/to/example.proto",
+ package: "example"
+ options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example' >
+ message_type <
+ name: "StringMessage"
+ field <
+ name: "string"
+ number: 1
+ label: LABEL_OPTIONAL
+ type: TYPE_STRING
+ >
+ >
+ service <
+ name: "ExampleService"
+ method <
+ name: "Echo"
+ input_type: "StringMessage"
+ output_type: "StringMessage"
+ >
+ >
`)
- file := reg.files["example.proto"]
- if file == nil {
- t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
- return
+ assertStringSlice(t, "unbound external HTTP rules", reg.UnboundExternalHTTPRules(), []string{})
+}
+
+func TestRegisterOpenAPIOptions(t *testing.T) {
+ codeReqText := `file_to_generate: 'a.proto'
+ proto_file <
+ name: 'a.proto'
+ package: 'example.foo'
+ options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example' >
+ message_type <
+ name: 'ExampleMessage'
+ field <
+ name: 'str'
+ label: LABEL_OPTIONAL
+ type: TYPE_STRING
+ number: 1
+ >
+ >
+ service <
+ name: "AService"
+ method <
+ name: "Meth"
+ input_type: "ExampleMessage"
+ output_type: "ExampleMessage"
+ options <
+ [google.api.http] < post: "/v1/a" body: "*" >
+ >
+ >
+ >
+ >
+ `
+ var codeReq pluginpb.CodeGeneratorRequest
+ if err := prototext.Unmarshal([]byte(codeReqText), &codeReq); err != nil {
+ t.Fatalf("proto.UnmarshalText(%s, &file) failed with %v; want success", codeReqText, err)
}
- wantPkg := GoPackage{Path: "example.com/xyz", Name: "pb"}
- if got, want := file.GoPkg, wantPkg; got != want {
- t.Errorf("file.GoPkg = %#v; want %#v", got, want)
+
+ for _, tcase := range []struct {
+ options *openapiconfig.OpenAPIOptions
+ shouldErr bool
+ desc string
+ }{
+ {
+ desc: "handle nil options",
+ },
+ {
+ desc: "successfully add options if referenced entity exists",
+ options: &openapiconfig.OpenAPIOptions{
+ File: []*openapiconfig.OpenAPIFileOption{
+ {
+ File: "a.proto",
+ },
+ },
+ Method: []*openapiconfig.OpenAPIMethodOption{
+ {
+ Method: "example.foo.AService.Meth",
+ },
+ },
+ Message: []*openapiconfig.OpenAPIMessageOption{
+ {
+ Message: "example.foo.ExampleMessage",
+ },
+ },
+ Service: []*openapiconfig.OpenAPIServiceOption{
+ {
+ Service: "example.foo.AService",
+ },
+ },
+ Field: []*openapiconfig.OpenAPIFieldOption{
+ {
+ Field: "example.foo.ExampleMessage.str",
+ },
+ },
+ },
+ },
+ {
+ desc: "reject fully qualified names with leading \".\"",
+ options: &openapiconfig.OpenAPIOptions{
+ File: []*openapiconfig.OpenAPIFileOption{
+ {
+ File: "a.proto",
+ },
+ },
+ Method: []*openapiconfig.OpenAPIMethodOption{
+ {
+ Method: ".example.foo.AService.Meth",
+ },
+ },
+ Message: []*openapiconfig.OpenAPIMessageOption{
+ {
+ Message: ".example.foo.ExampleMessage",
+ },
+ },
+ Service: []*openapiconfig.OpenAPIServiceOption{
+ {
+ Service: ".example.foo.AService",
+ },
+ },
+ Field: []*openapiconfig.OpenAPIFieldOption{
+ {
+ Field: ".example.foo.ExampleMessage.str",
+ },
+ },
+ },
+ shouldErr: true,
+ },
+ {
+ desc: "error if file does not exist",
+ options: &openapiconfig.OpenAPIOptions{
+ File: []*openapiconfig.OpenAPIFileOption{
+ {
+ File: "b.proto",
+ },
+ },
+ },
+ shouldErr: true,
+ },
+ {
+ desc: "error if method does not exist",
+ options: &openapiconfig.OpenAPIOptions{
+ Method: []*openapiconfig.OpenAPIMethodOption{
+ {
+ Method: "example.foo.AService.Meth2",
+ },
+ },
+ },
+ shouldErr: true,
+ },
+ {
+ desc: "error if message does not exist",
+ options: &openapiconfig.OpenAPIOptions{
+ Message: []*openapiconfig.OpenAPIMessageOption{
+ {
+ Message: "example.foo.NonexistentMessage",
+ },
+ },
+ },
+ shouldErr: true,
+ },
+ {
+ desc: "error if service does not exist",
+ options: &openapiconfig.OpenAPIOptions{
+ Service: []*openapiconfig.OpenAPIServiceOption{
+ {
+ Service: "example.foo.AService1",
+ },
+ },
+ },
+ shouldErr: true,
+ },
+ {
+ desc: "error if field does not exist",
+ options: &openapiconfig.OpenAPIOptions{
+ Field: []*openapiconfig.OpenAPIFieldOption{
+ {
+ Field: "example.foo.ExampleMessage.str1",
+ },
+ },
+ },
+ shouldErr: true,
+ },
+ } {
+ t.Run(tcase.desc, func(t *testing.T) {
+ reg := NewRegistry()
+ loadFileWithCodeGeneratorRequest(t, reg, &codeReq)
+ err := reg.RegisterOpenAPIOptions(tcase.options)
+ if (err != nil) != tcase.shouldErr {
+ t.Fatalf("got unexpected error: %s", err)
+ }
+ })
+ }
+}
+
+func assertStringSlice(t *testing.T, message string, got, want []string) {
+ if len(got) != len(want) {
+ t.Errorf("%s = %#v len(%d); want %#v len(%d)", message, got, len(got), want, len(want))
+ }
+ for i := range want {
+ if got[i] != want[i] {
+ t.Errorf("%s[%d] = %#v; want %#v", message, i, got[i], want[i])
+ }
}
}
diff --git a/gateway/protoc-gen-grpc-gateway/descriptor/services.go b/gateway/internal/descriptor/services.go
similarity index 76%
rename from gateway/protoc-gen-grpc-gateway/descriptor/services.go
rename to gateway/internal/descriptor/services.go
index b895ec9..11c181e 100644
--- a/gateway/protoc-gen-grpc-gateway/descriptor/services.go
+++ b/gateway/internal/descriptor/services.go
@@ -6,14 +6,11 @@ import (
"strings"
"github.com/golang/glog"
- "github.com/golang/protobuf/proto"
- descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
-
- // "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule"
- "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/httprule"
-
+ "github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule"
// options "google.golang.org/genproto/googleapis/api/annotations"
- options "github.com/binchencoder/ease-gateway/httpoptions"
+ options "github.com/binchencoder/janus-gateway/httpoptions"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/types/descriptorpb"
)
var (
@@ -51,6 +48,7 @@ func (r *Registry) loadServices(file *File) error {
GenController: spec.GenController,
Balancer: spec.Balancer,
ServiceDescriptorProto: sd,
+ ForcePrefixedName: r.standalone,
}
for _, md := range sd.GetMethod() {
glog.V(2).Infof("Processing %s.%s", sd.GetName(), md.GetName())
@@ -64,7 +62,20 @@ func (r *Registry) loadServices(file *File) error {
optsList = append(optsList, opts)
}
if len(optsList) == 0 {
- glog.V(1).Infof("Found non-target method: %s.%s", svc.GetName(), md.GetName())
+ if r.generateUnboundMethods {
+ defaultOpts, err := defaultAPIOptions(svc, md)
+ if err != nil {
+ glog.Errorf("Failed to generate default HttpRule from %s.%s: %v", svc.GetName(), md.GetName(), err)
+ return err
+ }
+ optsList = append(optsList, defaultOpts)
+ } else {
+ logFn := glog.V(1).Infof
+ if r.warnOnUnboundMethods {
+ logFn = glog.Warningf
+ }
+ logFn("No HttpRule found for method: %s.%s", svc.GetName(), md.GetName())
+ }
}
meth, err := r.newMethod(svc, md, optsList, mopts)
if err != nil {
@@ -82,7 +93,7 @@ func (r *Registry) loadServices(file *File) error {
return nil
}
-func (r *Registry) newMethod(svc *Service, md *descriptor.MethodDescriptorProto, optsList []*options.HttpRule, mopts *options.ApiMethod) (*Method, error) {
+func (r *Registry) newMethod(svc *Service, md *descriptorpb.MethodDescriptorProto, optsList []*options.HttpRule, mopts *options.ApiMethod) (*Method, error) {
requestType, err := r.LookupMsg(svc.File.GetPackage(), md.GetInputType())
if err != nil {
return nil, err
@@ -222,7 +233,7 @@ func (r *Registry) newMethod(svc *Service, md *descriptor.MethodDescriptorProto,
return meth, nil
}
-func extractServiceSpec(svc *descriptor.ServiceDescriptorProto) (*options.ServiceSpec, error) {
+func extractServiceSpec(svc *descriptorpb.ServiceDescriptorProto) (*options.ServiceSpec, error) {
if svc.Options == nil {
glog.Errorf("extractServiceSpec svc.Options == nil, %+v", svc)
return nil, errNoServiceSpec
@@ -231,11 +242,8 @@ func extractServiceSpec(svc *descriptor.ServiceDescriptorProto) (*options.Servic
glog.Errorf("extractServiceSpec !proto.HasExtension == true, %+v", svc)
return nil, errNoServiceSpec
}
- spec, err := proto.GetExtension(svc.Options, options.E_ServiceSpec)
- if err != nil {
- return nil, err
- }
-
+ spec := proto.GetExtension(svc.Options, options.E_ServiceSpec)
+ // Extract janus gateway service spec options.
svcSpec, ok := spec.(*options.ServiceSpec)
if !ok {
return nil, fmt.Errorf("extension is %T; Want a service spec", spec)
@@ -243,17 +251,14 @@ func extractServiceSpec(svc *descriptor.ServiceDescriptorProto) (*options.Servic
return svcSpec, nil
}
-func extractFieldRules(field *descriptor.FieldDescriptorProto) (*options.ValidationRules, error) {
+func extractFieldRules(field *descriptorpb.FieldDescriptorProto) (*options.ValidationRules, error) {
if field.Options == nil {
return nil, nil
}
if !proto.HasExtension(field.Options, options.E_Rules) {
return nil, nil
}
- r, err := proto.GetExtension(field.Options, options.E_Rules)
- if err != nil {
- return nil, err
- }
+ r := proto.GetExtension(field.Options, options.E_Rules)
rules, ok := r.(*options.ValidationRules)
if !ok {
return nil, fmt.Errorf("Faile to extract rules: %v", rules)
@@ -261,17 +266,14 @@ func extractFieldRules(field *descriptor.FieldDescriptorProto) (*options.Validat
return rules, nil
}
-func extractAPIOptions(meth *descriptor.MethodDescriptorProto) (*options.HttpRule, *options.ApiMethod, error) {
+func extractAPIOptions(meth *descriptorpb.MethodDescriptorProto) (*options.HttpRule, *options.ApiMethod, error) {
if meth.Options == nil {
return nil, nil, nil
}
if !proto.HasExtension(meth.Options, options.E_Http) {
return nil, nil, nil
}
- ext, err := proto.GetExtension(meth.Options, options.E_Http)
- if err != nil {
- return nil, nil, err
- }
+ ext := proto.GetExtension(meth.Options, options.E_Http)
opts, ok := ext.(*options.HttpRule)
if !ok {
return nil, nil, fmt.Errorf("extension is %T; want an HttpRule", ext)
@@ -281,12 +283,8 @@ func extractAPIOptions(meth *descriptor.MethodDescriptorProto) (*options.HttpRul
if !proto.HasExtension(meth.Options, options.E_Method) {
return opts, mopts, nil
}
-
- // Extract ease gateway method options.
- m, err := proto.GetExtension(meth.Options, options.E_Method)
- if err != nil {
- return nil, nil, err
- }
+ // Extract janus gateway method options.
+ m := proto.GetExtension(meth.Options, options.E_Method)
mopts, ok = m.(*options.ApiMethod)
if !ok {
return nil, nil, fmt.Errorf("extension is %T; want an ApiMethod", ext)
@@ -294,6 +292,25 @@ func extractAPIOptions(meth *descriptor.MethodDescriptorProto) (*options.HttpRul
return opts, mopts, nil
}
+func defaultAPIOptions(svc *Service, md *descriptorpb.MethodDescriptorProto) (*options.HttpRule, error) {
+ // FQSN prefixes the service's full name with a '.', e.g.: '.example.ExampleService'
+ fqsn := strings.TrimPrefix(svc.FQSN(), ".")
+
+ // This generates an HttpRule that matches the gRPC mapping to HTTP/2 described in
+ // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests
+ // i.e.:
+ // * method is POST
+ // * path is "//"
+ // * body should contain the serialized request message
+ rule := &options.HttpRule{
+ Pattern: &options.HttpRule_Post{
+ Post: fmt.Sprintf("/%s/%s", fqsn, md.GetName()),
+ },
+ Body: "*",
+ }
+ return rule, nil
+}
+
func (r *Registry) newParam(meth *Method, path string) (Parameter, error) {
msg := meth.RequestType
fields, err := r.resolveFieldPath(msg, path, true)
@@ -306,12 +323,12 @@ func (r *Registry) newParam(meth *Method, path string) (Parameter, error) {
}
target := fields[l-1].Target
switch target.GetType() {
- case descriptor.FieldDescriptorProto_TYPE_MESSAGE, descriptor.FieldDescriptorProto_TYPE_GROUP:
+ case descriptorpb.FieldDescriptorProto_TYPE_MESSAGE, descriptorpb.FieldDescriptorProto_TYPE_GROUP:
glog.V(2).Infoln("found aggregate type:", target, target.TypeName)
if IsWellKnownType(*target.TypeName) {
glog.V(2).Infoln("found well known aggregate type:", target)
} else {
- return Parameter{}, fmt.Errorf("aggregate type %s in parameter of %s.%s: %s", target.Type, meth.Service.GetName(), meth.GetName(), path)
+ return Parameter{}, fmt.Errorf("%s.%s: %s is a protobuf message type. Protobuf message types cannot be used as path parameters, use a scalar value type (such as string) instead", meth.Service.GetName(), meth.GetName(), path)
}
}
return Parameter{
@@ -372,7 +389,7 @@ func (r *Registry) resolveFieldPath(msg *Message, path string, isPathParam bool)
if i > 0 {
f := result[i-1].Target
switch f.GetType() {
- case descriptor.FieldDescriptorProto_TYPE_MESSAGE, descriptor.FieldDescriptorProto_TYPE_GROUP:
+ case descriptorpb.FieldDescriptorProto_TYPE_MESSAGE, descriptorpb.FieldDescriptorProto_TYPE_GROUP:
var err error
msg, err = r.LookupMsg(msg.FQMN(), f.GetTypeName())
if err != nil {
@@ -388,9 +405,12 @@ func (r *Registry) resolveFieldPath(msg *Message, path string, isPathParam bool)
if f == nil {
return nil, fmt.Errorf("no field %q found in %s", path, root.GetName())
}
- if !(isPathParam || r.allowRepeatedFieldsInBody) && f.GetLabel() == descriptor.FieldDescriptorProto_LABEL_REPEATED {
+ if !(isPathParam || r.allowRepeatedFieldsInBody) && f.GetLabel() == descriptorpb.FieldDescriptorProto_LABEL_REPEATED {
return nil, fmt.Errorf("repeated field not allowed in field path: %s in %s", f.GetName(), path)
}
+ if isPathParam && f.GetProto3Optional() {
+ return nil, fmt.Errorf("optional field not allowed in field path: %s in %s", f.GetName(), path)
+ }
result = append(result, FieldPathComponent{Name: c, Target: f})
}
return result, nil
diff --git a/gateway/protoc-gen-grpc-gateway/descriptor/services_test.go b/gateway/internal/descriptor/services_test.go
similarity index 77%
rename from gateway/protoc-gen-grpc-gateway/descriptor/services_test.go
rename to gateway/internal/descriptor/services_test.go
index 3b69074..8ce91f1 100644
--- a/gateway/protoc-gen-grpc-gateway/descriptor/services_test.go
+++ b/gateway/internal/descriptor/services_test.go
@@ -2,12 +2,14 @@ package descriptor
import (
"reflect"
+ "strings"
"testing"
- "github.com/golang/protobuf/proto"
- descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
- // "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule"
- "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/httprule"
+ "github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule"
+ "google.golang.org/protobuf/compiler/protogen"
+ "google.golang.org/protobuf/encoding/prototext"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/types/descriptorpb"
)
func compilePath(t *testing.T, path string) httprule.Template {
@@ -18,10 +20,15 @@ func compilePath(t *testing.T, path string) httprule.Template {
return parsed.Compile()
}
-func testExtractServices(t *testing.T, input []*descriptor.FileDescriptorProto, target string, wantSvcs []*Service) {
- reg := NewRegistry()
+func testExtractServices(t *testing.T, input []*descriptorpb.FileDescriptorProto, target string, wantSvcs []*Service) {
+ testExtractServicesWithRegistry(t, NewRegistry(), input, target, wantSvcs)
+}
+
+func testExtractServicesWithRegistry(t *testing.T, reg *Registry, input []*descriptorpb.FileDescriptorProto, target string, wantSvcs []*Service) {
for _, file := range input {
- reg.loadFile(file)
+ reg.loadFile(file.GetName(), &protogen.File{
+ Proto: file,
+ })
}
err := reg.loadServices(reg.files[target])
if err != nil {
@@ -145,6 +152,9 @@ func crossLinkFixture(f *File) *File {
}
}
}
+ for _, e := range f.Enums {
+ e.File = f
+ }
return f
}
@@ -176,8 +186,8 @@ func TestExtractServicesSimple(t *testing.T) {
>
>
`
- var fd descriptor.FileDescriptorProto
- if err := proto.UnmarshalText(src, &fd); err != nil {
+ var fd descriptorpb.FileDescriptorProto
+ if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
}
msg := &Message{
@@ -217,7 +227,134 @@ func TestExtractServicesSimple(t *testing.T) {
}
crossLinkFixture(file)
- testExtractServices(t, []*descriptor.FileDescriptorProto{&fd}, "path/to/example.proto", file.Services)
+ testExtractServices(t, []*descriptorpb.FileDescriptorProto{&fd}, "path/to/example.proto", file.Services)
+}
+
+func TestExtractServicesWithoutAnnotation(t *testing.T) {
+ src := `
+ name: "path/to/example.proto",
+ package: "example"
+ message_type <
+ name: "StringMessage"
+ field <
+ name: "string"
+ number: 1
+ label: LABEL_OPTIONAL
+ type: TYPE_STRING
+ >
+ >
+ service <
+ name: "ExampleService"
+ method <
+ name: "Echo"
+ input_type: "StringMessage"
+ output_type: "StringMessage"
+ >
+ >
+ `
+ var fd descriptorpb.FileDescriptorProto
+ if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
+ t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
+ }
+ msg := &Message{
+ DescriptorProto: fd.MessageType[0],
+ Fields: []*Field{
+ {
+ FieldDescriptorProto: fd.MessageType[0].Field[0],
+ },
+ },
+ }
+ file := &File{
+ FileDescriptorProto: &fd,
+ GoPkg: GoPackage{
+ Path: "path/to/example.pb",
+ Name: "example_pb",
+ },
+ Messages: []*Message{msg},
+ Services: []*Service{
+ {
+ ServiceDescriptorProto: fd.Service[0],
+ Methods: []*Method{
+ {
+ MethodDescriptorProto: fd.Service[0].Method[0],
+ RequestType: msg,
+ ResponseType: msg,
+ },
+ },
+ },
+ },
+ }
+
+ crossLinkFixture(file)
+ testExtractServices(t, []*descriptorpb.FileDescriptorProto{&fd}, "path/to/example.proto", file.Services)
+}
+
+func TestExtractServicesGenerateUnboundMethods(t *testing.T) {
+ src := `
+ name: "path/to/example.proto",
+ package: "example"
+ message_type <
+ name: "StringMessage"
+ field <
+ name: "string"
+ number: 1
+ label: LABEL_OPTIONAL
+ type: TYPE_STRING
+ >
+ >
+ service <
+ name: "ExampleService"
+ method <
+ name: "Echo"
+ input_type: "StringMessage"
+ output_type: "StringMessage"
+ >
+ >
+ `
+ var fd descriptorpb.FileDescriptorProto
+ if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
+ t.Fatalf("prototext.Unmarshal (%s, &fd) failed with %v; want success", src, err)
+ }
+ msg := &Message{
+ DescriptorProto: fd.MessageType[0],
+ Fields: []*Field{
+ {
+ FieldDescriptorProto: fd.MessageType[0].Field[0],
+ },
+ },
+ }
+ file := &File{
+ FileDescriptorProto: &fd,
+ GoPkg: GoPackage{
+ Path: "path/to/example.pb",
+ Name: "example_pb",
+ },
+ Messages: []*Message{msg},
+ Services: []*Service{
+ {
+ ServiceDescriptorProto: fd.Service[0],
+ Methods: []*Method{
+ {
+ MethodDescriptorProto: fd.Service[0].Method[0],
+ RequestType: msg,
+ ResponseType: msg,
+ Bindings: []*Binding{
+ {
+ PathTmpl: compilePath(t, "/example.ExampleService/Echo"),
+ HTTPMethod: "POST",
+ Body: &Body{FieldPath: nil},
+ },
+ },
+ },
+ },
+ },
+ },
+ }
+
+ crossLinkFixture(file)
+ reg := NewRegistry()
+ reg.SetGenerateUnboundMethods(true)
+ testExtractServicesWithRegistry(t, reg, []*descriptorpb.FileDescriptorProto{&fd}, "path/to/example.proto", file.Services)
}
func TestExtractServicesCrossPackage(t *testing.T) {
@@ -262,11 +399,11 @@ func TestExtractServicesCrossPackage(t *testing.T) {
>
`,
}
- var fds []*descriptor.FileDescriptorProto
+ var fds []*descriptorpb.FileDescriptorProto
for _, src := range srcs {
- var fd descriptor.FileDescriptorProto
- if err := proto.UnmarshalText(src, &fd); err != nil {
- t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
+ var fd descriptorpb.FileDescriptorProto
+ if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
+ t.Fatalf("prototext.Unmarshal(%s, &fd) failed with %v; want success", src, err)
}
fds = append(fds, &fd)
}
@@ -368,8 +505,8 @@ func TestExtractServicesWithBodyPath(t *testing.T) {
>
>
`
- var fd descriptor.FileDescriptorProto
- if err := proto.UnmarshalText(src, &fd); err != nil {
+ var fd descriptorpb.FileDescriptorProto
+ if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
}
msg := &Message{
@@ -416,7 +553,7 @@ func TestExtractServicesWithBodyPath(t *testing.T) {
}
crossLinkFixture(file)
- testExtractServices(t, []*descriptor.FileDescriptorProto{&fd}, "path/to/example.proto", file.Services)
+ testExtractServices(t, []*descriptorpb.FileDescriptorProto{&fd}, "path/to/example.proto", file.Services)
}
func TestExtractServicesWithPathParam(t *testing.T) {
@@ -446,8 +583,8 @@ func TestExtractServicesWithPathParam(t *testing.T) {
>
>
`
- var fd descriptor.FileDescriptorProto
- if err := proto.UnmarshalText(src, &fd); err != nil {
+ var fd descriptorpb.FileDescriptorProto
+ if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
}
msg := &Message{
@@ -497,7 +634,7 @@ func TestExtractServicesWithPathParam(t *testing.T) {
}
crossLinkFixture(file)
- testExtractServices(t, []*descriptor.FileDescriptorProto{&fd}, "path/to/example.proto", file.Services)
+ testExtractServices(t, []*descriptorpb.FileDescriptorProto{&fd}, "path/to/example.proto", file.Services)
}
func TestExtractServicesWithAdditionalBinding(t *testing.T) {
@@ -535,8 +672,8 @@ func TestExtractServicesWithAdditionalBinding(t *testing.T) {
>
>
`
- var fd descriptor.FileDescriptorProto
- if err := proto.UnmarshalText(src, &fd); err != nil {
+ var fd descriptorpb.FileDescriptorProto
+ if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
}
msg := &Message{
@@ -607,7 +744,7 @@ func TestExtractServicesWithAdditionalBinding(t *testing.T) {
}
crossLinkFixture(file)
- testExtractServices(t, []*descriptor.FileDescriptorProto{&fd}, "path/to/example.proto", file.Services)
+ testExtractServices(t, []*descriptorpb.FileDescriptorProto{&fd}, "path/to/example.proto", file.Services)
}
func TestExtractServicesWithError(t *testing.T) {
@@ -906,14 +1043,14 @@ func TestExtractServicesWithError(t *testing.T) {
} {
reg := NewRegistry()
- var fds []*descriptor.FileDescriptorProto
for _, src := range spec.srcs {
- var fd descriptor.FileDescriptorProto
- if err := proto.UnmarshalText(src, &fd); err != nil {
+ var fd descriptorpb.FileDescriptorProto
+ if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
}
- reg.loadFile(&fd)
- fds = append(fds, &fd)
+ reg.loadFile(spec.target, &protogen.File{
+ Proto: &fd,
+ })
}
err := reg.loadServices(reg.files[spec.target])
if err == nil {
@@ -1088,12 +1225,14 @@ func TestResolveFieldPath(t *testing.T) {
wantErr: true,
},
} {
- var file descriptor.FileDescriptorProto
- if err := proto.UnmarshalText(spec.src, &file); err != nil {
+ var file descriptorpb.FileDescriptorProto
+ if err := prototext.Unmarshal([]byte(spec.src), &file); err != nil {
t.Fatalf("proto.Unmarshal(%s) failed with %v; want success", spec.src, err)
}
reg := NewRegistry()
- reg.loadFile(&file)
+ reg.loadFile(file.GetName(), &protogen.File{
+ Proto: &file,
+ })
f, err := reg.LookupFile(file.GetName())
if err != nil {
t.Fatalf("reg.LookupFile(%q) failed with %v; want success; on file=%s", file.GetName(), err, spec.src)
@@ -1190,14 +1329,14 @@ func TestExtractServicesWithDeleteBody(t *testing.T) {
reg := NewRegistry()
reg.SetAllowDeleteBody(spec.allowDeleteBody)
- var fds []*descriptor.FileDescriptorProto
for _, src := range spec.srcs {
- var fd descriptor.FileDescriptorProto
- if err := proto.UnmarshalText(src, &fd); err != nil {
+ var fd descriptorpb.FileDescriptorProto
+ if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
}
- reg.loadFile(&fd)
- fds = append(fds, &fd)
+ reg.loadFile(fd.GetName(), &protogen.File{
+ Proto: &fd,
+ })
}
err := reg.loadServices(reg.files[spec.target])
if spec.expectErr && err == nil {
@@ -1209,3 +1348,100 @@ func TestExtractServicesWithDeleteBody(t *testing.T) {
t.Log(err)
}
}
+
+func TestCauseErrorWithPathParam(t *testing.T) {
+ src := `
+ name: "path/to/example.proto",
+ package: "example"
+ message_type <
+ name: "TypeMessage"
+ field <
+ name: "message"
+ type: TYPE_MESSAGE
+ type_name: 'ExampleMessage'
+ number: 1,
+ label: LABEL_OPTIONAL
+ >
+ >
+ service <
+ name: "ExampleService"
+ method <
+ name: "Echo"
+ input_type: "TypeMessage"
+ output_type: "TypeMessage"
+ options <
+ [google.api.http] <
+ get: "/v1/example/echo/{message=*}"
+ >
+ >
+ >
+ >
+ `
+ var fd descriptorpb.FileDescriptorProto
+ if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
+ t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
+ }
+ target := "path/to/example.proto"
+ reg := NewRegistry()
+ input := []*descriptorpb.FileDescriptorProto{&fd}
+ reg.loadFile(fd.GetName(), &protogen.File{
+ Proto: &fd,
+ })
+ // switch this field to see the error
+ wantErr := true
+ err := reg.loadServices(reg.files[target])
+ if got, want := err != nil, wantErr; got != want {
+ if want {
+ t.Errorf("loadServices(%q, %q) succeeded; want an error", target, input)
+ }
+ t.Errorf("loadServices(%q, %q) failed with %v; want success", target, input, err)
+ }
+}
+
+func TestOptionalProto3URLPathMappingError(t *testing.T) {
+ src := `
+ name: "path/to/example.proto"
+ package: "example"
+ message_type <
+ name: "StringMessage"
+ field <
+ name: "field1"
+ number: 1
+ type: TYPE_STRING
+ proto3_optional: true
+ >
+ >
+ service <
+ name: "ExampleService"
+ method <
+ name: "Echo"
+ input_type: "StringMessage"
+ output_type: "StringMessage"
+ options <
+ [google.api.http] <
+ get: "/v1/example/echo/{field1=*}"
+ >
+ >
+ >
+ >
+ `
+ var fd descriptorpb.FileDescriptorProto
+ if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
+ t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
+ }
+ target := "path/to/example.proto"
+ reg := NewRegistry()
+ input := []*descriptorpb.FileDescriptorProto{&fd}
+ reg.loadFile(fd.GetName(), &protogen.File{
+ Proto: &fd,
+ })
+ wantErrMsg := "field not allowed in field path: field1 in field1"
+ err := reg.loadServices(reg.files[target])
+ if err != nil {
+ if !strings.Contains(err.Error(), wantErrMsg) {
+ t.Errorf("loadServices(%q, %q) failed with %v; want %s", target, input, err, wantErrMsg)
+ }
+ } else {
+ t.Errorf("loadServices(%q, %q) expcted an error %s, got nil", target, input, wantErrMsg)
+ }
+}
diff --git a/gateway/protoc-gen-grpc-gateway/descriptor/types.go b/gateway/internal/descriptor/types.go
similarity index 63%
rename from gateway/protoc-gen-grpc-gateway/descriptor/types.go
rename to gateway/internal/descriptor/types.go
index 1001ecb..79b20d7 100644
--- a/gateway/protoc-gen-grpc-gateway/descriptor/types.go
+++ b/gateway/internal/descriptor/types.go
@@ -5,13 +5,13 @@ import (
"strings"
"unicode"
- "github.com/golang/protobuf/protoc-gen-go/descriptor"
- gogen "github.com/golang/protobuf/protoc-gen-go/generator"
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/internal/casing"
+ "github.com/binchencoder/janus-gateway/gateway/internal/casing"
+ "github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule"
+ "google.golang.org/protobuf/types/descriptorpb"
+ "google.golang.org/protobuf/types/pluginpb"
- // "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule"
- "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/httprule"
-
- options "github.com/binchencoder/ease-gateway/httpoptions"
+ options "github.com/binchencoder/janus-gateway/httpoptions"
"github.com/binchencoder/gateway-proto/data"
)
@@ -21,13 +21,13 @@ func IsWellKnownType(typeName string) bool {
return ok
}
-// GoPackage represents a golang package
+// GoPackage represents a golang package.
type GoPackage struct {
// Path is the package path to the package.
Path string
// Name is the package name of the package
Name string
- // Alias is an alias of the package unique within the current invokation of grpc-gateway generator.
+ // Alias is an alias of the package unique within the current invocation of gRPC-Gateway generator.
Alias string
}
@@ -44,11 +44,24 @@ func (p GoPackage) String() string {
return fmt.Sprintf("%s %q", p.Alias, p.Path)
}
-// File wraps descriptor.FileDescriptorProto for richer features.
+// ResponseFile wraps pluginpb.CodeGeneratorResponse_File.
+type ResponseFile struct {
+ *pluginpb.CodeGeneratorResponse_File
+ // GoPkg is the Go package of the generated file.
+ GoPkg GoPackage
+}
+
+// File wraps descriptorpb.FileDescriptorProto for richer features.
type File struct {
- *descriptor.FileDescriptorProto
- // GoPkg is the go package of the go file generated from this file..
+ *descriptorpb.FileDescriptorProto
+ // GoPkg is the go package of the go file generated from this file.
GoPkg GoPackage
+ // GeneratedFilenamePrefix is used to construct filenames for generated
+ // files associated with this source file.
+ //
+ // For example, the source file "dir/foo.proto" might have a filename prefix
+ // of "dir/foo". Appending ".pb.go" produces an output file of "dir/foo.pb.go".
+ GeneratedFilenamePrefix string
// Messages is the list of messages defined in this file.
Messages []*Message
// Enums is the list of enums defined in this file.
@@ -57,22 +70,33 @@ type File struct {
Services []*Service
}
+// Pkg returns package name or alias if it's present
+func (f *File) Pkg() string {
+ pkg := f.GoPkg.Name
+ if alias := f.GoPkg.Alias; alias != "" {
+ pkg = alias
+ }
+ return pkg
+}
+
// proto2 determines if the syntax of the file is proto2.
func (f *File) proto2() bool {
return f.Syntax == nil || f.GetSyntax() == "proto2"
}
-// Message describes a protocol buffer message types
+// Message describes a protocol buffer message types.
type Message struct {
- // File is the file where the message is defined
+ *descriptorpb.DescriptorProto
+ // File is the file where the message is defined.
File *File
// Outers is a list of outer messages if this message is a nested type.
Outers []string
- *descriptor.DescriptorProto
+ // Fields is a list of message fields.
Fields []*Field
-
// Index is proto path index of this message in File.
Index int
+ // ForcePrefixedName when set to true, prefixes a type with a package prefix.
+ ForcePrefixedName bool
// Checked fields, with key constructed with message's package, and field type,
// And value as the HasRule result.
@@ -130,7 +154,7 @@ func (m *Message) HasRule() bool {
return true
}
- if *f.Type == descriptor.FieldDescriptorProto_TYPE_MESSAGE {
+ if *f.Type == descriptorpb.FieldDescriptorProto_TYPE_MESSAGE {
// It looks the field's type name is prefixed with package already.
// To make it consistent with parameters passing to Reg.LookupMessage,
// let's construct map key with package and type name.
@@ -176,25 +200,23 @@ func (m *Message) GoType(currentPackage string) string {
components = append(components, m.GetName())
name := strings.Join(components, "_")
- if m.File.GoPkg.Path == currentPackage {
+ if !m.ForcePrefixedName && m.File.GoPkg.Path == currentPackage {
return name
}
- pkg := m.File.GoPkg.Name
- if alias := m.File.GoPkg.Alias; alias != "" {
- pkg = alias
- }
- return fmt.Sprintf("%s.%s", pkg, name)
+ return fmt.Sprintf("%s.%s", m.File.Pkg(), name)
}
-// Enum describes a protocol buffer enum types
+// Enum describes a protocol buffer enum types.
type Enum struct {
+ *descriptorpb.EnumDescriptorProto
// File is the file where the enum is defined
File *File
// Outers is a list of outer messages if this enum is a nested type.
Outers []string
- *descriptor.EnumDescriptorProto
-
+ // Index is a enum index value.
Index int
+ // ForcePrefixedName when set to true, prefixes a type with a package prefix.
+ ForcePrefixedName bool
}
// FQEN returns a fully qualified enum name of this enum.
@@ -217,21 +239,17 @@ func (e *Enum) GoType(currentPackage string) string {
components = append(components, e.GetName())
name := strings.Join(components, "_")
- if e.File.GoPkg.Path == currentPackage {
+ if !e.ForcePrefixedName && e.File.GoPkg.Path == currentPackage {
return name
}
- pkg := e.File.GoPkg.Name
- if alias := e.File.GoPkg.Alias; alias != "" {
- pkg = alias
- }
- return fmt.Sprintf("%s.%s", pkg, name)
+ return fmt.Sprintf("%s.%s", e.File.Pkg(), name)
}
-// Service wraps descriptor.ServiceDescriptorProto for richer features.
+// Service wraps descriptorpb.ServiceDescriptorProto for richer features.
type Service struct {
+ *descriptorpb.ServiceDescriptorProto
// File is the file where this service is defined.
File *File
- *descriptor.ServiceDescriptorProto
// service ID uniquely identifies this service in context of org.
ServiceId *data.ServiceId
@@ -247,6 +265,8 @@ type Service struct {
// Methods is the list of methods defined in this service.
Methods []*Method
+ // ForcePrefixedName when set to true, prefixes a type with a package prefix.
+ ForcePrefixedName bool
}
// FQSN returns the fully qualified service name of this service.
@@ -259,12 +279,28 @@ func (s *Service) FQSN() string {
return strings.Join(components, ".")
}
-// Method wraps descriptor.MethodDescriptorProto for richer features.
+// InstanceName returns object name of the service with package prefix if needed
+func (s *Service) InstanceName() string {
+ if !s.ForcePrefixedName {
+ return s.GetName()
+ }
+ return fmt.Sprintf("%s.%s", s.File.Pkg(), s.GetName())
+}
+
+// ClientConstructorName returns name of the Client constructor with package prefix if needed
+func (s *Service) ClientConstructorName() string {
+ constructor := "New" + s.GetName() + "Client"
+ if !s.ForcePrefixedName {
+ return constructor
+ }
+ return fmt.Sprintf("%s.%s", s.File.Pkg(), constructor)
+}
+
+// Method wraps descriptorpb.MethodDescriptorProto for richer features.
type Method struct {
+ *descriptorpb.MethodDescriptorProto
// Service is the service which this method belongs to.
Service *Service
- *descriptor.MethodDescriptorProto
-
// RequestType is the message type of requests to this method.
RequestType *Message
// ResponseType is the message type of responses from this method.
@@ -283,7 +319,7 @@ type Method struct {
// FQMN returns a fully qualified rpc method name of this method.
func (m *Method) FQMN() string {
- components := []string{}
+ var components []string
components = append(components, m.Service.FQSN())
components = append(components, m.GetName())
return strings.Join(components, ".")
@@ -320,17 +356,24 @@ func (b *Binding) ExplicitParams() []string {
return result
}
-// Field wraps descriptor.FieldDescriptorProto for richer features.
+// Field wraps descriptorpb.FieldDescriptorProto for richer features.
type Field struct {
+ *descriptorpb.FieldDescriptorProto
// Message is the message type which this field belongs to.
Message *Message
// FieldMessage is the message type of the field.
FieldMessage *Message
- *descriptor.FieldDescriptorProto
+ // ForcePrefixedName when set to true, prefixes a type with a package prefix.
+ ForcePrefixedName bool
Rules []*Rule
}
+// FQFN returns a fully qualified field name of this field.
+func (f *Field) FQFN() string {
+ return strings.Join([]string{f.Message.FQMN(), f.GetName()}, ".")
+}
+
// IsOneOf return true if this field is oneof field.
func (f *Field) IsOneOf() bool {
return f.OneofIndex != nil
@@ -355,7 +398,7 @@ func (f *Field) OneOfDeclGoName() string {
// IsRepeated return true if this field is repeated otherwise return false.
func (f *Field) IsRepeated() bool {
- return *f.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED
+ return *f.Label == descriptorpb.FieldDescriptorProto_LABEL_REPEATED
}
// HasRule returns true if there is any validation rule defined.
@@ -466,6 +509,8 @@ func (p Parameter) ConvertFuncExpr() (string, error) {
tbl := proto3ConvertFuncs
if !p.IsProto2() && p.IsRepeated() {
tbl = proto3RepeatedConvertFuncs
+ } else if !p.IsProto2() && p.IsOptionalProto3() {
+ tbl = proto3OptionalConvertFuncs
} else if p.IsProto2() && !p.IsRepeated() {
tbl = proto2ConvertFuncs
} else if p.IsProto2() && p.IsRepeated() {
@@ -484,12 +529,12 @@ func (p Parameter) ConvertFuncExpr() (string, error) {
// IsEnum returns true if the field is an enum type, otherwise false is returned.
func (p Parameter) IsEnum() bool {
- return p.Target.GetType() == descriptor.FieldDescriptorProto_TYPE_ENUM
+ return p.Target.GetType() == descriptorpb.FieldDescriptorProto_TYPE_ENUM
}
// IsRepeated returns true if the field is repeated, otherwise false is returned.
func (p Parameter) IsRepeated() bool {
- return p.Target.GetLabel() == descriptor.FieldDescriptorProto_LABEL_REPEATED
+ return p.Target.GetLabel() == descriptorpb.FieldDescriptorProto_LABEL_REPEATED
}
// IsProto2 returns true if the field is proto2, otherwise false is returned.
@@ -531,6 +576,14 @@ func (p FieldPath) IsNestedProto3() bool {
return false
}
+// IsOptionalProto3 indicates whether the FieldPath is a proto3 optional field.
+func (p FieldPath) IsOptionalProto3() bool {
+ if len(p) == 0 {
+ return false
+ }
+ return p[0].Target.GetProto3Optional()
+}
+
// AssignableExpr is an assignable expression in Go to be used to assign a value to the target field.
// It starts with "msgExpr", which is the go expression of the method request object.
func (p FieldPath) AssignableExpr(msgExpr string) string {
@@ -542,18 +595,24 @@ func (p FieldPath) AssignableExpr(msgExpr string) string {
var preparations []string
components := msgExpr
for i, c := range p {
- // Check if it is a oneOf field.
- if c.Target.OneofIndex != nil {
+ // We need to check if the target is not proto3_optional first.
+ // Under the hood, proto3_optional uses oneof to signal to old proto3 clients
+ // that presence is tracked for this field. This oneof is known as a "synthetic" oneof.
+ if !c.Target.GetProto3Optional() && c.Target.OneofIndex != nil {
index := c.Target.OneofIndex
msg := c.Target.Message
- oneOfName := gogen.CamelCase(msg.GetOneofDecl()[*index].GetName())
+ oneOfName := casing.Camel(msg.GetOneofDecl()[*index].GetName())
oneofFieldName := msg.GetName() + "_" + c.AssignableExpr()
+ if c.Target.ForcePrefixedName {
+ oneofFieldName = msg.File.Pkg() + "." + oneofFieldName
+ }
+
components = components + "." + oneOfName
s := `if %s == nil {
%s =&%s{}
} else if _, ok := %s.(*%s); !ok {
- return nil, metadata, grpc.Errorf(codes.InvalidArgument, "expect type: *%s, but: %%t\n",%s)
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "expect type: *%s, but: %%t\n",%s)
}`
preparations = append(preparations, fmt.Sprintf(s, components, components, oneofFieldName, components, oneofFieldName, oneofFieldName, components))
@@ -582,102 +641,114 @@ type FieldPathComponent struct {
// AssignableExpr returns an assignable expression in go for this field.
func (c FieldPathComponent) AssignableExpr() string {
- return gogen.CamelCase(c.Name)
+ return casing.Camel(c.Name)
}
// ValueExpr returns an expression in go for this field.
func (c FieldPathComponent) ValueExpr() string {
if c.Target.Message.File.proto2() {
- return fmt.Sprintf("Get%s()", gogen.CamelCase(c.Name))
+ return fmt.Sprintf("Get%s()", casing.Camel(c.Name))
}
- return gogen.CamelCase(c.Name)
+ return casing.Camel(c.Name)
}
var (
- proto3ConvertFuncs = map[descriptor.FieldDescriptorProto_Type]string{
- descriptor.FieldDescriptorProto_TYPE_DOUBLE: "runtime.Float64",
- descriptor.FieldDescriptorProto_TYPE_FLOAT: "runtime.Float32",
- descriptor.FieldDescriptorProto_TYPE_INT64: "runtime.Int64",
- descriptor.FieldDescriptorProto_TYPE_UINT64: "runtime.Uint64",
- descriptor.FieldDescriptorProto_TYPE_INT32: "runtime.Int32",
- descriptor.FieldDescriptorProto_TYPE_FIXED64: "runtime.Uint64",
- descriptor.FieldDescriptorProto_TYPE_FIXED32: "runtime.Uint32",
- descriptor.FieldDescriptorProto_TYPE_BOOL: "runtime.Bool",
- descriptor.FieldDescriptorProto_TYPE_STRING: "runtime.String",
+ proto3ConvertFuncs = map[descriptorpb.FieldDescriptorProto_Type]string{
+ descriptorpb.FieldDescriptorProto_TYPE_DOUBLE: "runtime.Float64",
+ descriptorpb.FieldDescriptorProto_TYPE_FLOAT: "runtime.Float32",
+ descriptorpb.FieldDescriptorProto_TYPE_INT64: "runtime.Int64",
+ descriptorpb.FieldDescriptorProto_TYPE_UINT64: "runtime.Uint64",
+ descriptorpb.FieldDescriptorProto_TYPE_INT32: "runtime.Int32",
+ descriptorpb.FieldDescriptorProto_TYPE_FIXED64: "runtime.Uint64",
+ descriptorpb.FieldDescriptorProto_TYPE_FIXED32: "runtime.Uint32",
+ descriptorpb.FieldDescriptorProto_TYPE_BOOL: "runtime.Bool",
+ descriptorpb.FieldDescriptorProto_TYPE_STRING: "runtime.String",
// FieldDescriptorProto_TYPE_GROUP
// FieldDescriptorProto_TYPE_MESSAGE
- descriptor.FieldDescriptorProto_TYPE_BYTES: "runtime.Bytes",
- descriptor.FieldDescriptorProto_TYPE_UINT32: "runtime.Uint32",
- descriptor.FieldDescriptorProto_TYPE_ENUM: "runtime.Enum",
- descriptor.FieldDescriptorProto_TYPE_SFIXED32: "runtime.Int32",
- descriptor.FieldDescriptorProto_TYPE_SFIXED64: "runtime.Int64",
- descriptor.FieldDescriptorProto_TYPE_SINT32: "runtime.Int32",
- descriptor.FieldDescriptorProto_TYPE_SINT64: "runtime.Int64",
+ descriptorpb.FieldDescriptorProto_TYPE_BYTES: "runtime.Bytes",
+ descriptorpb.FieldDescriptorProto_TYPE_UINT32: "runtime.Uint32",
+ descriptorpb.FieldDescriptorProto_TYPE_ENUM: "runtime.Enum",
+ descriptorpb.FieldDescriptorProto_TYPE_SFIXED32: "runtime.Int32",
+ descriptorpb.FieldDescriptorProto_TYPE_SFIXED64: "runtime.Int64",
+ descriptorpb.FieldDescriptorProto_TYPE_SINT32: "runtime.Int32",
+ descriptorpb.FieldDescriptorProto_TYPE_SINT64: "runtime.Int64",
}
- proto3RepeatedConvertFuncs = map[descriptor.FieldDescriptorProto_Type]string{
- descriptor.FieldDescriptorProto_TYPE_DOUBLE: "runtime.Float64Slice",
- descriptor.FieldDescriptorProto_TYPE_FLOAT: "runtime.Float32Slice",
- descriptor.FieldDescriptorProto_TYPE_INT64: "runtime.Int64Slice",
- descriptor.FieldDescriptorProto_TYPE_UINT64: "runtime.Uint64Slice",
- descriptor.FieldDescriptorProto_TYPE_INT32: "runtime.Int32Slice",
- descriptor.FieldDescriptorProto_TYPE_FIXED64: "runtime.Uint64Slice",
- descriptor.FieldDescriptorProto_TYPE_FIXED32: "runtime.Uint32Slice",
- descriptor.FieldDescriptorProto_TYPE_BOOL: "runtime.BoolSlice",
- descriptor.FieldDescriptorProto_TYPE_STRING: "runtime.StringSlice",
+ proto3OptionalConvertFuncs = func() map[descriptorpb.FieldDescriptorProto_Type]string {
+ result := make(map[descriptorpb.FieldDescriptorProto_Type]string)
+ for typ, converter := range proto3ConvertFuncs {
+ // TODO: this will use convert functions from proto2.
+ // The converters returning pointers should be moved
+ // to a more generic file.
+ result[typ] = converter + "P"
+ }
+ return result
+ }()
+
+ // TODO: replace it with a IIFE
+ proto3RepeatedConvertFuncs = map[descriptorpb.FieldDescriptorProto_Type]string{
+ descriptorpb.FieldDescriptorProto_TYPE_DOUBLE: "runtime.Float64Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_FLOAT: "runtime.Float32Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_INT64: "runtime.Int64Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_UINT64: "runtime.Uint64Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_INT32: "runtime.Int32Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_FIXED64: "runtime.Uint64Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_FIXED32: "runtime.Uint32Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_BOOL: "runtime.BoolSlice",
+ descriptorpb.FieldDescriptorProto_TYPE_STRING: "runtime.StringSlice",
// FieldDescriptorProto_TYPE_GROUP
// FieldDescriptorProto_TYPE_MESSAGE
- descriptor.FieldDescriptorProto_TYPE_BYTES: "runtime.BytesSlice",
- descriptor.FieldDescriptorProto_TYPE_UINT32: "runtime.Uint32Slice",
- descriptor.FieldDescriptorProto_TYPE_ENUM: "runtime.EnumSlice",
- descriptor.FieldDescriptorProto_TYPE_SFIXED32: "runtime.Int32Slice",
- descriptor.FieldDescriptorProto_TYPE_SFIXED64: "runtime.Int64Slice",
- descriptor.FieldDescriptorProto_TYPE_SINT32: "runtime.Int32Slice",
- descriptor.FieldDescriptorProto_TYPE_SINT64: "runtime.Int64Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_BYTES: "runtime.BytesSlice",
+ descriptorpb.FieldDescriptorProto_TYPE_UINT32: "runtime.Uint32Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_ENUM: "runtime.EnumSlice",
+ descriptorpb.FieldDescriptorProto_TYPE_SFIXED32: "runtime.Int32Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_SFIXED64: "runtime.Int64Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_SINT32: "runtime.Int32Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_SINT64: "runtime.Int64Slice",
}
- proto2ConvertFuncs = map[descriptor.FieldDescriptorProto_Type]string{
- descriptor.FieldDescriptorProto_TYPE_DOUBLE: "runtime.Float64P",
- descriptor.FieldDescriptorProto_TYPE_FLOAT: "runtime.Float32P",
- descriptor.FieldDescriptorProto_TYPE_INT64: "runtime.Int64P",
- descriptor.FieldDescriptorProto_TYPE_UINT64: "runtime.Uint64P",
- descriptor.FieldDescriptorProto_TYPE_INT32: "runtime.Int32P",
- descriptor.FieldDescriptorProto_TYPE_FIXED64: "runtime.Uint64P",
- descriptor.FieldDescriptorProto_TYPE_FIXED32: "runtime.Uint32P",
- descriptor.FieldDescriptorProto_TYPE_BOOL: "runtime.BoolP",
- descriptor.FieldDescriptorProto_TYPE_STRING: "runtime.StringP",
+ proto2ConvertFuncs = map[descriptorpb.FieldDescriptorProto_Type]string{
+ descriptorpb.FieldDescriptorProto_TYPE_DOUBLE: "runtime.Float64P",
+ descriptorpb.FieldDescriptorProto_TYPE_FLOAT: "runtime.Float32P",
+ descriptorpb.FieldDescriptorProto_TYPE_INT64: "runtime.Int64P",
+ descriptorpb.FieldDescriptorProto_TYPE_UINT64: "runtime.Uint64P",
+ descriptorpb.FieldDescriptorProto_TYPE_INT32: "runtime.Int32P",
+ descriptorpb.FieldDescriptorProto_TYPE_FIXED64: "runtime.Uint64P",
+ descriptorpb.FieldDescriptorProto_TYPE_FIXED32: "runtime.Uint32P",
+ descriptorpb.FieldDescriptorProto_TYPE_BOOL: "runtime.BoolP",
+ descriptorpb.FieldDescriptorProto_TYPE_STRING: "runtime.StringP",
// FieldDescriptorProto_TYPE_GROUP
// FieldDescriptorProto_TYPE_MESSAGE
// FieldDescriptorProto_TYPE_BYTES
// TODO(yugui) Handle bytes
- descriptor.FieldDescriptorProto_TYPE_UINT32: "runtime.Uint32P",
- descriptor.FieldDescriptorProto_TYPE_ENUM: "runtime.EnumP",
- descriptor.FieldDescriptorProto_TYPE_SFIXED32: "runtime.Int32P",
- descriptor.FieldDescriptorProto_TYPE_SFIXED64: "runtime.Int64P",
- descriptor.FieldDescriptorProto_TYPE_SINT32: "runtime.Int32P",
- descriptor.FieldDescriptorProto_TYPE_SINT64: "runtime.Int64P",
+ descriptorpb.FieldDescriptorProto_TYPE_UINT32: "runtime.Uint32P",
+ descriptorpb.FieldDescriptorProto_TYPE_ENUM: "runtime.EnumP",
+ descriptorpb.FieldDescriptorProto_TYPE_SFIXED32: "runtime.Int32P",
+ descriptorpb.FieldDescriptorProto_TYPE_SFIXED64: "runtime.Int64P",
+ descriptorpb.FieldDescriptorProto_TYPE_SINT32: "runtime.Int32P",
+ descriptorpb.FieldDescriptorProto_TYPE_SINT64: "runtime.Int64P",
}
- proto2RepeatedConvertFuncs = map[descriptor.FieldDescriptorProto_Type]string{
- descriptor.FieldDescriptorProto_TYPE_DOUBLE: "runtime.Float64Slice",
- descriptor.FieldDescriptorProto_TYPE_FLOAT: "runtime.Float32Slice",
- descriptor.FieldDescriptorProto_TYPE_INT64: "runtime.Int64Slice",
- descriptor.FieldDescriptorProto_TYPE_UINT64: "runtime.Uint64Slice",
- descriptor.FieldDescriptorProto_TYPE_INT32: "runtime.Int32Slice",
- descriptor.FieldDescriptorProto_TYPE_FIXED64: "runtime.Uint64Slice",
- descriptor.FieldDescriptorProto_TYPE_FIXED32: "runtime.Uint32Slice",
- descriptor.FieldDescriptorProto_TYPE_BOOL: "runtime.BoolSlice",
- descriptor.FieldDescriptorProto_TYPE_STRING: "runtime.StringSlice",
+ proto2RepeatedConvertFuncs = map[descriptorpb.FieldDescriptorProto_Type]string{
+ descriptorpb.FieldDescriptorProto_TYPE_DOUBLE: "runtime.Float64Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_FLOAT: "runtime.Float32Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_INT64: "runtime.Int64Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_UINT64: "runtime.Uint64Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_INT32: "runtime.Int32Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_FIXED64: "runtime.Uint64Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_FIXED32: "runtime.Uint32Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_BOOL: "runtime.BoolSlice",
+ descriptorpb.FieldDescriptorProto_TYPE_STRING: "runtime.StringSlice",
// FieldDescriptorProto_TYPE_GROUP
// FieldDescriptorProto_TYPE_MESSAGE
// FieldDescriptorProto_TYPE_BYTES
// TODO(maros7) Handle bytes
- descriptor.FieldDescriptorProto_TYPE_UINT32: "runtime.Uint32Slice",
- descriptor.FieldDescriptorProto_TYPE_ENUM: "runtime.EnumSlice",
- descriptor.FieldDescriptorProto_TYPE_SFIXED32: "runtime.Int32Slice",
- descriptor.FieldDescriptorProto_TYPE_SFIXED64: "runtime.Int64Slice",
- descriptor.FieldDescriptorProto_TYPE_SINT32: "runtime.Int32Slice",
- descriptor.FieldDescriptorProto_TYPE_SINT64: "runtime.Int64Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_UINT32: "runtime.Uint32Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_ENUM: "runtime.EnumSlice",
+ descriptorpb.FieldDescriptorProto_TYPE_SFIXED32: "runtime.Int32Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_SFIXED64: "runtime.Int64Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_SINT32: "runtime.Int32Slice",
+ descriptorpb.FieldDescriptorProto_TYPE_SINT64: "runtime.Int64Slice",
}
wellKnownTypeConv = map[string]string{
diff --git a/gateway/protoc-gen-grpc-gateway/descriptor/types_test.go b/gateway/internal/descriptor/types_test.go
similarity index 67%
rename from gateway/protoc-gen-grpc-gateway/descriptor/types_test.go
rename to gateway/internal/descriptor/types_test.go
index 1dcdb34..1887764 100644
--- a/gateway/protoc-gen-grpc-gateway/descriptor/types_test.go
+++ b/gateway/internal/descriptor/types_test.go
@@ -3,8 +3,8 @@ package descriptor
import (
"testing"
- "github.com/golang/protobuf/proto"
- descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
+ "google.golang.org/protobuf/encoding/prototext"
+ "google.golang.org/protobuf/types/descriptorpb"
)
func TestGoPackageStandard(t *testing.T) {
@@ -21,7 +21,7 @@ func TestGoPackageStandard(t *testing.T) {
want: true,
},
{
- pkg: GoPackage{Path: "github.com/golang/protobuf/jsonpb", Name: "jsonpb"},
+ pkg: GoPackage{Path: "google.golang.org/protobuf/encoding/protojson", Name: "jsonpb"},
want: false,
},
{
@@ -57,8 +57,8 @@ func TestGoPackageString(t *testing.T) {
want: `"encoding/json"`,
},
{
- pkg: GoPackage{Path: "github.com/golang/protobuf/jsonpb", Name: "jsonpb"},
- want: `"github.com/golang/protobuf/jsonpb"`,
+ pkg: GoPackage{Path: "google.golang.org/protobuf/encoding/protojson", Name: "jsonpb"},
+ want: `"google.golang.org/protobuf/encoding/protojson"`,
},
{
pkg: GoPackage{Path: "golang.org/x/net/context", Name: "context"},
@@ -80,7 +80,7 @@ func TestGoPackageString(t *testing.T) {
}
func TestFieldPath(t *testing.T) {
- var fds []*descriptor.FileDescriptorProto
+ var fds []*descriptorpb.FileDescriptorProto
for _, src := range []string{
`
name: 'example.proto'
@@ -124,13 +124,13 @@ func TestFieldPath(t *testing.T) {
syntax: "proto2"
`,
} {
- var fd descriptor.FileDescriptorProto
- if err := proto.UnmarshalText(src, &fd); err != nil {
+ var fd descriptorpb.FileDescriptorProto
+ if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
}
fds = append(fds, &fd)
}
- nest := &Message{
+ nest1 := &Message{
DescriptorProto: fds[0].MessageType[0],
Fields: []*Field{
{FieldDescriptorProto: fds[0].MessageType[0].Field[0]},
@@ -147,7 +147,7 @@ func TestFieldPath(t *testing.T) {
file1 := &File{
FileDescriptorProto: fds[0],
GoPkg: GoPackage{Path: "example", Name: "example"},
- Messages: []*Message{nest},
+ Messages: []*Message{nest1},
}
file2 := &File{
FileDescriptorProto: fds[1],
@@ -170,7 +170,7 @@ func TestFieldPath(t *testing.T) {
c2 := FieldPathComponent{
Name: "nest2_field",
- Target: nest.Fields[0],
+ Target: nest1.Fields[0],
}
if got, want := c2.ValueExpr(), "Nest2Field"; got != want {
t.Errorf("c2.ValueExpr() = %q; want %q", got, want)
@@ -182,7 +182,7 @@ func TestFieldPath(t *testing.T) {
fp := FieldPath{
c1, c2, c1, FieldPathComponent{
Name: "terminal_field",
- Target: nest.Fields[1],
+ Target: nest1.Fields[1],
},
}
if got, want := fp.AssignableExpr("resp"), "resp.GetNestField().Nest2Field.GetNestField().TerminalField"; got != want {
@@ -204,3 +204,66 @@ func TestFieldPath(t *testing.T) {
t.Errorf("fpEmpty.AssignableExpr(%q) = %q; want %q", "resp", got, want)
}
}
+
+func TestGoType(t *testing.T) {
+ src := `
+ name: 'example.proto'
+ package: 'example'
+ message_type <
+ name: 'Message'
+ field <
+ name: 'field'
+ type: TYPE_STRING
+ number: 1
+ >
+ >,
+ enum_type <
+ name: 'EnumName'
+ >,
+ `
+
+ var fd descriptorpb.FileDescriptorProto
+ if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
+ t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
+ }
+
+ msg := &Message{
+ DescriptorProto: fd.MessageType[0],
+ Fields: []*Field{
+ {FieldDescriptorProto: fd.MessageType[0].Field[0]},
+ },
+ }
+ enum := &Enum{
+ EnumDescriptorProto: fd.EnumType[0],
+ }
+ file := &File{
+ FileDescriptorProto: &fd,
+ GoPkg: GoPackage{Path: "example", Name: "example"},
+ Messages: []*Message{msg},
+ Enums: []*Enum{enum},
+ }
+ crossLinkFixture(file)
+
+ if got, want := msg.GoType("example"), "Message"; got != want {
+ t.Errorf("msg.GoType() = %q; want %q", got, want)
+ }
+ if got, want := msg.GoType("extPackage"), "example.Message"; got != want {
+ t.Errorf("msg.GoType() = %q; want %q", got, want)
+ }
+ msg.ForcePrefixedName = true
+ if got, want := msg.GoType("example"), "example.Message"; got != want {
+ t.Errorf("msg.GoType() = %q; want %q", got, want)
+ }
+
+ if got, want := enum.GoType("example"), "EnumName"; got != want {
+ t.Errorf("enum.GoType() = %q; want %q", got, want)
+ }
+ if got, want := enum.GoType("extPackage"), "example.EnumName"; got != want {
+ t.Errorf("enum.GoType() = %q; want %q", got, want)
+ }
+ enum.ForcePrefixedName = true
+ if got, want := enum.GoType("example"), "example.EnumName"; got != want {
+ t.Errorf("enum.GoType() = %q; want %q", got, want)
+ }
+
+}
diff --git a/gateway/internal/errors.pb.go b/gateway/internal/errors.pb.go
new file mode 100644
index 0000000..4716d8e
--- /dev/null
+++ b/gateway/internal/errors.pb.go
@@ -0,0 +1,191 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: internal/errors.proto
+
+package internal
+
+import (
+ fmt "fmt"
+ math "math"
+
+ frontend "github.com/binchencoder/gateway-proto/frontend"
+ any "github.com/golang/protobuf/ptypes/any"
+ proto "google.golang.org/protobuf/proto"
+)
+
+// 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
+
+// Error is the generic error returned from unary RPCs.
+type Error struct {
+ Error *frontend.Error `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"`
+ // This is to make the error more compatible with users that expect errors to be Status objects:
+ // https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto
+ // It should be the exact same message as the Error field.
+ Code int32 `protobuf:"varint,2,opt,name=code,proto3" json:"code,omitempty"`
+ Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+ Details []*any.Any `protobuf:"bytes,4,rep,name=details,proto3" json:"details,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Error) Reset() { *m = Error{} }
+func (m *Error) String() string { return proto.CompactTextString(m) }
+func (*Error) ProtoMessage() {}
+func (*Error) Descriptor() ([]byte, []int) {
+ return fileDescriptor_9b093362ca6d1e03, []int{0}
+}
+
+func (m *Error) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Error.Unmarshal(m, b)
+}
+func (m *Error) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Error.Marshal(b, m, deterministic)
+}
+func (m *Error) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Error.Merge(m, src)
+}
+func (m *Error) XXX_Size() int {
+ return xxx_messageInfo_Error.Size(m)
+}
+func (m *Error) XXX_DiscardUnknown() {
+ xxx_messageInfo_Error.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Error proto.InternalMessageInfo
+
+func (m *Error) GetError() *frontend.Error {
+ if m != nil {
+ return m.Error
+ }
+ return nil
+}
+
+func (m *Error) GetCode() int32 {
+ if m != nil {
+ return m.Code
+ }
+ return 0
+}
+
+func (m *Error) GetMessage() string {
+ if m != nil {
+ return m.Message
+ }
+ return ""
+}
+
+func (m *Error) GetDetails() []*any.Any {
+ if m != nil {
+ return m.Details
+ }
+ return nil
+}
+
+// StreamError is a response type which is returned when
+// streaming rpc returns an error.
+type StreamError struct {
+ GrpcCode int32 `protobuf:"varint,1,opt,name=grpc_code,json=grpcCode,proto3" json:"grpc_code,omitempty"`
+ HttpCode int32 `protobuf:"varint,2,opt,name=http_code,json=httpCode,proto3" json:"http_code,omitempty"`
+ Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+ HttpStatus string `protobuf:"bytes,4,opt,name=http_status,json=httpStatus,proto3" json:"http_status,omitempty"`
+ Details []*any.Any `protobuf:"bytes,5,rep,name=details,proto3" json:"details,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *StreamError) Reset() { *m = StreamError{} }
+func (m *StreamError) String() string { return proto.CompactTextString(m) }
+func (*StreamError) ProtoMessage() {}
+func (*StreamError) Descriptor() ([]byte, []int) {
+ return fileDescriptor_9b093362ca6d1e03, []int{1}
+}
+
+func (m *StreamError) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_StreamError.Unmarshal(m, b)
+}
+func (m *StreamError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_StreamError.Marshal(b, m, deterministic)
+}
+func (m *StreamError) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_StreamError.Merge(m, src)
+}
+func (m *StreamError) XXX_Size() int {
+ return xxx_messageInfo_StreamError.Size(m)
+}
+func (m *StreamError) XXX_DiscardUnknown() {
+ xxx_messageInfo_StreamError.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_StreamError proto.InternalMessageInfo
+
+func (m *StreamError) GetGrpcCode() int32 {
+ if m != nil {
+ return m.GrpcCode
+ }
+ return 0
+}
+
+func (m *StreamError) GetHttpCode() int32 {
+ if m != nil {
+ return m.HttpCode
+ }
+ return 0
+}
+
+func (m *StreamError) GetMessage() string {
+ if m != nil {
+ return m.Message
+ }
+ return ""
+}
+
+func (m *StreamError) GetHttpStatus() string {
+ if m != nil {
+ return m.HttpStatus
+ }
+ return ""
+}
+
+func (m *StreamError) GetDetails() []*any.Any {
+ if m != nil {
+ return m.Details
+ }
+ return nil
+}
+
+func init() {
+ proto.RegisterType((*Error)(nil), "grpc.gateway.runtime.Error")
+ proto.RegisterType((*StreamError)(nil), "grpc.gateway.runtime.StreamError")
+}
+
+func init() { proto.RegisterFile("internal/errors.proto", fileDescriptor_9b093362ca6d1e03) }
+
+var fileDescriptor_9b093362ca6d1e03 = []byte{
+ // 252 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x90, 0xc1, 0x4a, 0xc4, 0x30,
+ 0x10, 0x86, 0x89, 0xbb, 0x75, 0xdb, 0xe9, 0x2d, 0x54, 0x88, 0xee, 0xc1, 0xb2, 0xa7, 0x9e, 0x52,
+ 0xd0, 0x27, 0xd0, 0xc5, 0x17, 0xe8, 0xde, 0xbc, 0x2c, 0xd9, 0xdd, 0x31, 0x16, 0xda, 0xa4, 0x24,
+ 0x53, 0xa4, 0xf8, 0x56, 0x3e, 0xa1, 0x24, 0xa5, 0xb0, 0x27, 0xf1, 0xd6, 0xf9, 0xfb, 0xcf, 0x7c,
+ 0x1f, 0x81, 0xbb, 0xd6, 0x10, 0x3a, 0xa3, 0xba, 0x1a, 0x9d, 0xb3, 0xce, 0xcb, 0xc1, 0x59, 0xb2,
+ 0xbc, 0xd0, 0x6e, 0x38, 0x4b, 0xad, 0x08, 0xbf, 0xd4, 0x24, 0xdd, 0x68, 0xa8, 0xed, 0xf1, 0xe1,
+ 0x5e, 0x5b, 0xab, 0x3b, 0xac, 0x63, 0xe7, 0x34, 0x7e, 0xd4, 0xca, 0x4c, 0xf3, 0xc2, 0xee, 0x1b,
+ 0x92, 0xb7, 0x70, 0x80, 0x17, 0x90, 0xc4, 0x4b, 0x82, 0x95, 0xac, 0xca, 0x9a, 0x79, 0xe0, 0x1c,
+ 0xd6, 0x67, 0x7b, 0x41, 0x71, 0x53, 0xb2, 0x2a, 0x69, 0xe2, 0x37, 0x17, 0xb0, 0xe9, 0xd1, 0x7b,
+ 0xa5, 0x51, 0xac, 0x62, 0x77, 0x19, 0xb9, 0x84, 0xcd, 0x05, 0x49, 0xb5, 0x9d, 0x17, 0xeb, 0x72,
+ 0x55, 0xe5, 0x4f, 0x85, 0x9c, 0xc9, 0x72, 0x21, 0xcb, 0x17, 0x33, 0x35, 0x4b, 0x69, 0xf7, 0xc3,
+ 0x20, 0x3f, 0x90, 0x43, 0xd5, 0xcf, 0x0e, 0x5b, 0xc8, 0x82, 0xff, 0x31, 0x22, 0x59, 0x44, 0xa6,
+ 0x21, 0xd8, 0x07, 0xec, 0x16, 0xb2, 0x4f, 0xa2, 0xe1, 0x78, 0xe5, 0x93, 0x86, 0x60, 0xff, 0xb7,
+ 0xd3, 0x23, 0xe4, 0x71, 0xcd, 0x93, 0xa2, 0x31, 0x78, 0x85, 0xbf, 0x10, 0xa2, 0x43, 0x4c, 0xae,
+ 0xa5, 0x93, 0x7f, 0x48, 0xbf, 0xc2, 0x7b, 0xba, 0xbc, 0xfd, 0xe9, 0x36, 0x56, 0x9e, 0x7f, 0x03,
+ 0x00, 0x00, 0xff, 0xff, 0xde, 0x72, 0x6b, 0x83, 0x8e, 0x01, 0x00, 0x00,
+}
diff --git a/gateway/internal/errors.proto b/gateway/internal/errors.proto
new file mode 100644
index 0000000..b0a0022
--- /dev/null
+++ b/gateway/internal/errors.proto
@@ -0,0 +1,27 @@
+syntax = "proto3";
+package grpc.gateway.runtime;
+option go_package = "internal";
+
+import "google/protobuf/any.proto";
+import "frontend/error.proto";
+
+// Error is the generic error returned from unary RPCs.
+message Error {
+ frontend.Error error = 1;
+ // This is to make the error more compatible with users that expect errors to be Status objects:
+ // https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto
+ // It should be the exact same message as the Error field.
+ int32 code = 2;
+ string message = 3;
+ repeated google.protobuf.Any details = 4;
+}
+
+// StreamError is a response type which is returned when
+// streaming rpc returns an error.
+message StreamError {
+ int32 grpc_code = 1;
+ int32 http_code = 2;
+ string message = 3;
+ string http_status = 4;
+ repeated google.protobuf.Any details = 5;
+}
diff --git a/gateway/internal/generator/BUILD.bazel b/gateway/internal/generator/BUILD.bazel
new file mode 100644
index 0000000..225c6a1
--- /dev/null
+++ b/gateway/internal/generator/BUILD.bazel
@@ -0,0 +1,16 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+package(default_visibility = ["//visibility:public"])
+
+go_library(
+ name = "generator",
+ srcs = ["generator.go"],
+ importpath = "github.com/binchencoder/janus-gateway/gateway/internal/generator",
+ deps = ["//gateway/internal/descriptor:go_default_library"],
+)
+
+alias(
+ name = "go_default_library",
+ actual = ":generator",
+ visibility = ["//:__subpackages__"],
+)
diff --git a/gateway/internal/generator/generator.go b/gateway/internal/generator/generator.go
new file mode 100644
index 0000000..d03c1f7
--- /dev/null
+++ b/gateway/internal/generator/generator.go
@@ -0,0 +1,13 @@
+// Package generator provides an abstract interface to code generators.
+package generator
+
+import (
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor"
+ "github.com/binchencoder/janus-gateway/gateway/internal/descriptor"
+)
+
+// Generator is an abstraction of code generators.
+type Generator interface {
+ // Generate generates output files from input .proto files.
+ Generate(targets []*descriptor.File) ([]*descriptor.ResponseFile, error)
+}
diff --git a/gateway/protoc-gen-grpc-gateway/BUILD.bazel b/gateway/protoc-gen-grpc-gateway/BUILD.bazel
index 7141bfc..8c39b20 100644
--- a/gateway/protoc-gen-grpc-gateway/BUILD.bazel
+++ b/gateway/protoc-gen-grpc-gateway/BUILD.bazel
@@ -1,25 +1,24 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test")
load("@io_bazel_rules_go//proto:compiler.bzl", "go_proto_compiler")
package(default_visibility = ["//visibility:private"])
go_library(
- name = "go_default_library",
+ name = "protoc-gen-grpc-gateway_lib",
srcs = ["main.go"],
- importpath = "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway",
+ importpath = "github.com/binchencoder/janus-gateway/gateway/protoc-gen-grpc-gateway",
deps = [
- "//gateway/codegenerator:go_default_library",
- "//gateway/protoc-gen-grpc-gateway/descriptor:go_default_library",
- "//gateway/protoc-gen-grpc-gateway/gengateway:go_default_library",
- "@com_github_golang_glog//:go_default_library",
- "@com_github_golang_protobuf//proto:go_default_library",
- "@io_bazel_rules_go//proto/wkt:compiler_plugin_go_proto",
+ "@com_github_grpc_ecosystem_grpc_gateway//internal/codegenerator",
+ "//gateway/internal/descriptor:go_default_library",
+ "//gateway/protoc-gen-grpc-gateway/internal/gengateway",
+ "@com_github_golang_glog//:glog",
+ "@org_golang_google_protobuf//compiler/protogen",
],
)
go_binary(
name = "protoc-gen-grpc-gateway",
- embed = [":go_default_library"],
+ embed = [":protoc-gen-grpc-gateway_lib"],
visibility = ["//visibility:public"],
)
@@ -36,12 +35,19 @@ go_proto_compiler(
"//gateway/runtime:go_default_library",
"@com_github_binchencoder_gateway_proto//data:go_default_library",
"@com_github_binchencoder_gateway_proto//frontend:go_default_library",
- "@com_github_grpc_ecosystem_grpc_gateway//utilities:go_default_library",
- "@com_github_golang_protobuf//proto:go_default_library",
+ "@com_github_grpc_ecosystem_grpc_gateway//utilities",
"@org_golang_google_grpc//:go_default_library",
"@org_golang_google_grpc//codes:go_default_library",
"@org_golang_google_grpc//grpclog:go_default_library",
+ "@org_golang_google_grpc//metadata:go_default_library",
"@org_golang_google_grpc//status:go_default_library",
- "@org_golang_x_net//context:go_default_library",
+ "@org_golang_google_protobuf//proto:go_default_library",
],
)
+
+go_test(
+ name = "protoc-gen-grpc-gateway_test",
+ srcs = ["main_test.go"],
+ embed = [":protoc-gen-grpc-gateway_lib"],
+ deps = ["//gateway/internal/descriptor"],
+)
diff --git a/gateway/protoc-gen-grpc-gateway/descriptor/BUILD.bazel b/gateway/protoc-gen-grpc-gateway/descriptor/BUILD.bazel
deleted file mode 100644
index 011317f..0000000
--- a/gateway/protoc-gen-grpc-gateway/descriptor/BUILD.bazel
+++ /dev/null
@@ -1,45 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-
-package(default_visibility = ["//visibility:public"])
-
-go_library(
- name = "go_default_library",
- srcs = [
- "grpc_api_configuration.go",
- "grpc_api_service.go",
- "registry.go",
- "services.go",
- "types.go",
- ],
- importpath = "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/descriptor",
- deps = [
- "//httpoptions:go_default_library",
- "//gateway/protoc-gen-grpc-gateway/httprule:go_default_library",
- "@com_github_binchencoder_gateway_proto//data:go_default_library",
- "@com_github_ghodss_yaml//:go_default_library",
- "@com_github_golang_glog//:go_default_library",
- "@com_github_golang_protobuf//jsonpb:go_default_library_gen",
- "@com_github_golang_protobuf//proto:go_default_library",
- "@com_github_golang_protobuf//protoc-gen-go/generator:go_default_library_gen",
- "@io_bazel_rules_go//proto/wkt:compiler_plugin_go_proto",
- "@io_bazel_rules_go//proto/wkt:descriptor_go_proto",
- ],
-)
-
-go_test(
- name = "go_default_test",
- size = "small",
- srcs = [
- "grpc_api_configuration_test.go",
- "registry_test.go",
- "services_test.go",
- "types_test.go",
- ],
- embed = [":go_default_library"],
- deps = [
- "//gateway/protoc-gen-grpc-gateway/httprule:go_default_library",
- "@com_github_golang_protobuf//proto:go_default_library",
- "@io_bazel_rules_go//proto/wkt:compiler_plugin_go_proto",
- "@io_bazel_rules_go//proto/wkt:descriptor_go_proto",
- ],
-)
diff --git a/gateway/protoc-gen-grpc-gateway/descriptor/grpc_api_service.go b/gateway/protoc-gen-grpc-gateway/descriptor/grpc_api_service.go
deleted file mode 100644
index 534daae..0000000
--- a/gateway/protoc-gen-grpc-gateway/descriptor/grpc_api_service.go
+++ /dev/null
@@ -1,32 +0,0 @@
-package descriptor
-
-import (
- "github.com/golang/protobuf/proto"
- // "google.golang.org/genproto/googleapis/api/annotations"
- annotations "github.com/binchencoder/ease-gateway/httpoptions"
-)
-
-// GrpcAPIService represents a stripped down version of google.api.Service .
-// Compare to https://github.com/googleapis/googleapis/blob/master/google/api/service.proto
-// The original imports 23 other protobuf files we are not interested in. If a significant
-// subset (>50%) of these start being reproduced in this file we should swap to using the
-// full generated version instead.
-//
-// For the purposes of the gateway generator we only consider a small subset of all
-// available features google supports in their service descriptions. Thanks to backwards
-// compatibility guarantees by protobuf it is safe for us to remove the other fields.
-// We also only implement the absolute minimum of protobuf generator boilerplate to use
-// our simplified version. These should be pretty stable too.
-type GrpcAPIService struct {
- // Http Rule. Named Http in the actual proto. Changed to suppress linter warning.
- HTTP *annotations.Http `protobuf:"bytes,9,opt,name=http" json:"http,omitempty"`
-}
-
-// ProtoMessage returns an empty GrpcAPIService element
-func (*GrpcAPIService) ProtoMessage() {}
-
-// Reset resets the GrpcAPIService
-func (m *GrpcAPIService) Reset() { *m = GrpcAPIService{} }
-
-// String returns the string representation of the GrpcAPIService
-func (m *GrpcAPIService) String() string { return proto.CompactTextString(m) }
diff --git a/gateway/protoc-gen-grpc-gateway/descriptor/registry.go b/gateway/protoc-gen-grpc-gateway/descriptor/registry.go
deleted file mode 100644
index 620da49..0000000
--- a/gateway/protoc-gen-grpc-gateway/descriptor/registry.go
+++ /dev/null
@@ -1,527 +0,0 @@
-package descriptor
-
-import (
- "fmt"
- "path"
- "path/filepath"
- "strings"
-
- "github.com/golang/glog"
- descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
- plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
-
- // "google.golang.org/genproto/googleapis/api/annotations"
- annotations "github.com/binchencoder/ease-gateway/httpoptions"
-)
-
-// Registry is a registry of information extracted from plugin.CodeGeneratorRequest.
-type Registry struct {
- // msgs is a mapping from fully-qualified message name to descriptor
- msgs map[string]*Message
-
- // enums is a mapping from fully-qualified enum name to descriptor
- enums map[string]*Enum
-
- // files is a mapping from file path to descriptor
- files map[string]*File
-
- // prefix is a prefix to be inserted to golang package paths generated from proto package names.
- prefix string
-
- // importPath is used as the package if no input files declare go_package. If it contains slashes, everything up to the rightmost slash is ignored.
- importPath string
-
- // pkgMap is a user-specified mapping from file path to proto package.
- pkgMap map[string]string
-
- // pkgAliases is a mapping from package aliases to package paths in go which are already taken.
- pkgAliases map[string]string
-
- // allowDeleteBody permits http delete methods to have a body
- allowDeleteBody bool
-
- // externalHttpRules is a mapping from fully qualified service method names to additional HttpRules applicable besides the ones found in annotations.
- externalHTTPRules map[string][]*annotations.HttpRule
-
- // allowMerge generation one swagger file out of multiple protos
- allowMerge bool
-
- // mergeFileName target swagger file name after merge
- mergeFileName string
-
- // allowRepeatedFieldsInBody permits repeated field in body field path of `google.api.http` annotation option
- allowRepeatedFieldsInBody bool
-
- // includePackageInTags controls whether the package name defined in the `package` directive
- // in the proto file can be prepended to the gRPC service name in the `Tags` field of every operation.
- includePackageInTags bool
-
- // repeatedPathParamSeparator specifies how path parameter repeated fields are separated
- repeatedPathParamSeparator repeatedFieldSeparator
-
- // useJSONNamesForFields if true json tag name is used for generating fields in swagger definitions,
- // otherwise the original proto name is used. It's helpful for synchronizing the swagger definition
- // with grpc-gateway response, if it uses json tags for marshaling.
- useJSONNamesForFields bool
-
- // useFQNForSwaggerName if true swagger names will use the full qualified name (FQN) from proto definition,
- // and generate a dot-separated swagger name concatenating all elements from the proto FQN.
- // If false, the default behavior is to concat the last 2 elements of the FQN if they are unique, otherwise concat
- // all the elements of the FQN without any separator
- useFQNForSwaggerName bool
-
- // allowColonFinalSegments determines whether colons are permitted
- // in the final segment of a path.
- allowColonFinalSegments bool
-
- // useGoTemplate determines whether you want to use GO templates
- // in your protofile comments
- useGoTemplate bool
-}
-
-type repeatedFieldSeparator struct {
- name string
- sep rune
-}
-
-var (
- // Reg is the global dictionary.
- Reg *Registry
-)
-
-// NewRegistry returns a new Registry.
-func NewRegistry() *Registry {
- return &Registry{
- msgs: make(map[string]*Message),
- enums: make(map[string]*Enum),
- files: make(map[string]*File),
- pkgMap: make(map[string]string),
- pkgAliases: make(map[string]string),
- externalHTTPRules: make(map[string][]*annotations.HttpRule),
- repeatedPathParamSeparator: repeatedFieldSeparator{
- name: "csv",
- sep: ',',
- },
- }
-}
-
-// Load loads definitions of services, methods, messages, enumerations and fields from "req".
-func (r *Registry) Load(req *plugin.CodeGeneratorRequest) error {
- for _, file := range req.GetProtoFile() {
- r.loadFile(file)
- }
-
- var targetPkg string
- for _, name := range req.FileToGenerate {
- target := r.files[name]
- if target == nil {
- return fmt.Errorf("no such file: %s", name)
- }
- name := r.packageIdentityName(target.FileDescriptorProto)
- if targetPkg == "" {
- targetPkg = name
- } else {
- if targetPkg != name {
- return fmt.Errorf("inconsistent package names: %s %s", targetPkg, name)
- }
- }
-
- if err := r.loadServices(target); err != nil {
- return err
- }
- }
- return nil
-}
-
-// loadFile loads messages, enumerations and fields from "file".
-// It does not loads services and methods in "file". You need to call
-// loadServices after loadFiles is called for all files to load services and methods.
-func (r *Registry) loadFile(file *descriptor.FileDescriptorProto) {
- pkg := GoPackage{
- Path: r.goPackagePath(file),
- Name: r.defaultGoPackageName(file),
- }
- if err := r.ReserveGoPackageAlias(pkg.Name, pkg.Path); err != nil {
- for i := 0; ; i++ {
- alias := fmt.Sprintf("%s_%d", pkg.Name, i)
- if err := r.ReserveGoPackageAlias(alias, pkg.Path); err == nil {
- pkg.Alias = alias
- break
- }
- }
- }
- f := &File{
- FileDescriptorProto: file,
- GoPkg: pkg,
- }
-
- r.files[file.GetName()] = f
- r.registerMsg(f, nil, file.GetMessageType())
- r.registerEnum(f, nil, file.GetEnumType())
-}
-
-func (r *Registry) registerMsg(file *File, outerPath []string, msgs []*descriptor.DescriptorProto) {
- for i, md := range msgs {
- m := &Message{
- File: file,
- Outers: outerPath,
- DescriptorProto: md,
- Index: i,
- }
- for _, fd := range md.GetField() {
- rule, _ := extractFieldRules(fd)
- var rules []*Rule
- if rule != nil {
- for _, r := range rule.Rules {
- rules = append(rules, &Rule{rule: r})
- }
- }
- m.Fields = append(m.Fields, &Field{
- Message: m,
- FieldDescriptorProto: fd,
- Rules: rules,
- })
- }
- file.Messages = append(file.Messages, m)
- r.msgs[m.FQMN()] = m
- glog.V(1).Infof("register name: %s", m.FQMN())
-
- var outers []string
- outers = append(outers, outerPath...)
- outers = append(outers, m.GetName())
- r.registerMsg(file, outers, m.GetNestedType())
- r.registerEnum(file, outers, m.GetEnumType())
- }
-}
-
-func (r *Registry) registerEnum(file *File, outerPath []string, enums []*descriptor.EnumDescriptorProto) {
- for i, ed := range enums {
- e := &Enum{
- File: file,
- Outers: outerPath,
- EnumDescriptorProto: ed,
- Index: i,
- }
- file.Enums = append(file.Enums, e)
- r.enums[e.FQEN()] = e
- glog.V(1).Infof("register enum name: %s", e.FQEN())
- }
-}
-
-// LookupMsg looks up a message type by "name".
-// It tries to resolve "name" from "location" if "name" is a relative message name.
-func (r *Registry) LookupMsg(location, name string) (*Message, error) {
- glog.V(1).Infof("lookup %s from %s", name, location)
- if strings.HasPrefix(name, ".") {
- m, ok := r.msgs[name]
- if !ok {
- return nil, fmt.Errorf("no message found: %s", name)
- }
- return m, nil
- }
-
- if !strings.HasPrefix(location, ".") {
- location = fmt.Sprintf(".%s", location)
- }
- components := strings.Split(location, ".")
- for len(components) > 0 {
- fqmn := strings.Join(append(components, name), ".")
- if m, ok := r.msgs[fqmn]; ok {
- return m, nil
- }
- components = components[:len(components)-1]
- }
- return nil, fmt.Errorf("no message found: %s", name)
-}
-
-// LookupEnum looks up a enum type by "name".
-// It tries to resolve "name" from "location" if "name" is a relative enum name.
-func (r *Registry) LookupEnum(location, name string) (*Enum, error) {
- glog.V(1).Infof("lookup enum %s from %s", name, location)
- if strings.HasPrefix(name, ".") {
- e, ok := r.enums[name]
- if !ok {
- return nil, fmt.Errorf("no enum found: %s", name)
- }
- return e, nil
- }
-
- if !strings.HasPrefix(location, ".") {
- location = fmt.Sprintf(".%s", location)
- }
- components := strings.Split(location, ".")
- for len(components) > 0 {
- fqen := strings.Join(append(components, name), ".")
- if e, ok := r.enums[fqen]; ok {
- return e, nil
- }
- components = components[:len(components)-1]
- }
- return nil, fmt.Errorf("no enum found: %s", name)
-}
-
-// LookupFile looks up a file by name.
-func (r *Registry) LookupFile(name string) (*File, error) {
- f, ok := r.files[name]
- if !ok {
- return nil, fmt.Errorf("no such file given: %s", name)
- }
- return f, nil
-}
-
-// LookupExternalHTTPRules looks up external http rules by fully qualified service method name
-func (r *Registry) LookupExternalHTTPRules(qualifiedMethodName string) []*annotations.HttpRule {
- return r.externalHTTPRules[qualifiedMethodName]
-}
-
-// AddExternalHTTPRule adds an external http rule for the given fully qualified service method name
-func (r *Registry) AddExternalHTTPRule(qualifiedMethodName string, rule *annotations.HttpRule) {
- r.externalHTTPRules[qualifiedMethodName] = append(r.externalHTTPRules[qualifiedMethodName], rule)
-}
-
-// AddPkgMap adds a mapping from a .proto file to proto package name.
-func (r *Registry) AddPkgMap(file, protoPkg string) {
- r.pkgMap[file] = protoPkg
-}
-
-// SetPrefix registers the prefix to be added to go package paths generated from proto package names.
-func (r *Registry) SetPrefix(prefix string) {
- r.prefix = prefix
-}
-
-// SetImportPath registers the importPath which is used as the package if no
-// input files declare go_package. If it contains slashes, everything up to the
-// rightmost slash is ignored.
-func (r *Registry) SetImportPath(importPath string) {
- r.importPath = importPath
-}
-
-// ReserveGoPackageAlias reserves the unique alias of go package.
-// If succeeded, the alias will be never used for other packages in generated go files.
-// If failed, the alias is already taken by another package, so you need to use another
-// alias for the package in your go files.
-func (r *Registry) ReserveGoPackageAlias(alias, pkgpath string) error {
- if taken, ok := r.pkgAliases[alias]; ok {
- if taken == pkgpath {
- return nil
- }
- return fmt.Errorf("package name %s is already taken. Use another alias", alias)
- }
- r.pkgAliases[alias] = pkgpath
- return nil
-}
-
-// goPackagePath returns the go package path which go files generated from "f" should have.
-// It respects the mapping registered by AddPkgMap if exists. Or use go_package as import path
-// if it includes a slash, Otherwide, it generates a path from the file name of "f".
-func (r *Registry) goPackagePath(f *descriptor.FileDescriptorProto) string {
- name := f.GetName()
- if pkg, ok := r.pkgMap[name]; ok {
- return path.Join(r.prefix, pkg)
- }
-
- gopkg := f.Options.GetGoPackage()
- idx := strings.LastIndex(gopkg, "/")
- if idx >= 0 {
- if sc := strings.LastIndex(gopkg, ";"); sc > 0 {
- gopkg = gopkg[:sc+1-1]
- }
- return gopkg
- }
-
- return path.Join(r.prefix, path.Dir(name))
-}
-
-// GetAllFQMNs returns a list of all FQMNs
-func (r *Registry) GetAllFQMNs() []string {
- var keys []string
- for k := range r.msgs {
- keys = append(keys, k)
- }
- return keys
-}
-
-// GetAllFQENs returns a list of all FQENs
-func (r *Registry) GetAllFQENs() []string {
- var keys []string
- for k := range r.enums {
- keys = append(keys, k)
- }
- return keys
-}
-
-// SetAllowDeleteBody controls whether http delete methods may have a
-// body or fail loading if encountered.
-func (r *Registry) SetAllowDeleteBody(allow bool) {
- r.allowDeleteBody = allow
-}
-
-// SetAllowMerge controls whether generation one swagger file out of multiple protos
-func (r *Registry) SetAllowMerge(allow bool) {
- r.allowMerge = allow
-}
-
-// IsAllowMerge whether generation one swagger file out of multiple protos
-func (r *Registry) IsAllowMerge() bool {
- return r.allowMerge
-}
-
-// SetMergeFileName controls the target swagger file name out of multiple protos
-func (r *Registry) SetMergeFileName(mergeFileName string) {
- r.mergeFileName = mergeFileName
-}
-
-// SetAllowRepeatedFieldsInBody controls whether repeated field can be used
-// in `body` and `response_body` (`google.api.http` annotation option) field path or not
-func (r *Registry) SetAllowRepeatedFieldsInBody(allow bool) {
- r.allowRepeatedFieldsInBody = allow
-}
-
-// IsAllowRepeatedFieldsInBody checks if repeated field can be used
-// in `body` and `response_body` (`google.api.http` annotation option) field path or not
-func (r *Registry) IsAllowRepeatedFieldsInBody() bool {
- return r.allowRepeatedFieldsInBody
-}
-
-// SetIncludePackageInTags controls whether the package name defined in the `package` directive
-// in the proto file can be prepended to the gRPC service name in the `Tags` field of every operation.
-func (r *Registry) SetIncludePackageInTags(allow bool) {
- r.includePackageInTags = allow
-}
-
-// IsIncludePackageInTags checks whether the package name defined in the `package` directive
-// in the proto file can be prepended to the gRPC service name in the `Tags` field of every operation.
-func (r *Registry) IsIncludePackageInTags() bool {
- return r.includePackageInTags
-}
-
-// GetRepeatedPathParamSeparator returns a rune spcifying how
-// path parameter repeated fields are separated.
-func (r *Registry) GetRepeatedPathParamSeparator() rune {
- return r.repeatedPathParamSeparator.sep
-}
-
-// GetRepeatedPathParamSeparatorName returns the name path parameter repeated
-// fields repeatedFieldSeparator. I.e. 'csv', 'pipe', 'ssv' or 'tsv'
-func (r *Registry) GetRepeatedPathParamSeparatorName() string {
- return r.repeatedPathParamSeparator.name
-}
-
-// SetRepeatedPathParamSeparator sets how path parameter repeated fields are
-// separated. Allowed names are 'csv', 'pipe', 'ssv' and 'tsv'.
-func (r *Registry) SetRepeatedPathParamSeparator(name string) error {
- var sep rune
- switch name {
- case "csv":
- sep = ','
- case "pipes":
- sep = '|'
- case "ssv":
- sep = ' '
- case "tsv":
- sep = '\t'
- default:
- return fmt.Errorf("unknown repeated path parameter separator: %s", name)
- }
- r.repeatedPathParamSeparator = repeatedFieldSeparator{
- name: name,
- sep: sep,
- }
- return nil
-}
-
-// SetUseJSONNamesForFields sets useJSONNamesForFields
-func (r *Registry) SetUseJSONNamesForFields(use bool) {
- r.useJSONNamesForFields = use
-}
-
-// GetUseJSONNamesForFields returns useJSONNamesForFields
-func (r *Registry) GetUseJSONNamesForFields() bool {
- return r.useJSONNamesForFields
-}
-
-// SetUseFQNForSwaggerName sets useFQNForSwaggerName
-func (r *Registry) SetUseFQNForSwaggerName(use bool) {
- r.useFQNForSwaggerName = use
-}
-
-// GetAllowColonFinalSegments returns allowColonFinalSegments
-func (r *Registry) GetAllowColonFinalSegments() bool {
- return r.allowColonFinalSegments
-}
-
-// SetAllowColonFinalSegments sets allowColonFinalSegments
-func (r *Registry) SetAllowColonFinalSegments(use bool) {
- r.allowColonFinalSegments = use
-}
-
-// GetUseFQNForSwaggerName returns useFQNForSwaggerName
-func (r *Registry) GetUseFQNForSwaggerName() bool {
- return r.useFQNForSwaggerName
-}
-
-// GetMergeFileName return the target merge swagger file name
-func (r *Registry) GetMergeFileName() string {
- return r.mergeFileName
-}
-
-// SetUseGoTemplate sets useGoTemplate
-func (r *Registry) SetUseGoTemplate(use bool) {
- r.useGoTemplate = use
-}
-
-// GetUseGoTemplate returns useGoTemplate
-func (r *Registry) GetUseGoTemplate() bool {
- return r.useGoTemplate
-}
-
-// sanitizePackageName replaces unallowed character in package name
-// with allowed character.
-func sanitizePackageName(pkgName string) string {
- pkgName = strings.Replace(pkgName, ".", "_", -1)
- pkgName = strings.Replace(pkgName, "-", "_", -1)
- return pkgName
-}
-
-// defaultGoPackageName returns the default go package name to be used for go files generated from "f".
-// You might need to use an unique alias for the package when you import it. Use ReserveGoPackageAlias to get a unique alias.
-func (r *Registry) defaultGoPackageName(f *descriptor.FileDescriptorProto) string {
- name := r.packageIdentityName(f)
- return sanitizePackageName(name)
-}
-
-// packageIdentityName returns the identity of packages.
-// protoc-gen-grpc-gateway rejects CodeGenerationRequests which contains more than one packages
-// as protoc-gen-go does.
-func (r *Registry) packageIdentityName(f *descriptor.FileDescriptorProto) string {
- if f.Options != nil && f.Options.GoPackage != nil {
- gopkg := f.Options.GetGoPackage()
- idx := strings.LastIndex(gopkg, "/")
- if idx < 0 {
- gopkg = gopkg[idx+1:]
- }
-
- gopkg = gopkg[idx+1:]
- // package name is overrided with the string after the
- // ';' character
- sc := strings.IndexByte(gopkg, ';')
- if sc < 0 {
- return sanitizePackageName(gopkg)
-
- }
- return sanitizePackageName(gopkg[sc+1:])
- }
- if p := r.importPath; len(p) != 0 {
- if i := strings.LastIndex(p, "/"); i >= 0 {
- p = p[i+1:]
- }
- return p
- }
-
- if f.Package == nil {
- base := filepath.Base(f.GetName())
- ext := filepath.Ext(base)
- return strings.TrimSuffix(base, ext)
- }
- return f.GetPackage()
-}
diff --git a/gateway/protoc-gen-grpc-gateway/generator/BUILD.bazel b/gateway/protoc-gen-grpc-gateway/generator/BUILD.bazel
deleted file mode 100644
index dcabc5e..0000000
--- a/gateway/protoc-gen-grpc-gateway/generator/BUILD.bazel
+++ /dev/null
@@ -1,13 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library")
-
-package(default_visibility = ["//visibility:public"])
-
-go_library(
- name = "go_default_library",
- srcs = ["generator.go"],
- importpath = "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/generator",
- deps = [
- "//gateway/protoc-gen-grpc-gateway/descriptor:go_default_library",
- "@io_bazel_rules_go//proto/wkt:compiler_plugin_go_proto",
- ],
-)
diff --git a/gateway/protoc-gen-grpc-gateway/generator/generator.go b/gateway/protoc-gen-grpc-gateway/generator/generator.go
deleted file mode 100644
index 9816224..0000000
--- a/gateway/protoc-gen-grpc-gateway/generator/generator.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Package generator provides an abstract interface to code generators.
-package generator
-
-import (
- plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
- // "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
- "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/descriptor"
-)
-
-// Generator is an abstraction of code generators.
-type Generator interface {
- // Generate generates output files from input .proto files.
- Generate(targets []*descriptor.File) ([]*plugin.CodeGeneratorResponse_File, error)
-}
diff --git a/gateway/protoc-gen-grpc-gateway/gengateway/BUILD.bazel b/gateway/protoc-gen-grpc-gateway/gengateway/BUILD.bazel
deleted file mode 100644
index 35955e2..0000000
--- a/gateway/protoc-gen-grpc-gateway/gengateway/BUILD.bazel
+++ /dev/null
@@ -1,40 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-
-package(default_visibility = ["//visibility:public"])
-
-go_library(
- name = "go_default_library",
- srcs = [
- "doc.go",
- "generator.go",
- "template.go",
- ],
- importpath = "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/gengateway",
- deps = [
- "//httpoptions:go_default_library",
- "//gateway/runtime:go_default_library",
- "//gateway/protoc-gen-grpc-gateway/descriptor:go_default_library",
- "//gateway/protoc-gen-grpc-gateway/generator:go_default_library",
- "@com_github_grpc_ecosystem_grpc_gateway//utilities:go_default_library",
- "@com_github_golang_glog//:go_default_library",
- "@com_github_golang_protobuf//proto:go_default_library",
- "@com_github_golang_protobuf//protoc-gen-go/generator:go_default_library_gen",
- "@io_bazel_rules_go//proto/wkt:compiler_plugin_go_proto",
- ],
-)
-
-go_test(
- name = "go_default_test",
- size = "small",
- srcs = [
- "generator_test.go",
- "template_test.go",
- ],
- embed = [":go_default_library"],
- deps = [
- "//gateway/protoc-gen-grpc-gateway/descriptor:go_default_library",
- "//gateway/protoc-gen-grpc-gateway/httprule:go_default_library",
- "@com_github_golang_protobuf//proto:go_default_library",
- "@io_bazel_rules_go//proto/wkt:descriptor_go_proto",
- ],
-)
diff --git a/gateway/protoc-gen-grpc-gateway/gengateway/generator_test.go b/gateway/protoc-gen-grpc-gateway/gengateway/generator_test.go
deleted file mode 100644
index fa09216..0000000
--- a/gateway/protoc-gen-grpc-gateway/gengateway/generator_test.go
+++ /dev/null
@@ -1,176 +0,0 @@
-package gengateway
-
-import (
- "path/filepath"
- "strings"
- "testing"
-
- "github.com/golang/protobuf/proto"
- protodescriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
- // "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
- "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/descriptor"
-)
-
-func newExampleFileDescriptor() *descriptor.File {
- return newExampleFileDescriptorWithGoPkg(
- &descriptor.GoPackage{
- Path: "example.com/path/to/example/example.pb",
- Name: "example_pb",
- },
- )
-}
-
-func newExampleFileDescriptorWithGoPkg(gp *descriptor.GoPackage) *descriptor.File {
- msgdesc := &protodescriptor.DescriptorProto{
- Name: proto.String("ExampleMessage"),
- }
- msg := &descriptor.Message{
- DescriptorProto: msgdesc,
- }
- msg1 := &descriptor.Message{
- DescriptorProto: msgdesc,
- File: &descriptor.File{
- GoPkg: descriptor.GoPackage{
- Path: "github.com/golang/protobuf/ptypes/empty",
- Name: "empty",
- },
- },
- }
- meth := &protodescriptor.MethodDescriptorProto{
- Name: proto.String("Example"),
- InputType: proto.String("ExampleMessage"),
- OutputType: proto.String("ExampleMessage"),
- }
- meth1 := &protodescriptor.MethodDescriptorProto{
- Name: proto.String("ExampleWithoutBindings"),
- InputType: proto.String("empty.Empty"),
- OutputType: proto.String("empty.Empty"),
- }
- svc := &protodescriptor.ServiceDescriptorProto{
- Name: proto.String("ExampleService"),
- Method: []*protodescriptor.MethodDescriptorProto{meth, meth1},
- }
- return &descriptor.File{
- FileDescriptorProto: &protodescriptor.FileDescriptorProto{
- Name: proto.String("example.proto"),
- Package: proto.String("example"),
- Dependency: []string{"a.example/b/c.proto", "a.example/d/e.proto"},
- MessageType: []*protodescriptor.DescriptorProto{msgdesc},
- Service: []*protodescriptor.ServiceDescriptorProto{svc},
- },
- GoPkg: *gp,
- Messages: []*descriptor.Message{msg},
- Services: []*descriptor.Service{
- {
- ServiceDescriptorProto: svc,
- Methods: []*descriptor.Method{
- {
- MethodDescriptorProto: meth,
- RequestType: msg,
- ResponseType: msg,
- Bindings: []*descriptor.Binding{
- {
- HTTPMethod: "GET",
- Body: &descriptor.Body{FieldPath: nil},
- },
- },
- },
- {
- MethodDescriptorProto: meth1,
- RequestType: msg1,
- ResponseType: msg1,
- },
- },
- },
- },
- }
-}
-
-func TestGenerateServiceWithoutBindings(t *testing.T) {
- file := newExampleFileDescriptor()
- g := &generator{}
- got, err := g.generate(crossLinkFixture(file))
- if err != nil {
- t.Errorf("generate(%#v) failed with %v; want success", file, err)
- return
- }
- if notwanted := `"github.com/golang/protobuf/ptypes/empty"`; strings.Contains(got, notwanted) {
- t.Errorf("generate(%#v) = %s; does not want to contain %s", file, got, notwanted)
- }
-}
-
-func TestGenerateOutputPath(t *testing.T) {
- cases := []struct {
- file *descriptor.File
- pathType pathType
- expected string
- }{
- {
- file: newExampleFileDescriptorWithGoPkg(
- &descriptor.GoPackage{
- Path: "example.com/path/to/example",
- Name: "example_pb",
- },
- ),
- expected: "example.com/path/to/example",
- },
- {
- file: newExampleFileDescriptorWithGoPkg(
- &descriptor.GoPackage{
- Path: "example",
- Name: "example_pb",
- },
- ),
- expected: "example",
- },
- {
- file: newExampleFileDescriptorWithGoPkg(
- &descriptor.GoPackage{
- Path: "example.com/path/to/example",
- Name: "example_pb",
- },
- ),
- pathType: pathTypeSourceRelative,
- expected: ".",
- },
- {
- file: newExampleFileDescriptorWithGoPkg(
- &descriptor.GoPackage{
- Path: "example",
- Name: "example_pb",
- },
- ),
- pathType: pathTypeSourceRelative,
- expected: ".",
- },
- }
-
- for _, c := range cases {
- g := &generator{pathType: c.pathType}
-
- file := c.file
- gots, err := g.Generate([]*descriptor.File{crossLinkFixture(file)})
- if err != nil {
- t.Errorf("Generate(%#v) failed with %v; wants success", file, err)
- return
- }
-
- if len(gots) != 1 {
- t.Errorf("Generate(%#v) failed; expects on result got %d", file, len(gots))
- return
- }
-
- got := gots[0]
- if got.Name == nil {
- t.Errorf("Generate(%#v) failed; expects non-nil Name(%v)", file, got.Name)
- return
- }
-
- gotPath := filepath.Dir(*got.Name)
- expectedPath := c.expected
- if gotPath != expectedPath {
- t.Errorf("Generate(%#v) failed; got path: %s expected path: %s", file, gotPath, expectedPath)
- return
- }
- }
-}
diff --git a/gateway/protoc-gen-grpc-gateway/httprule/BUILD.bazel b/gateway/protoc-gen-grpc-gateway/httprule/BUILD.bazel
deleted file mode 100644
index 957db8f..0000000
--- a/gateway/protoc-gen-grpc-gateway/httprule/BUILD.bazel
+++ /dev/null
@@ -1,32 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-
-package(default_visibility = ["//visibility:public"])
-
-go_library(
- name = "go_default_library",
- srcs = [
- "compile.go",
- "parse.go",
- "types.go",
- ],
- importpath = "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/httprule",
- deps = [
- "@com_github_golang_glog//:go_default_library",
- "@com_github_grpc_ecosystem_grpc_gateway//utilities:go_default_library",
- ],
-)
-
-go_test(
- name = "go_default_test",
- size = "small",
- srcs = [
- "compile_test.go",
- "parse_test.go",
- "types_test.go",
- ],
- embed = [":go_default_library"],
- deps = [
- "@com_github_golang_glog//:go_default_library",
- "@com_github_grpc_ecosystem_grpc_gateway//utilities:go_default_library",
- ],
-)
diff --git a/gateway/protoc-gen-grpc-gateway/httprule/compile.go b/gateway/protoc-gen-grpc-gateway/httprule/compile.go
deleted file mode 100644
index 437039a..0000000
--- a/gateway/protoc-gen-grpc-gateway/httprule/compile.go
+++ /dev/null
@@ -1,117 +0,0 @@
-package httprule
-
-import (
- "github.com/grpc-ecosystem/grpc-gateway/utilities"
-)
-
-const (
- opcodeVersion = 1
-)
-
-// Template is a compiled representation of path templates.
-type Template struct {
- // Version is the version number of the format.
- Version int
- // OpCodes is a sequence of operations.
- OpCodes []int
- // Pool is a constant pool
- Pool []string
- // Verb is a VERB part in the template.
- Verb string
- // Fields is a list of field paths bound in this template.
- Fields []string
- // Original template (example: /v1/a_bit_of_everything)
- Template string
-}
-
-// Compiler compiles utilities representation of path templates into marshallable operations.
-// They can be unmarshalled by runtime.NewPattern.
-type Compiler interface {
- Compile() Template
-}
-
-type op struct {
- // code is the opcode of the operation
- code utilities.OpCode
-
- // str is a string operand of the code.
- // num is ignored if str is not empty.
- str string
-
- // num is a numeric operand of the code.
- num int
-}
-
-func (w wildcard) compile() []op {
- return []op{
- {code: utilities.OpPush},
- }
-}
-
-func (w deepWildcard) compile() []op {
- return []op{
- {code: utilities.OpPushM},
- }
-}
-
-func (l literal) compile() []op {
- return []op{
- {
- code: utilities.OpLitPush,
- str: string(l),
- },
- }
-}
-
-func (v variable) compile() []op {
- var ops []op
- for _, s := range v.segments {
- ops = append(ops, s.compile()...)
- }
- ops = append(ops, op{
- code: utilities.OpConcatN,
- num: len(v.segments),
- }, op{
- code: utilities.OpCapture,
- str: v.path,
- })
-
- return ops
-}
-
-func (t template) Compile() Template {
- var rawOps []op
- for _, s := range t.segments {
- rawOps = append(rawOps, s.compile()...)
- }
-
- var (
- ops []int
- pool []string
- fields []string
- )
- consts := make(map[string]int)
- for _, op := range rawOps {
- ops = append(ops, int(op.code))
- if op.str == "" {
- ops = append(ops, op.num)
- } else {
- if _, ok := consts[op.str]; !ok {
- consts[op.str] = len(pool)
- pool = append(pool, op.str)
- }
- ops = append(ops, consts[op.str])
- }
- if op.code == utilities.OpCapture {
- fields = append(fields, op.str)
- }
- }
- return Template{
- Version: opcodeVersion,
- OpCodes: ops,
- Pool: pool,
- Verb: t.verb,
- Fields: fields,
- Template: t.template,
- }
-}
diff --git a/gateway/protoc-gen-grpc-gateway/httprule/compile_test.go b/gateway/protoc-gen-grpc-gateway/httprule/compile_test.go
deleted file mode 100644
index 9ef2975..0000000
--- a/gateway/protoc-gen-grpc-gateway/httprule/compile_test.go
+++ /dev/null
@@ -1,122 +0,0 @@
-package httprule
-
-import (
- "reflect"
- "testing"
-
- "github.com/grpc-ecosystem/grpc-gateway/utilities"
-)
-
-const (
- operandFiller = 0
-)
-
-func TestCompile(t *testing.T) {
- for _, spec := range []struct {
- segs []segment
- verb string
-
- ops []int
- pool []string
- fields []string
- }{
- {},
- {
- segs: []segment{
- wildcard{},
- },
- ops: []int{int(utilities.OpPush), operandFiller},
- },
- {
- segs: []segment{
- deepWildcard{},
- },
- ops: []int{int(utilities.OpPushM), operandFiller},
- },
- {
- segs: []segment{
- literal("v1"),
- },
- ops: []int{int(utilities.OpLitPush), 0},
- pool: []string{"v1"},
- },
- {
- segs: []segment{
- literal("v1"),
- },
- verb: "LOCK",
- ops: []int{int(utilities.OpLitPush), 0},
- pool: []string{"v1"},
- },
- {
- segs: []segment{
- variable{
- path: "name.nested",
- segments: []segment{
- wildcard{},
- },
- },
- },
- ops: []int{
- int(utilities.OpPush), operandFiller,
- int(utilities.OpConcatN), 1,
- int(utilities.OpCapture), 0,
- },
- pool: []string{"name.nested"},
- fields: []string{"name.nested"},
- },
- {
- segs: []segment{
- literal("obj"),
- variable{
- path: "name.nested",
- segments: []segment{
- literal("a"),
- wildcard{},
- literal("b"),
- },
- },
- variable{
- path: "obj",
- segments: []segment{
- deepWildcard{},
- },
- },
- },
- ops: []int{
- int(utilities.OpLitPush), 0,
- int(utilities.OpLitPush), 1,
- int(utilities.OpPush), operandFiller,
- int(utilities.OpLitPush), 2,
- int(utilities.OpConcatN), 3,
- int(utilities.OpCapture), 3,
- int(utilities.OpPushM), operandFiller,
- int(utilities.OpConcatN), 1,
- int(utilities.OpCapture), 0,
- },
- pool: []string{"obj", "a", "b", "name.nested"},
- fields: []string{"name.nested", "obj"},
- },
- } {
- tmpl := template{
- segments: spec.segs,
- verb: spec.verb,
- }
- compiled := tmpl.Compile()
- if got, want := compiled.Version, opcodeVersion; got != want {
- t.Errorf("tmpl.Compile().Version = %d; want %d; segs=%#v, verb=%q", got, want, spec.segs, spec.verb)
- }
- if got, want := compiled.OpCodes, spec.ops; !reflect.DeepEqual(got, want) {
- t.Errorf("tmpl.Compile().OpCodes = %v; want %v; segs=%#v, verb=%q", got, want, spec.segs, spec.verb)
- }
- if got, want := compiled.Pool, spec.pool; !reflect.DeepEqual(got, want) {
- t.Errorf("tmpl.Compile().Pool = %q; want %q; segs=%#v, verb=%q", got, want, spec.segs, spec.verb)
- }
- if got, want := compiled.Verb, spec.verb; got != want {
- t.Errorf("tmpl.Compile().Verb = %q; want %q; segs=%#v, verb=%q", got, want, spec.segs, spec.verb)
- }
- if got, want := compiled.Fields, spec.fields; !reflect.DeepEqual(got, want) {
- t.Errorf("tmpl.Compile().Fields = %q; want %q; segs=%#v, verb=%q", got, want, spec.segs, spec.verb)
- }
- }
-}
diff --git a/gateway/protoc-gen-grpc-gateway/httprule/fuzz.go b/gateway/protoc-gen-grpc-gateway/httprule/fuzz.go
deleted file mode 100644
index 138f7c1..0000000
--- a/gateway/protoc-gen-grpc-gateway/httprule/fuzz.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// +build gofuzz
-
-package httprule
-
-func Fuzz(data []byte) int {
- _, err := Parse(string(data))
- if err != nil {
- return 0
- }
- return 0
-}
diff --git a/gateway/protoc-gen-grpc-gateway/httprule/parse.go b/gateway/protoc-gen-grpc-gateway/httprule/parse.go
deleted file mode 100644
index f933cd8..0000000
--- a/gateway/protoc-gen-grpc-gateway/httprule/parse.go
+++ /dev/null
@@ -1,351 +0,0 @@
-package httprule
-
-import (
- "fmt"
- "strings"
-
- "github.com/golang/glog"
-)
-
-// InvalidTemplateError indicates that the path template is not valid.
-type InvalidTemplateError struct {
- tmpl string
- msg string
-}
-
-func (e InvalidTemplateError) Error() string {
- return fmt.Sprintf("%s: %s", e.msg, e.tmpl)
-}
-
-// Parse parses the string representation of path template
-func Parse(tmpl string) (Compiler, error) {
- if !strings.HasPrefix(tmpl, "/") {
- return template{}, InvalidTemplateError{tmpl: tmpl, msg: "no leading /"}
- }
- tokens, verb := tokenize(tmpl[1:])
-
- p := parser{tokens: tokens}
- segs, err := p.topLevelSegments()
- if err != nil {
- return template{}, InvalidTemplateError{tmpl: tmpl, msg: err.Error()}
- }
-
- return template{
- segments: segs,
- verb: verb,
- template: tmpl,
- }, nil
-}
-
-func tokenize(path string) (tokens []string, verb string) {
- if path == "" {
- return []string{eof}, ""
- }
-
- const (
- init = iota
- field
- nested
- )
- var (
- st = init
- )
- for path != "" {
- var idx int
- switch st {
- case init:
- idx = strings.IndexAny(path, "/{")
- case field:
- idx = strings.IndexAny(path, ".=}")
- case nested:
- idx = strings.IndexAny(path, "/}")
- }
- if idx < 0 {
- tokens = append(tokens, path)
- break
- }
- switch r := path[idx]; r {
- case '/', '.':
- case '{':
- st = field
- case '=':
- st = nested
- case '}':
- st = init
- }
- if idx == 0 {
- tokens = append(tokens, path[idx:idx+1])
- } else {
- tokens = append(tokens, path[:idx], path[idx:idx+1])
- }
- path = path[idx+1:]
- }
-
- l := len(tokens)
- t := tokens[l-1]
- if idx := strings.LastIndex(t, ":"); idx == 0 {
- tokens, verb = tokens[:l-1], t[1:]
- } else if idx > 0 {
- tokens[l-1], verb = t[:idx], t[idx+1:]
- }
- tokens = append(tokens, eof)
- return tokens, verb
-}
-
-// parser is a parser of the template syntax defined in github.com/googleapis/googleapis/google/api/http.proto.
-type parser struct {
- tokens []string
- accepted []string
-}
-
-// topLevelSegments is the target of this parser.
-func (p *parser) topLevelSegments() ([]segment, error) {
- glog.V(1).Infof("Parsing %q", p.tokens)
- segs, err := p.segments()
- if err != nil {
- return nil, err
- }
- glog.V(2).Infof("accept segments: %q; %q", p.accepted, p.tokens)
- if _, err := p.accept(typeEOF); err != nil {
- return nil, fmt.Errorf("unexpected token %q after segments %q", p.tokens[0], strings.Join(p.accepted, ""))
- }
- glog.V(2).Infof("accept eof: %q; %q", p.accepted, p.tokens)
- return segs, nil
-}
-
-func (p *parser) segments() ([]segment, error) {
- s, err := p.segment()
- if err != nil {
- return nil, err
- }
- glog.V(2).Infof("accept segment: %q; %q", p.accepted, p.tokens)
-
- segs := []segment{s}
- for {
- if _, err := p.accept("/"); err != nil {
- return segs, nil
- }
- s, err := p.segment()
- if err != nil {
- return segs, err
- }
- segs = append(segs, s)
- glog.V(2).Infof("accept segment: %q; %q", p.accepted, p.tokens)
- }
-}
-
-func (p *parser) segment() (segment, error) {
- if _, err := p.accept("*"); err == nil {
- return wildcard{}, nil
- }
- if _, err := p.accept("**"); err == nil {
- return deepWildcard{}, nil
- }
- if l, err := p.literal(); err == nil {
- return l, nil
- }
-
- v, err := p.variable()
- if err != nil {
- return nil, fmt.Errorf("segment neither wildcards, literal or variable: %v", err)
- }
- return v, err
-}
-
-func (p *parser) literal() (segment, error) {
- lit, err := p.accept(typeLiteral)
- if err != nil {
- return nil, err
- }
- return literal(lit), nil
-}
-
-func (p *parser) variable() (segment, error) {
- if _, err := p.accept("{"); err != nil {
- return nil, err
- }
-
- path, err := p.fieldPath()
- if err != nil {
- return nil, err
- }
-
- var segs []segment
- if _, err := p.accept("="); err == nil {
- segs, err = p.segments()
- if err != nil {
- return nil, fmt.Errorf("invalid segment in variable %q: %v", path, err)
- }
- } else {
- segs = []segment{wildcard{}}
- }
-
- if _, err := p.accept("}"); err != nil {
- return nil, fmt.Errorf("unterminated variable segment: %s", path)
- }
- return variable{
- path: path,
- segments: segs,
- }, nil
-}
-
-func (p *parser) fieldPath() (string, error) {
- c, err := p.accept(typeIdent)
- if err != nil {
- return "", err
- }
- components := []string{c}
- for {
- if _, err = p.accept("."); err != nil {
- return strings.Join(components, "."), nil
- }
- c, err := p.accept(typeIdent)
- if err != nil {
- return "", fmt.Errorf("invalid field path component: %v", err)
- }
- components = append(components, c)
- }
-}
-
-// A termType is a type of terminal symbols.
-type termType string
-
-// These constants define some of valid values of termType.
-// They improve readability of parse functions.
-//
-// You can also use "/", "*", "**", "." or "=" as valid values.
-const (
- typeIdent = termType("ident")
- typeLiteral = termType("literal")
- typeEOF = termType("$")
-)
-
-const (
- // eof is the terminal symbol which always appears at the end of token sequence.
- eof = "\u0000"
-)
-
-// accept tries to accept a token in "p".
-// This function consumes a token and returns it if it matches to the specified "term".
-// If it doesn't match, the function does not consume any tokens and return an error.
-func (p *parser) accept(term termType) (string, error) {
- t := p.tokens[0]
- switch term {
- case "/", "*", "**", ".", "=", "{", "}":
- if t != string(term) && t != "/" {
- return "", fmt.Errorf("expected %q but got %q", term, t)
- }
- case typeEOF:
- if t != eof {
- return "", fmt.Errorf("expected EOF but got %q", t)
- }
- case typeIdent:
- if err := expectIdent(t); err != nil {
- return "", err
- }
- case typeLiteral:
- if err := expectPChars(t); err != nil {
- return "", err
- }
- default:
- return "", fmt.Errorf("unknown termType %q", term)
- }
- p.tokens = p.tokens[1:]
- p.accepted = append(p.accepted, t)
- return t, nil
-}
-
-// expectPChars determines if "t" consists of only pchars defined in RFC3986.
-//
-// https://www.ietf.org/rfc/rfc3986.txt, P.49
-// pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
-// unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
-// sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
-// / "*" / "+" / "," / ";" / "="
-// pct-encoded = "%" HEXDIG HEXDIG
-func expectPChars(t string) error {
- const (
- init = iota
- pct1
- pct2
- )
- st := init
- for _, r := range t {
- if st != init {
- if !isHexDigit(r) {
- return fmt.Errorf("invalid hexdigit: %c(%U)", r, r)
- }
- switch st {
- case pct1:
- st = pct2
- case pct2:
- st = init
- }
- continue
- }
-
- // unreserved
- switch {
- case 'A' <= r && r <= 'Z':
- continue
- case 'a' <= r && r <= 'z':
- continue
- case '0' <= r && r <= '9':
- continue
- }
- switch r {
- case '-', '.', '_', '~':
- // unreserved
- case '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=':
- // sub-delims
- case ':', '@':
- // rest of pchar
- case '%':
- // pct-encoded
- st = pct1
- default:
- return fmt.Errorf("invalid character in path segment: %q(%U)", r, r)
- }
- }
- if st != init {
- return fmt.Errorf("invalid percent-encoding in %q", t)
- }
- return nil
-}
-
-// expectIdent determines if "ident" is a valid identifier in .proto schema ([[:alpha:]_][[:alphanum:]_]*).
-func expectIdent(ident string) error {
- if ident == "" {
- return fmt.Errorf("empty identifier")
- }
- for pos, r := range ident {
- switch {
- case '0' <= r && r <= '9':
- if pos == 0 {
- return fmt.Errorf("identifier starting with digit: %s", ident)
- }
- continue
- case 'A' <= r && r <= 'Z':
- continue
- case 'a' <= r && r <= 'z':
- continue
- case r == '_':
- continue
- default:
- return fmt.Errorf("invalid character %q(%U) in identifier: %s", r, r, ident)
- }
- }
- return nil
-}
-
-func isHexDigit(r rune) bool {
- switch {
- case '0' <= r && r <= '9':
- return true
- case 'A' <= r && r <= 'F':
- return true
- case 'a' <= r && r <= 'f':
- return true
- }
- return false
-}
diff --git a/gateway/protoc-gen-grpc-gateway/httprule/parse_test.go b/gateway/protoc-gen-grpc-gateway/httprule/parse_test.go
deleted file mode 100644
index 6508e82..0000000
--- a/gateway/protoc-gen-grpc-gateway/httprule/parse_test.go
+++ /dev/null
@@ -1,319 +0,0 @@
-package httprule
-
-import (
- "flag"
- "fmt"
- "reflect"
- "testing"
-
- "github.com/golang/glog"
-)
-
-func TestTokenize(t *testing.T) {
- for _, spec := range []struct {
- src string
- tokens []string
- }{
- {
- src: "",
- tokens: []string{eof},
- },
- {
- src: "v1",
- tokens: []string{"v1", eof},
- },
- {
- src: "v1/b",
- tokens: []string{"v1", "/", "b", eof},
- },
- {
- src: "v1/endpoint/*",
- tokens: []string{"v1", "/", "endpoint", "/", "*", eof},
- },
- {
- src: "v1/endpoint/**",
- tokens: []string{"v1", "/", "endpoint", "/", "**", eof},
- },
- {
- src: "v1/b/{bucket_name=*}",
- tokens: []string{
- "v1", "/",
- "b", "/",
- "{", "bucket_name", "=", "*", "}",
- eof,
- },
- },
- {
- src: "v1/b/{bucket_name=buckets/*}",
- tokens: []string{
- "v1", "/",
- "b", "/",
- "{", "bucket_name", "=", "buckets", "/", "*", "}",
- eof,
- },
- },
- {
- src: "v1/b/{bucket_name=buckets/*}/o",
- tokens: []string{
- "v1", "/",
- "b", "/",
- "{", "bucket_name", "=", "buckets", "/", "*", "}", "/",
- "o",
- eof,
- },
- },
- {
- src: "v1/b/{bucket_name=buckets/*}/o/{name}",
- tokens: []string{
- "v1", "/",
- "b", "/",
- "{", "bucket_name", "=", "buckets", "/", "*", "}", "/",
- "o", "/", "{", "name", "}",
- eof,
- },
- },
- {
- src: "v1/a=b&c=d;e=f:g/endpoint.rdf",
- tokens: []string{
- "v1", "/",
- "a=b&c=d;e=f:g", "/",
- "endpoint.rdf",
- eof,
- },
- },
- } {
- tokens, verb := tokenize(spec.src)
- if got, want := tokens, spec.tokens; !reflect.DeepEqual(got, want) {
- t.Errorf("tokenize(%q) = %q, _; want %q, _", spec.src, got, want)
- }
- if got, want := verb, ""; got != want {
- t.Errorf("tokenize(%q) = _, %q; want _, %q", spec.src, got, want)
- }
-
- src := fmt.Sprintf("%s:%s", spec.src, "LOCK")
- tokens, verb = tokenize(src)
- if got, want := tokens, spec.tokens; !reflect.DeepEqual(got, want) {
- t.Errorf("tokenize(%q) = %q, _; want %q, _", src, got, want)
- }
- if got, want := verb, "LOCK"; got != want {
- t.Errorf("tokenize(%q) = _, %q; want _, %q", src, got, want)
- }
- }
-}
-
-func TestParseSegments(t *testing.T) {
- flag.Set("v", "3")
- for _, spec := range []struct {
- tokens []string
- want []segment
- }{
- {
- tokens: []string{"v1", eof},
- want: []segment{
- literal("v1"),
- },
- },
- {
- tokens: []string{"/", eof},
- want: []segment{
- wildcard{},
- },
- },
- {
- tokens: []string{"-._~!$&'()*+,;=:@", eof},
- want: []segment{
- literal("-._~!$&'()*+,;=:@"),
- },
- },
- {
- tokens: []string{"%e7%ac%ac%e4%b8%80%e7%89%88", eof},
- want: []segment{
- literal("%e7%ac%ac%e4%b8%80%e7%89%88"),
- },
- },
- {
- tokens: []string{"v1", "/", "*", eof},
- want: []segment{
- literal("v1"),
- wildcard{},
- },
- },
- {
- tokens: []string{"v1", "/", "**", eof},
- want: []segment{
- literal("v1"),
- deepWildcard{},
- },
- },
- {
- tokens: []string{"{", "name", "}", eof},
- want: []segment{
- variable{
- path: "name",
- segments: []segment{
- wildcard{},
- },
- },
- },
- },
- {
- tokens: []string{"{", "name", "=", "*", "}", eof},
- want: []segment{
- variable{
- path: "name",
- segments: []segment{
- wildcard{},
- },
- },
- },
- },
- {
- tokens: []string{"{", "field", ".", "nested", ".", "nested2", "=", "*", "}", eof},
- want: []segment{
- variable{
- path: "field.nested.nested2",
- segments: []segment{
- wildcard{},
- },
- },
- },
- },
- {
- tokens: []string{"{", "name", "=", "a", "/", "b", "/", "*", "}", eof},
- want: []segment{
- variable{
- path: "name",
- segments: []segment{
- literal("a"),
- literal("b"),
- wildcard{},
- },
- },
- },
- },
- {
- tokens: []string{
- "v1", "/",
- "{",
- "name", ".", "nested", ".", "nested2",
- "=",
- "a", "/", "b", "/", "*",
- "}", "/",
- "o", "/",
- "{",
- "another_name",
- "=",
- "a", "/", "b", "/", "*", "/", "c",
- "}", "/",
- "**",
- eof},
- want: []segment{
- literal("v1"),
- variable{
- path: "name.nested.nested2",
- segments: []segment{
- literal("a"),
- literal("b"),
- wildcard{},
- },
- },
- literal("o"),
- variable{
- path: "another_name",
- segments: []segment{
- literal("a"),
- literal("b"),
- wildcard{},
- literal("c"),
- },
- },
- deepWildcard{},
- },
- },
- } {
- p := parser{tokens: spec.tokens}
- segs, err := p.topLevelSegments()
- if err != nil {
- t.Errorf("parser{%q}.segments() failed with %v; want success", spec.tokens, err)
- continue
- }
- if got, want := segs, spec.want; !reflect.DeepEqual(got, want) {
- t.Errorf("parser{%q}.segments() = %#v; want %#v", spec.tokens, got, want)
- }
- if got := p.tokens; len(got) > 0 {
- t.Errorf("p.tokens = %q; want []; spec.tokens=%q", got, spec.tokens)
- }
- }
-}
-
-func TestParseSegmentsWithErrors(t *testing.T) {
- flag.Set("v", "3")
- for _, spec := range []struct {
- tokens []string
- }{
- {
- // double slash
- tokens: []string{"//", eof},
- },
- {
- // invalid literal
- tokens: []string{"a?b", eof},
- },
- {
- // invalid percent-encoding
- tokens: []string{"%", eof},
- },
- {
- // invalid percent-encoding
- tokens: []string{"%2", eof},
- },
- {
- // invalid percent-encoding
- tokens: []string{"a%2z", eof},
- },
- {
- // empty segments
- tokens: []string{eof},
- },
- {
- // unterminated variable
- tokens: []string{"{", "name", eof},
- },
- {
- // unterminated variable
- tokens: []string{"{", "name", "=", eof},
- },
- {
- // unterminated variable
- tokens: []string{"{", "name", "=", "*", eof},
- },
- {
- // empty component in field path
- tokens: []string{"{", "name", ".", "}", eof},
- },
- {
- // empty component in field path
- tokens: []string{"{", "name", ".", ".", "nested", "}", eof},
- },
- {
- // invalid character in identifier
- tokens: []string{"{", "field-name", "}", eof},
- },
- {
- // no slash between segments
- tokens: []string{"v1", "endpoint", eof},
- },
- {
- // no slash between segments
- tokens: []string{"v1", "{", "name", "}", eof},
- },
- } {
- p := parser{tokens: spec.tokens}
- segs, err := p.topLevelSegments()
- if err == nil {
- t.Errorf("parser{%q}.segments() succeeded; want InvalidTemplateError; accepted %#v", spec.tokens, segs)
- continue
- }
- glog.V(1).Info(err)
- }
-}
diff --git a/gateway/protoc-gen-grpc-gateway/httprule/types.go b/gateway/protoc-gen-grpc-gateway/httprule/types.go
deleted file mode 100644
index 5a814a0..0000000
--- a/gateway/protoc-gen-grpc-gateway/httprule/types.go
+++ /dev/null
@@ -1,60 +0,0 @@
-package httprule
-
-import (
- "fmt"
- "strings"
-)
-
-type template struct {
- segments []segment
- verb string
- template string
-}
-
-type segment interface {
- fmt.Stringer
- compile() (ops []op)
-}
-
-type wildcard struct{}
-
-type deepWildcard struct{}
-
-type literal string
-
-type variable struct {
- path string
- segments []segment
-}
-
-func (wildcard) String() string {
- return "*"
-}
-
-func (deepWildcard) String() string {
- return "**"
-}
-
-func (l literal) String() string {
- return string(l)
-}
-
-func (v variable) String() string {
- var segs []string
- for _, s := range v.segments {
- segs = append(segs, s.String())
- }
- return fmt.Sprintf("{%s=%s}", v.path, strings.Join(segs, "/"))
-}
-
-func (t template) String() string {
- var segs []string
- for _, s := range t.segments {
- segs = append(segs, s.String())
- }
- str := strings.Join(segs, "/")
- if t.verb != "" {
- str = fmt.Sprintf("%s:%s", str, t.verb)
- }
- return "/" + str
-}
diff --git a/gateway/protoc-gen-grpc-gateway/httprule/types_test.go b/gateway/protoc-gen-grpc-gateway/httprule/types_test.go
deleted file mode 100644
index 7ed0c5c..0000000
--- a/gateway/protoc-gen-grpc-gateway/httprule/types_test.go
+++ /dev/null
@@ -1,91 +0,0 @@
-package httprule
-
-import (
- "fmt"
- "testing"
-)
-
-func TestTemplateStringer(t *testing.T) {
- for _, spec := range []struct {
- segs []segment
- want string
- }{
- {
- segs: []segment{
- literal("v1"),
- },
- want: "/v1",
- },
- {
- segs: []segment{
- wildcard{},
- },
- want: "/*",
- },
- {
- segs: []segment{
- deepWildcard{},
- },
- want: "/**",
- },
- {
- segs: []segment{
- variable{
- path: "name",
- segments: []segment{
- literal("a"),
- },
- },
- },
- want: "/{name=a}",
- },
- {
- segs: []segment{
- variable{
- path: "name",
- segments: []segment{
- literal("a"),
- wildcard{},
- literal("b"),
- },
- },
- },
- want: "/{name=a/*/b}",
- },
- {
- segs: []segment{
- literal("v1"),
- variable{
- path: "name",
- segments: []segment{
- literal("a"),
- wildcard{},
- literal("b"),
- },
- },
- literal("c"),
- variable{
- path: "field.nested",
- segments: []segment{
- wildcard{},
- literal("d"),
- },
- },
- wildcard{},
- literal("e"),
- deepWildcard{},
- },
- want: "/v1/{name=a/*/b}/c/{field.nested=*/d}/*/e/**",
- },
- } {
- tmpl := template{segments: spec.segs}
- if got, want := tmpl.String(), spec.want; got != want {
- t.Errorf("%#v.String() = %q; want %q", tmpl, got, want)
- }
-
- tmpl.verb = "LOCK"
- if got, want := tmpl.String(), fmt.Sprintf("%s:LOCK", spec.want); got != want {
- t.Errorf("%#v.String() = %q; want %q", tmpl, got, want)
- }
- }
-}
diff --git a/gateway/protoc-gen-grpc-gateway/internal/gengateway/BUILD.bazel b/gateway/protoc-gen-grpc-gateway/internal/gengateway/BUILD.bazel
new file mode 100644
index 0000000..880cd64
--- /dev/null
+++ b/gateway/protoc-gen-grpc-gateway/internal/gengateway/BUILD.bazel
@@ -0,0 +1,45 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+
+package(default_visibility = ["//visibility:public"])
+
+go_library(
+ name = "gengateway",
+ srcs = [
+ "doc.go",
+ "generator.go",
+ "template.go",
+ ],
+ importpath = "github.com/binchencoder/janus-gateway/gateway/protoc-gen-grpc-gateway/internal/gengateway",
+ deps = [
+ "//httpoptions",
+ "//gateway/internal/casing",
+ "//gateway/internal/descriptor",
+ "//gateway/internal/generator",
+ "@com_github_grpc_ecosystem_grpc_gateway//utilities",
+ "@com_github_golang_glog//:glog",
+ "@org_golang_google_protobuf//proto",
+ "@org_golang_google_protobuf//types/pluginpb",
+ ],
+)
+
+go_test(
+ name = "gengateway_test",
+ size = "small",
+ srcs = [
+ "generator_test.go",
+ "template_test.go",
+ ],
+ embed = [":gengateway"],
+ deps = [
+ "//gateway/internal/descriptor",
+ "@com_github_grpc_ecosystem_grpc_gateway//internal/httprule",
+ "@org_golang_google_protobuf//proto",
+ "@org_golang_google_protobuf//types/descriptorpb",
+ ],
+)
+
+alias(
+ name = "go_default_library",
+ actual = ":gengateway",
+ visibility = ["//protoc-gen-grpc-gateway:__subpackages__"],
+)
diff --git a/gateway/protoc-gen-grpc-gateway/gengateway/doc.go b/gateway/protoc-gen-grpc-gateway/internal/gengateway/doc.go
similarity index 100%
rename from gateway/protoc-gen-grpc-gateway/gengateway/doc.go
rename to gateway/protoc-gen-grpc-gateway/internal/gengateway/doc.go
diff --git a/gateway/protoc-gen-grpc-gateway/gengateway/generator.go b/gateway/protoc-gen-grpc-gateway/internal/gengateway/generator.go
similarity index 58%
rename from gateway/protoc-gen-grpc-gateway/gengateway/generator.go
rename to gateway/protoc-gen-grpc-gateway/internal/gengateway/generator.go
index f229696..5b95e48 100644
--- a/gateway/protoc-gen-grpc-gateway/gengateway/generator.go
+++ b/gateway/protoc-gen-grpc-gateway/internal/gengateway/generator.go
@@ -5,44 +5,32 @@ import (
"fmt"
"go/format"
"path"
- "path/filepath"
- "strings"
"github.com/golang/glog"
- "github.com/golang/protobuf/proto"
- plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
-
- // "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
- "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/descriptor"
-
- // gen "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/generator"
- gen "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/generator"
-
- options "github.com/binchencoder/ease-gateway/httpoptions"
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor"
+ "github.com/binchencoder/janus-gateway/gateway/internal/descriptor"
+ // gen "github.com/grpc-ecosystem/grpc-gateway/v2/internal/generator"
+ gen "github.com/binchencoder/janus-gateway/gateway/internal/generator"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/types/pluginpb"
)
var (
errNoTargetService = errors.New("no target service defined in the file")
)
-type pathType int
-
-const (
- pathTypeImport pathType = iota
- pathTypeSourceRelative
-)
-
type generator struct {
reg *descriptor.Registry
baseImports []descriptor.GoPackage
useRequestContext bool
registerFuncSuffix string
- pathType pathType
allowPatchFeature bool
+ standalone bool
}
// New returns a new generator which generates grpc gateway files.
-func New(reg *descriptor.Registry, useRequestContext bool, registerFuncSuffix, pathTypeString string, allowPatchFeature bool) gen.Generator {
+func New(reg *descriptor.Registry, useRequestContext bool, registerFuncSuffix string,
+ allowPatchFeature, standalone bool) gen.Generator {
var imports []descriptor.GoPackage
for pkgpath, alias := range map[string]string{
"context": "",
@@ -52,21 +40,22 @@ func New(reg *descriptor.Registry, useRequestContext bool, registerFuncSuffix, p
"strings": "",
"sync": "",
"unicode/utf8": "",
- "github.com/binchencoder/ease-gateway/gateway/runtime": "",
- "github.com/grpc-ecosystem/grpc-gateway/utilities": "",
- "github.com/golang/protobuf/proto": "",
- "github.com/binchencoder/gateway-proto/data": "vexpb",
- "github.com/binchencoder/gateway-proto/frontend": "fpb",
- "github.com/binchencoder/letsgo/grpc": "lgr",
- "github.com/binchencoder/skylb-api/balancer": "",
- "github.com/binchencoder/skylb-api/client": "",
- "github.com/binchencoder/skylb-api/client/option": "",
- "github.com/binchencoder/skylb-api/proto": "skypb",
- "google.golang.org/grpc": "",
- "google.golang.org/grpc/codes": "",
- "google.golang.org/grpc/naming": "",
- // "google.golang.org/grpc/grpclog": "",
- "google.golang.org/grpc/status": "",
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/runtime",
+ "github.com/binchencoder/janus-gateway/gateway/runtime": "",
+ "github.com/grpc-ecosystem/grpc-gateway/v2/utilities": "",
+ "google.golang.org/protobuf/proto": "",
+ "github.com/binchencoder/gateway-proto/data": "vexpb",
+ "github.com/binchencoder/gateway-proto/frontend": "fpb",
+ "github.com/binchencoder/letsgo/grpc": "lgr",
+ // "github.com/binchencoder/skylb-api/balancer": "",
+ "github.com/binchencoder/skylb-api/client": "",
+ // "github.com/binchencoder/skylb-api/client/option": "",
+ "github.com/binchencoder/skylb-api/proto": "skypb",
+ "google.golang.org/grpc": "",
+ "google.golang.org/grpc/codes": "",
+ "google.golang.org/grpc/grpclog": "",
+ "google.golang.org/grpc/metadata": "",
+ "google.golang.org/grpc/status": "",
} {
pkg := descriptor.GoPackage{
Path: pkgpath,
@@ -88,30 +77,21 @@ func New(reg *descriptor.Registry, useRequestContext bool, registerFuncSuffix, p
imports = append(imports, pkg)
}
- var pathType pathType
- switch pathTypeString {
- case "", "import":
- // paths=import is default
- case "source_relative":
- pathType = pathTypeSourceRelative
- default:
- glog.Fatalf(`Unknown path type %q: want "import" or "source_relative".`, pathTypeString)
- }
-
return &generator{
reg: reg,
baseImports: imports,
useRequestContext: useRequestContext,
registerFuncSuffix: registerFuncSuffix,
- pathType: pathType,
allowPatchFeature: allowPatchFeature,
+ standalone: standalone,
}
}
-func (g *generator) Generate(targets []*descriptor.File) ([]*plugin.CodeGeneratorResponse_File, error) {
- var files []*plugin.CodeGeneratorResponse_File
+func (g *generator) Generate(targets []*descriptor.File) ([]*descriptor.ResponseFile, error) {
+ var files []*descriptor.ResponseFile
for _, file := range targets {
glog.V(1).Infof("Processing %s", file.GetName())
+
code, err := g.generate(file)
if err == errNoTargetService {
glog.V(1).Infof("%s: %v", file.GetName(), err)
@@ -125,18 +105,13 @@ func (g *generator) Generate(targets []*descriptor.File) ([]*plugin.CodeGenerato
glog.Errorf("%v: %s", err, code)
return nil, err
}
- name := file.GetName()
- if g.pathType == pathTypeImport && file.GoPkg.Path != "" {
- name = fmt.Sprintf("%s/%s", file.GoPkg.Path, filepath.Base(name))
- }
- ext := filepath.Ext(name)
- base := strings.TrimSuffix(name, ext)
- output := fmt.Sprintf("%s.pb.gw.go", base)
- files = append(files, &plugin.CodeGeneratorResponse_File{
- Name: proto.String(output),
- Content: proto.String(string(formatted)),
+ files = append(files, &descriptor.ResponseFile{
+ GoPkg: file.GoPkg,
+ CodeGeneratorResponse_File: &pluginpb.CodeGeneratorResponse_File{
+ Name: proto.String(file.GeneratedFilenamePrefix + ".pb.gw.go"),
+ Content: proto.String(string(formatted)),
+ },
})
- glog.V(1).Infof("Will emit %s", output)
}
return files, nil
}
@@ -148,6 +123,11 @@ func (g *generator) generate(file *descriptor.File) (string, error) {
pkgSeen[pkg.Path] = true
imports = append(imports, pkg)
}
+
+ if g.standalone {
+ imports = append(imports, file.GoPkg)
+ }
+
for _, svc := range file.Services {
for _, m := range svc.Methods {
imports = append(imports, g.addEnumPathParamImports(file, m, pkgSeen)...)
@@ -156,10 +136,6 @@ func (g *generator) generate(file *descriptor.File) (string, error) {
if m.RequestType.HasRule() {
g.populateImportForValidation(m.RequestType, file, &pkgSeen, &imports)
}
- if m.Options == nil || !proto.HasExtension(m.Options, options.E_Http) ||
- pkg == file.GoPkg || pkgSeen[pkg.Path] {
- continue
- }
if len(m.Bindings) == 0 ||
pkg == file.GoPkg || pkgSeen[pkg.Path] {
continue
@@ -175,6 +151,9 @@ func (g *generator) generate(file *descriptor.File) (string, error) {
RegisterFuncSuffix: g.registerFuncSuffix,
AllowPatchFeature: g.allowPatchFeature,
}
+ if g.reg != nil {
+ params.OmitPackageDoc = g.reg.GetOmitPackageDoc()
+ }
return applyTemplate(params, g.reg)
}
diff --git a/gateway/protoc-gen-grpc-gateway/internal/gengateway/generator_test.go b/gateway/protoc-gen-grpc-gateway/internal/gengateway/generator_test.go
new file mode 100644
index 0000000..4ba41e0
--- /dev/null
+++ b/gateway/protoc-gen-grpc-gateway/internal/gengateway/generator_test.go
@@ -0,0 +1,99 @@
+package gengateway
+
+import (
+ "testing"
+
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor"
+ "github.com/binchencoder/janus-gateway/gateway/internal/descriptor"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/types/descriptorpb"
+)
+
+func newExampleFileDescriptorWithGoPkg(gp *descriptor.GoPackage, filenamePrefix string) *descriptor.File {
+ msgdesc := &descriptorpb.DescriptorProto{
+ Name: proto.String("ExampleMessage"),
+ }
+ msg := &descriptor.Message{
+ DescriptorProto: msgdesc,
+ }
+ msg1 := &descriptor.Message{
+ DescriptorProto: msgdesc,
+ File: &descriptor.File{
+ GoPkg: descriptor.GoPackage{
+ Path: "github.com/golang/protobuf/ptypes/empty",
+ Name: "emptypb",
+ },
+ },
+ }
+ meth := &descriptorpb.MethodDescriptorProto{
+ Name: proto.String("Example"),
+ InputType: proto.String("ExampleMessage"),
+ OutputType: proto.String("ExampleMessage"),
+ }
+ meth1 := &descriptorpb.MethodDescriptorProto{
+ Name: proto.String("ExampleWithoutBindings"),
+ InputType: proto.String("empty.Empty"),
+ OutputType: proto.String("empty.Empty"),
+ }
+ svc := &descriptorpb.ServiceDescriptorProto{
+ Name: proto.String("ExampleService"),
+ Method: []*descriptorpb.MethodDescriptorProto{meth, meth1},
+ }
+ return &descriptor.File{
+ FileDescriptorProto: &descriptorpb.FileDescriptorProto{
+ Name: proto.String("example.proto"),
+ Package: proto.String("example"),
+ Dependency: []string{"a.example/b/c.proto", "a.example/d/e.proto"},
+ MessageType: []*descriptorpb.DescriptorProto{msgdesc},
+ Service: []*descriptorpb.ServiceDescriptorProto{svc},
+ },
+ GoPkg: *gp,
+ GeneratedFilenamePrefix: filenamePrefix,
+ Messages: []*descriptor.Message{msg},
+ Services: []*descriptor.Service{
+ {
+ ServiceDescriptorProto: svc,
+ Methods: []*descriptor.Method{
+ {
+ MethodDescriptorProto: meth,
+ RequestType: msg,
+ ResponseType: msg,
+ Bindings: []*descriptor.Binding{
+ {
+ HTTPMethod: "GET",
+ Body: &descriptor.Body{FieldPath: nil},
+ },
+ },
+ },
+ {
+ MethodDescriptorProto: meth1,
+ RequestType: msg1,
+ ResponseType: msg1,
+ },
+ },
+ },
+ },
+ }
+}
+
+func TestGenerator_Generate(t *testing.T) {
+ g := new(generator)
+ g.reg = descriptor.NewRegistry()
+ result, err := g.Generate([]*descriptor.File{
+ crossLinkFixture(newExampleFileDescriptorWithGoPkg(&descriptor.GoPackage{
+ Path: "example.com/path/to/example",
+ Name: "example_pb",
+ }, "path/to/example")),
+ })
+ if err != nil {
+ t.Fatalf("failed to generate stubs: %v", err)
+ }
+ if len(result) != 1 {
+ t.Fatalf("expected to generate one file, got: %d", len(result))
+ }
+ expectedName := "path/to/example.pb.gw.go"
+ gotName := result[0].GetName()
+ if gotName != expectedName {
+ t.Fatalf("invalid name %q, expected %q", gotName, expectedName)
+ }
+}
diff --git a/gateway/protoc-gen-grpc-gateway/gengateway/template.go b/gateway/protoc-gen-grpc-gateway/internal/gengateway/template.go
similarity index 84%
rename from gateway/protoc-gen-grpc-gateway/gengateway/template.go
rename to gateway/protoc-gen-grpc-gateway/internal/gengateway/template.go
index b7b5883..f46ec6b 100644
--- a/gateway/protoc-gen-grpc-gateway/gengateway/template.go
+++ b/gateway/protoc-gen-grpc-gateway/internal/gengateway/template.go
@@ -9,11 +9,11 @@ import (
"unicode"
"github.com/golang/glog"
- generator2 "github.com/golang/protobuf/protoc-gen-go/generator"
-
- // "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
- "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/descriptor"
- "github.com/grpc-ecosystem/grpc-gateway/utilities"
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/internal/casing"
+ "github.com/binchencoder/janus-gateway/gateway/internal/casing"
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor"
+ "github.com/binchencoder/janus-gateway/gateway/internal/descriptor"
+ "github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
)
type param struct {
@@ -22,6 +22,7 @@ type param struct {
UseRequestContext bool
RegisterFuncSuffix string
AllowPatchFeature bool
+ OmitPackageDoc bool
}
type binding struct {
@@ -38,12 +39,12 @@ func (b binding) GetBodyFieldPath() string {
return "*"
}
-// GetBodyFieldPath returns the binding body's struct field name.
+// GetBodyFieldStructName returns the binding body's struct field name.
func (b binding) GetBodyFieldStructName() (string, error) {
if b.Body != nil && len(b.Body.FieldPath) != 0 {
- return generator2.CamelCase(b.Body.FieldPath.String()), nil
+ return casing.Camel(b.Body.FieldPath.String()), nil
}
- return "", errors.New("No body field found")
+ return "", errors.New("no body field found")
}
// badToUnderscore is the mapping function used to generate Go names from
@@ -142,7 +143,7 @@ func (b binding) FieldMaskField() string {
}
}
if fieldMaskField != nil {
- return generator2.CamelCase(fieldMaskField.GetName())
+ return casing.Camel(fieldMaskField.GetName())
}
return ""
}
@@ -165,7 +166,6 @@ type trailerParams struct {
Services []*descriptor.Service
UseRequestContext bool
RegisterFuncSuffix string
- AssumeColonVerb bool
}
func applyTemplate(p param, reg *descriptor.Registry) (string, error) {
@@ -181,18 +181,24 @@ func applyTemplate(p param, reg *descriptor.Registry) (string, error) {
var targetServices []*descriptor.Service
for _, msg := range p.Messages {
- msgName := generator2.CamelCase(*msg.Name)
+ msgName := casing.Camel(*msg.Name)
msg.Name = &msgName
}
+
for _, svc := range p.Services {
var methodWithBindingsSeen bool
- svcName := generator2.CamelCase(*svc.Name)
+ svcName := casing.Camel(*svc.Name)
svc.Name = &svcName
+
for _, meth := range svc.Methods {
glog.V(2).Infof("Processing %s.%s", svc.GetName(), meth.GetName())
- methName := generator2.CamelCase(*meth.Name)
+ methName := casing.Camel(*meth.Name)
meth.Name = &methName
for _, b := range meth.Bindings {
+ if err := reg.CheckDuplicateAnnotation(b.HTTPMethod, b.PathTmpl.Template, svc); err != nil {
+ return "", err
+ }
+
methodWithBindingsSeen = true
if err := handlerTemplate.Execute(w, binding{
Binding: b,
@@ -220,20 +226,15 @@ func applyTemplate(p param, reg *descriptor.Registry) (string, error) {
return "", errNoTargetService
}
- assumeColonVerb := true
- if reg != nil {
- assumeColonVerb = !reg.GetAllowColonFinalSegments()
- }
tp := trailerParams{
Services: targetServices,
UseRequestContext: p.UseRequestContext,
RegisterFuncSuffix: p.RegisterFuncSuffix,
- AssumeColonVerb: assumeColonVerb,
}
// Local
- // if err := localTrailerTemplate.Execute(w, tp); err != nil {
- // return "", err
- // }
+ if err := localTrailerTemplate.Execute(w, tp); err != nil {
+ return "", err
+ }
if err := trailerTemplate.Execute(w, tp); err != nil {
return "", err
@@ -246,11 +247,11 @@ var (
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: {{.GetName}}
-/*
+{{if not .OmitPackageDoc}}/*
Package {{.GoPkg.Name}} is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
-*/
+*/{{end}}
package {{.GoPkg.Name}}
import (
{{range $i := .Imports}}{{if $i.Standard}}{{$i | printf "%s\n"}}{{end}}{{end}}
@@ -264,6 +265,7 @@ var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
+var _ = metadata.Join
// var _ = descriptor.ForMessage
var _ sync.RWMutex
var _ proto.Message
@@ -273,9 +275,9 @@ var _ client.ServiceCli
var _ vexpb.ServiceId
var _ = http.MethodGet
var _ regexp.Regexp
-var _ = balancer.ConsistentHashing
-var _ option.BalancerCreator
-var _ naming.Resolver
+// var _ = balancer.ConsistentHashing
+// var _ option.BalancerCreator
+// var _ naming.Resolver
var _ strings.Reader
var _ = utf8.UTFMax
@@ -450,9 +452,9 @@ var {{.GetUniqueName}}_error = lgr.ToGrpcError(codes.InvalidArgument, &fpb.Error
_ = template.Must(handlerTemplate.New("request-func-signature").Parse(strings.Replace(`
{{if .Method.GetServerStreaming}}
-func request_{{.Method.Service.GetName}}_{{.Method.GetName}}_{{.Index}}(ctx context.Context, marshaler runtime.Marshaler, client {{.Method.Service.GetName}}Client, req *http.Request, pathParams map[string]string) ({{.Method.Service.GetName}}_{{.Method.GetName}}Client, runtime.ServerMetadata, error)
+func request_{{.Method.Service.GetName}}_{{.Method.GetName}}_{{.Index}}(ctx context.Context, marshaler runtime.Marshaler, client {{.Method.Service.InstanceName}}Client, req *http.Request, pathParams map[string]string) ({{.Method.Service.InstanceName}}_{{.Method.GetName}}Client, runtime.ServerMetadata, error)
{{else}}
-func request_{{.Method.Service.GetName}}_{{.Method.GetName}}_{{.Index}}(ctx context.Context, marshaler runtime.Marshaler, client {{.Method.Service.GetName}}Client, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error)
+func request_{{.Method.Service.GetName}}_{{.Method.GetName}}_{{.Index}}(ctx context.Context, marshaler runtime.Marshaler, client {{.Method.Service.InstanceName}}Client, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error)
{{end}}`, "\n", "", -1)))
_ = template.Must(handlerTemplate.New("client-streaming-request-func").Parse(`
@@ -525,8 +527,7 @@ var (
}
{{- if and $AllowPatchFeature (eq (.HTTPMethod) "PATCH") (.FieldMaskField) (not (eq "*" .GetBodyFieldPath)) }}
if protoReq.{{.FieldMaskField}} == nil || len(protoReq.{{.FieldMaskField}}.GetPaths()) == 0 {
- _, md := descriptor.ForMessage(protoReq.{{.GetBodyFieldStructName}})
- if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), md); err != nil {
+ if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), protoReq.{{.GetBodyFieldStructName}}); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
} else {
protoReq.{{.FieldMaskField}} = fieldMask
@@ -557,25 +558,34 @@ var (
}
{{if $param.IsNestedProto3}}
err = runtime.PopulateFieldFromPath(&protoReq, {{$param | printf "%q"}}, val)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", {{$param | printf "%q"}}, err)
+ }
{{if $enum}}
- e{{if $param.IsRepeated}}s{{end}}, err = {{$param.ConvertFuncExpr}}(val{{if $param.IsRepeated}}, {{$binding.Registry.GetRepeatedPathParamSeparator | printf "%c" | printf "%q"}}{{end}}, {{$enum.GoType $param.Target.Message.File.GoPkg.Path}}_value)
+ e{{if $param.IsRepeated}}s{{end}}, err = {{$param.ConvertFuncExpr}}(val{{if $param.IsRepeated}}, {{$binding.Registry.GetRepeatedPathParamSeparator | printf "%c" | printf "%q"}}{{end}}, {{$enum.GoType $param.Method.Service.File.GoPkg.Path}}_value)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "could not parse path as enum value, parameter: %s, error: %v", {{$param | printf "%q"}}, err)
+ }
{{end}}
{{else if $enum}}
- e{{if $param.IsRepeated}}s{{end}}, err = {{$param.ConvertFuncExpr}}(val{{if $param.IsRepeated}}, {{$binding.Registry.GetRepeatedPathParamSeparator | printf "%c" | printf "%q"}}{{end}}, {{$enum.GoType $param.Target.Message.File.GoPkg.Path}}_value)
+ e{{if $param.IsRepeated}}s{{end}}, err = {{$param.ConvertFuncExpr}}(val{{if $param.IsRepeated}}, {{$binding.Registry.GetRepeatedPathParamSeparator | printf "%c" | printf "%q"}}{{end}}, {{$enum.GoType $param.Method.Service.File.GoPkg.Path}}_value)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", {{$param | printf "%q"}}, err)
+ }
{{else}}
{{$param.AssignableExpr "protoReq"}}, err = {{$param.ConvertFuncExpr}}(val{{if $param.IsRepeated}}, {{$binding.Registry.GetRepeatedPathParamSeparator | printf "%c" | printf "%q"}}{{end}})
-{{end}}
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", {{$param | printf "%q"}}, err)
}
+{{end}}
{{if and $enum $param.IsRepeated}}
- s := make([]{{$enum.GoType $param.Target.Message.File.GoPkg.Path}}, len(es))
+ s := make([]{{$enum.GoType $param.Method.Service.File.GoPkg.Path}}, len(es))
for i, v := range es {
- s[i] = {{$enum.GoType $param.Target.Message.File.GoPkg.Path}}(v)
+ s[i] = {{$enum.GoType $param.Method.Service.File.GoPkg.Path}}(v)
}
{{$param.AssignableExpr "protoReq"}} = s
{{else if $enum}}
- {{$param.AssignableExpr "protoReq"}} = {{$enum.GoType $param.Target.Message.File.GoPkg.Path}}(e)
+ {{$param.AssignableExpr "protoReq"}} = {{$enum.GoType $param.Method.Service.File.GoPkg.Path}}(e)
{{end}}
{{end}}
{{end}}
@@ -645,15 +655,6 @@ var (
}
return nil
}
- if err := handleSend(); err != nil {
- if cerr := stream.CloseSend(); cerr != nil {
- grpclog.Infof("Failed to terminate client stream: %v", cerr)
- }
- if err == io.EOF {
- return stream, metadata, nil
- }
- return nil, metadata, err
- }
go func() {
for {
if err := handleSend(); err != nil {
@@ -686,7 +687,7 @@ var (
_ = template.Must(localHandlerTemplate.New("local-request-func-signature").Parse(strings.Replace(`
{{if .Method.GetServerStreaming}}
{{else}}
-func local_request_{{.Method.Service.GetName}}_{{.Method.GetName}}_{{.Index}}(ctx context.Context, marshaler runtime.Marshaler, server {{.Method.Service.GetName}}Server, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error)
+func local_request_{{.Method.Service.GetName}}_{{.Method.GetName}}_{{.Index}}(ctx context.Context, marshaler runtime.Marshaler, server {{.Method.Service.InstanceName}}Server, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error)
{{end}}`, "\n", "", -1)))
_ = template.Must(localHandlerTemplate.New("local-client-rpc-request-func").Parse(`
@@ -704,8 +705,7 @@ func local_request_{{.Method.Service.GetName}}_{{.Method.GetName}}_{{.Index}}(ct
}
{{- if and $AllowPatchFeature (eq (.HTTPMethod) "PATCH") (.FieldMaskField) (not (eq "*" .GetBodyFieldPath)) }}
if protoReq.{{.FieldMaskField}} == nil || len(protoReq.{{.FieldMaskField}}.GetPaths()) == 0 {
- _, md := descriptor.ForMessage(protoReq.{{.GetBodyFieldStructName}})
- if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), md); err != nil {
+ if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), protoReq.{{.GetBodyFieldStructName}}); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
} else {
protoReq.{{.FieldMaskField}} = fieldMask
@@ -735,30 +735,43 @@ func local_request_{{.Method.Service.GetName}}_{{.Method.GetName}}_{{.Index}}(ct
}
{{if $param.IsNestedProto3}}
err = runtime.PopulateFieldFromPath(&protoReq, {{$param | printf "%q"}}, val)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", {{$param | printf "%q"}}, err)
+ }
{{if $enum}}
- e{{if $param.IsRepeated}}s{{end}}, err = {{$param.ConvertFuncExpr}}(val{{if $param.IsRepeated}}, {{$binding.Registry.GetRepeatedPathParamSeparator | printf "%c" | printf "%q"}}{{end}}, {{$enum.GoType $param.Target.Message.File.GoPkg.Path}}_value)
+ e{{if $param.IsRepeated}}s{{end}}, err = {{$param.ConvertFuncExpr}}(val{{if $param.IsRepeated}}, {{$binding.Registry.GetRepeatedPathParamSeparator | printf "%c" | printf "%q"}}{{end}}, {{$enum.GoType $param.Method.Service.File.GoPkg.Path}}_value)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "could not parse path as enum value, parameter: %s, error: %v", {{$param | printf "%q"}}, err)
+ }
{{end}}
{{else if $enum}}
- e{{if $param.IsRepeated}}s{{end}}, err = {{$param.ConvertFuncExpr}}(val{{if $param.IsRepeated}}, {{$binding.Registry.GetRepeatedPathParamSeparator | printf "%c" | printf "%q"}}{{end}}, {{$enum.GoType $param.Target.Message.File.GoPkg.Path}}_value)
+ e{{if $param.IsRepeated}}s{{end}}, err = {{$param.ConvertFuncExpr}}(val{{if $param.IsRepeated}}, {{$binding.Registry.GetRepeatedPathParamSeparator | printf "%c" | printf "%q"}}{{end}}, {{$enum.GoType $param.Method.Service.File.GoPkg.Path}}_value)
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", {{$param | printf "%q"}}, err)
+ }
{{else}}
{{$param.AssignableExpr "protoReq"}}, err = {{$param.ConvertFuncExpr}}(val{{if $param.IsRepeated}}, {{$binding.Registry.GetRepeatedPathParamSeparator | printf "%c" | printf "%q"}}{{end}})
-{{end}}
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", {{$param | printf "%q"}}, err)
}
+{{end}}
+
{{if and $enum $param.IsRepeated}}
- s := make([]{{$enum.GoType $param.Target.Message.File.GoPkg.Path}}, len(es))
+ s := make([]{{$enum.GoType $param.Method.Service.File.GoPkg.Path}}, len(es))
for i, v := range es {
- s[i] = {{$enum.GoType $param.Target.Message.File.GoPkg.Path}}(v)
+ s[i] = {{$enum.GoType $param.Method.Service.File.GoPkg.Path}}(v)
}
{{$param.AssignableExpr "protoReq"}} = s
{{else if $enum}}
- {{$param.AssignableExpr "protoReq"}} = {{$enum.GoType $param.Target.Message.File.GoPkg.Path}}(e)
+ {{$param.AssignableExpr "protoReq"}} = {{$enum.GoType $param.Method.Service.File.GoPkg.Path}}(e)
{{end}}
{{end}}
{{end}}
{{if .HasQueryParam}}
- if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_{{.Method.Service.GetName}}_{{.Method.GetName}}_{{.Index}}); err != nil {
+ if err := req.ParseForm(); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+ if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_{{.Method.Service.GetName}}_{{.Method.GetName}}_{{.Index}}); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
{{end}}
@@ -776,31 +789,40 @@ func local_request_{{.Method.Service.GetName}}_{{.Method.GetName}}_{{.Index}}(ct
// Register{{$svc.GetName}}{{$.RegisterFuncSuffix}}Server registers the http handlers for service {{$svc.GetName}} to "mux".
// UnaryRPC :call {{$svc.GetName}}Server directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
-func Register{{$svc.GetName}}{{$.RegisterFuncSuffix}}Server(ctx context.Context, mux *runtime.ServeMux, server {{$svc.GetName}}Server) error {
+// Note that using this registration option will cause many gRPC library features to stop working. Consider using Register{{$svc.GetName}}{{$.RegisterFuncSuffix}}FromEndpoint instead.
+func Register{{$svc.GetName}}{{$.RegisterFuncSuffix}}Server(ctx context.Context, mux *runtime.ServeMux, server {{$svc.InstanceName}}Server) error {
{{range $m := $svc.Methods}}
{{range $b := $m.Bindings}}
{{if or $m.GetClientStreaming $m.GetServerStreaming}}
- mux.Handle({{$b.HTTPMethod | printf "%q"}}, pattern_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ mux.Handle({{$b.HTTPMethod | printf "%q"}}, pattern_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}, vexpb.ServiceId_{{$svc.ServiceId}}, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
err := status.Error(codes.Unimplemented, "streaming calls are not yet supported in the in-process transport")
_, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
})
{{else}}
- mux.Handle({{$b.HTTPMethod | printf "%q"}}, pattern_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ mux.Handle({{$b.HTTPMethod | printf "%q"}}, pattern_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}, vexpb.ServiceId_{{$svc.ServiceId}}, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
{{- if $UseRequestContext }}
ctx, cancel := context.WithCancel(req.Context())
{{- else -}}
ctx, cancel := context.WithCancel(ctx)
{{- end }}
defer cancel()
+ var stream runtime.ServerTransportStream
+ ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
- rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+ var err error
+ {{- if $b.PathTmpl }}
+ ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/{{$svc.File.GetPackage}}.{{$svc.GetName}}/{{$m.GetName}}", runtime.WithHTTPPathPattern("{{$b.PathTmpl.Template}}"))
+ {{- else -}}
+ ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/{{$svc.File.GetPackage}}.{{$svc.GetName}}/{{$m.GetName}}")
+ {{- end }}
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
- resp, md, err := local_request_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}(rctx, inboundMarshaler, server, req, pathParams)
+ resp, md, err := local_request_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}(ctx, inboundMarshaler, server, req, pathParams)
+ md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -877,15 +899,15 @@ func Register{{$svc.GetName}}{{$.RegisterFuncSuffix}}FromEndpoint(mux *runtime.S
// Register{{$svc.GetName}}{{$.RegisterFuncSuffix}} registers the http handlers for service {{$svc.GetName}} to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func Register{{$svc.GetName}}{{$.RegisterFuncSuffix}}(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
- return Register{{$svc.GetName}}{{$.RegisterFuncSuffix}}Client(ctx, mux, New{{$svc.GetName}}Client(conn))
+ return Register{{$svc.GetName}}{{$.RegisterFuncSuffix}}Client(ctx, mux, {{$svc.ClientConstructorName}}(conn))
}
// Register{{$svc.GetName}}{{$.RegisterFuncSuffix}}Client registers the http handlers for service {{$svc.GetName}}
-// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "{{$svc.GetName}}Client".
-// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "{{$svc.GetName}}Client"
+// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "{{$svc.InstanceName}}Client".
+// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "{{$svc.InstanceName}}Client"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
-// "{{$svc.GetName}}Client" to call the correct interceptors.
-func Register{{$svc.GetName}}{{$.RegisterFuncSuffix}}Client(ctx context.Context, mux *runtime.ServeMux, client {{$svc.GetName}}Client) error {
+// "{{$svc.InstanceName}}Client" to call the correct interceptors.
+func Register{{$svc.GetName}}{{$.RegisterFuncSuffix}}Client(ctx context.Context, mux *runtime.ServeMux, client {{$svc.InstanceName}}Client) error {
spec := internal_{{$svc.GetName}}_{{$svc.ServiceId}}_spec
{{range $m := $svc.Methods}}
@@ -896,15 +918,17 @@ func Register{{$svc.GetName}}{{$.RegisterFuncSuffix}}Client(ctx context.Context,
// internal_{{$svc.ServiceId}}__{{$svc.Namespace}}__{{$svc.PortName}}_lock.RLock()
// defer internal_{{$svc.ServiceId}}__{{$svc.Namespace}}__{{$svc.PortName}}_lock.RUnlock()
client := internal_{{$svc.GetName}}_{{$svc.ServiceId}}_client
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
if client == nil {
- runtime.DefaultOtherErrorHandler(w, req, "service disabled", http.StatusInternalServerError)
+ err := status.Error(codes.Internal, "service disabled")
+ runtime.HTTPError(inctx, mux, outboundMarshaler, w, req, err)
return
}
ctx, err := runtime.RequestAccepted(inctx, internal_{{$svc.GetName}}_{{$svc.ServiceId}}_spec, "{{$svc.GetName}}", "{{$m.GetName}}", w, req)
if err != nil {
- // grpclog.Errorf("runtime.RequestAccepted returns error: %v", err)
- runtime.HTTPError(ctx, nil, &runtime.JSONBuiltin{}, w, req, err)
+ grpclog.Errorf("runtime.RequestAccepted returns error: %v", err)
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
@@ -914,20 +938,32 @@ func Register{{$svc.GetName}}{{$.RegisterFuncSuffix}}Client(ctx context.Context,
ctx, cancel := context.WithCancel(ctx)
{{- end }}
defer cancel()
- inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
- rctx, err := runtime.AnnotateContext(ctx, mux, req)
+ // inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ // var err error
+ {{- if $b.PathTmpl }}
+ ctx, err = runtime.AnnotateContext(ctx, mux, req, "/{{$svc.File.GetPackage}}.{{$svc.GetName}}/{{$m.GetName}}", runtime.WithHTTPPathPattern("{{$b.PathTmpl.Template}}"))
+ {{- else -}}
+ ctx, err = runtime.AnnotateContext(ctx, mux, req, "/{{$svc.File.GetPackage}}.{{$svc.GetName}}/{{$m.GetName}}")
+ {{- end }}
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
- resp, md, err := request_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}(rctx, inboundMarshaler, client, req, pathParams)
+ resp, md, err := request_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}(ctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
{{if $m.GetServerStreaming}}
+ {{ if $b.ResponseBody }}
+ forward_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}(ctx, mux, outboundMarshaler, w, req, func() (proto.Message, error) {
+ res, err := resp.Recv()
+ return response_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}{res}, err
+ }, mux.GetForwardResponseOptions()...)
+ {{ else }}
forward_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}(ctx, mux, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...)
+ {{end}}
{{else}}
{{ if $b.ResponseBody }}
forward_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}(ctx, mux, outboundMarshaler, w, req, response_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}{resp}, mux.GetForwardResponseOptions()...)
@@ -985,13 +1021,9 @@ func Enable_{{$svc.ServiceId}}__{{$svc.Namespace}}__{{$svc.PortName}}_ServiceGro
{{if eq $svc.Balancer.String "ROUND_ROBIN"}}
internal_{{$svc.ServiceId}}__{{$svc.Namespace}}__{{$svc.PortName}}_skycli.Resolve(spec)
{{else if eq $svc.Balancer.String "CONSISTENT"}}
- internal_{{$svc.ServiceId}}__{{$svc.Namespace}}__{{$svc.PortName}}_skycli.Resolve(spec,
- option.WithBalancerCreator(func(r naming.Resolver) grpc.Balancer {
- return balancer.ConsistentHashing(r)
- }),
+ internal_{{$svc.ServiceId}}__{{$svc.Namespace}}__{{$svc.PortName}}_skycli.Resolve(spec),
)
{{end}}
- internal_{{$svc.ServiceId}}__{{$svc.Namespace}}__{{$svc.PortName}}_skycli.EnableResolveFullEps()
internal_{{$svc.ServiceId}}__{{$svc.Namespace}}__{{$svc.PortName}}_skycli.Start(func(spec *skypb.ServiceSpec, conn *grpc.ClientConn) {
sg := runtime.GetServiceGroup(spec)
for _, svc := range sg.Services {
@@ -1012,7 +1044,7 @@ func Disable{{$svc.GetName}}_Service() {
var (
{{range $m := $svc.Methods}}
{{range $b := $m.Bindings}}
- pattern_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}} = runtime.MustPattern(runtime.NewPattern({{$b.PathTmpl.Version}}, {{$b.PathTmpl.OpCodes | printf "%#v"}}, {{$b.PathTmpl.Pool | printf "%#v"}}, {{$b.PathTmpl.Verb | printf "%q"}}, runtime.AssumeColonVerbOpt({{$.AssumeColonVerb}})))
+ pattern_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}} = runtime.MustPattern(runtime.NewPattern({{$b.PathTmpl.Version}}, {{$b.PathTmpl.OpCodes | printf "%#v"}}, {{$b.PathTmpl.Pool | printf "%#v"}}, {{$b.PathTmpl.Verb | printf "%q"}}))
{{end}}
{{end}}
)
diff --git a/gateway/protoc-gen-grpc-gateway/gengateway/template_test.go b/gateway/protoc-gen-grpc-gateway/internal/gengateway/template_test.go
similarity index 64%
rename from gateway/protoc-gen-grpc-gateway/gengateway/template_test.go
rename to gateway/protoc-gen-grpc-gateway/internal/gengateway/template_test.go
index e500b3e..7b414a1 100644
--- a/gateway/protoc-gen-grpc-gateway/gengateway/template_test.go
+++ b/gateway/protoc-gen-grpc-gateway/internal/gengateway/template_test.go
@@ -4,12 +4,11 @@ import (
"strings"
"testing"
- "github.com/golang/protobuf/proto"
- protodescriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
- // "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
- "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/descriptor"
- // "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule"
- "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/httprule"
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor"
+ "github.com/binchencoder/janus-gateway/gateway/internal/descriptor"
+ "github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/types/descriptorpb"
)
func crossLinkFixture(f *descriptor.File) *descriptor.File {
@@ -31,29 +30,37 @@ func crossLinkFixture(f *descriptor.File) *descriptor.File {
return f
}
+func compilePath(t *testing.T, path string) httprule.Template {
+ parsed, err := httprule.Parse(path)
+ if err != nil {
+ t.Fatalf("httprule.Parse(%q) failed with %v; want success", path, err)
+ }
+ return parsed.Compile()
+}
+
func TestApplyTemplateHeader(t *testing.T) {
- msgdesc := &protodescriptor.DescriptorProto{
+ msgdesc := &descriptorpb.DescriptorProto{
Name: proto.String("ExampleMessage"),
}
- meth := &protodescriptor.MethodDescriptorProto{
+ meth := &descriptorpb.MethodDescriptorProto{
Name: proto.String("Example"),
InputType: proto.String("ExampleMessage"),
OutputType: proto.String("ExampleMessage"),
}
- svc := &protodescriptor.ServiceDescriptorProto{
+ svc := &descriptorpb.ServiceDescriptorProto{
Name: proto.String("ExampleService"),
- Method: []*protodescriptor.MethodDescriptorProto{meth},
+ Method: []*descriptorpb.MethodDescriptorProto{meth},
}
msg := &descriptor.Message{
DescriptorProto: msgdesc,
}
file := descriptor.File{
- FileDescriptorProto: &protodescriptor.FileDescriptorProto{
+ FileDescriptorProto: &descriptorpb.FileDescriptorProto{
Name: proto.String("example.proto"),
Package: proto.String("example"),
Dependency: []string{"a.example/b/c.proto", "a.example/d/e.proto"},
- MessageType: []*protodescriptor.DescriptorProto{msgdesc},
- Service: []*protodescriptor.ServiceDescriptorProto{svc},
+ MessageType: []*descriptorpb.DescriptorProto{msgdesc},
+ Service: []*descriptorpb.ServiceDescriptorProto{svc},
},
GoPkg: descriptor.GoPackage{
Path: "example.com/path/to/example/example.pb",
@@ -90,44 +97,44 @@ func TestApplyTemplateHeader(t *testing.T) {
}
func TestApplyTemplateRequestWithoutClientStreaming(t *testing.T) {
- msgdesc := &protodescriptor.DescriptorProto{
+ msgdesc := &descriptorpb.DescriptorProto{
Name: proto.String("ExampleMessage"),
- Field: []*protodescriptor.FieldDescriptorProto{
+ Field: []*descriptorpb.FieldDescriptorProto{
{
Name: proto.String("nested"),
- Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
+ Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
+ Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
TypeName: proto.String("NestedMessage"),
Number: proto.Int32(1),
},
},
}
- nesteddesc := &protodescriptor.DescriptorProto{
+ nesteddesc := &descriptorpb.DescriptorProto{
Name: proto.String("NestedMessage"),
- Field: []*protodescriptor.FieldDescriptorProto{
+ Field: []*descriptorpb.FieldDescriptorProto{
{
Name: proto.String("int32"),
- Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
- Type: protodescriptor.FieldDescriptorProto_TYPE_INT32.Enum(),
+ Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
+ Type: descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
Number: proto.Int32(1),
},
{
Name: proto.String("bool"),
- Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
- Type: protodescriptor.FieldDescriptorProto_TYPE_BOOL.Enum(),
+ Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
+ Type: descriptorpb.FieldDescriptorProto_TYPE_BOOL.Enum(),
Number: proto.Int32(2),
},
},
}
- meth := &protodescriptor.MethodDescriptorProto{
+ meth := &descriptorpb.MethodDescriptorProto{
Name: proto.String("Echo"),
InputType: proto.String("ExampleMessage"),
OutputType: proto.String("ExampleMessage"),
ClientStreaming: proto.Bool(false),
}
- svc := &protodescriptor.ServiceDescriptorProto{
+ svc := &descriptorpb.ServiceDescriptorProto{
Name: proto.String("ExampleService"),
- Method: []*protodescriptor.MethodDescriptorProto{meth},
+ Method: []*descriptorpb.MethodDescriptorProto{meth},
}
for _, spec := range []struct {
serverStreaming bool
@@ -164,11 +171,11 @@ func TestApplyTemplateRequestWithoutClientStreaming(t *testing.T) {
FieldDescriptorProto: nested.GetField()[1],
}
file := descriptor.File{
- FileDescriptorProto: &protodescriptor.FileDescriptorProto{
+ FileDescriptorProto: &descriptorpb.FileDescriptorProto{
Name: proto.String("example.proto"),
Package: proto.String("example"),
- MessageType: []*protodescriptor.DescriptorProto{msgdesc, nesteddesc},
- Service: []*protodescriptor.ServiceDescriptorProto{svc},
+ MessageType: []*descriptorpb.DescriptorProto{msgdesc, nesteddesc},
+ Service: []*descriptorpb.ServiceDescriptorProto{svc},
},
GoPkg: descriptor.GoPackage{
Path: "example.com/path/to/example/example.pb",
@@ -187,8 +194,9 @@ func TestApplyTemplateRequestWithoutClientStreaming(t *testing.T) {
{
HTTPMethod: "POST",
PathTmpl: httprule.Template{
- Version: 1,
- OpCodes: []int{0, 0},
+ Version: 1,
+ OpCodes: []int{0, 0},
+ Template: "/v1",
},
PathParams: []descriptor.Parameter{
{
@@ -244,51 +252,54 @@ func TestApplyTemplateRequestWithoutClientStreaming(t *testing.T) {
if want := `func RegisterExampleServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {`; !strings.Contains(got, want) {
t.Errorf("applyTemplate(%#v) = %s; want to contain %s", file, got, want)
}
- if want := `pattern_ExampleService_Echo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{0, 0}, []string(nil), "", runtime.AssumeColonVerbOpt(true)))`; !strings.Contains(got, want) {
+ if want := `pattern_ExampleService_Echo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{0, 0}, []string(nil), ""))`; !strings.Contains(got, want) {
+ t.Errorf("applyTemplate(%#v) = %s; want to contain %s", file, got, want)
+ }
+ if want := `ctx, err = runtime.AnnotateContext(ctx, mux, req, "/example.ExampleService/Echo", runtime.WithHTTPPathPattern("/v1"))`; !strings.Contains(got, want) {
t.Errorf("applyTemplate(%#v) = %s; want to contain %s", file, got, want)
}
}
}
func TestApplyTemplateRequestWithClientStreaming(t *testing.T) {
- msgdesc := &protodescriptor.DescriptorProto{
+ msgdesc := &descriptorpb.DescriptorProto{
Name: proto.String("ExampleMessage"),
- Field: []*protodescriptor.FieldDescriptorProto{
+ Field: []*descriptorpb.FieldDescriptorProto{
{
Name: proto.String("nested"),
- Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
+ Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
+ Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
TypeName: proto.String("NestedMessage"),
Number: proto.Int32(1),
},
},
}
- nesteddesc := &protodescriptor.DescriptorProto{
+ nesteddesc := &descriptorpb.DescriptorProto{
Name: proto.String("NestedMessage"),
- Field: []*protodescriptor.FieldDescriptorProto{
+ Field: []*descriptorpb.FieldDescriptorProto{
{
Name: proto.String("int32"),
- Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
- Type: protodescriptor.FieldDescriptorProto_TYPE_INT32.Enum(),
+ Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
+ Type: descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
Number: proto.Int32(1),
},
{
Name: proto.String("bool"),
- Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
- Type: protodescriptor.FieldDescriptorProto_TYPE_BOOL.Enum(),
+ Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
+ Type: descriptorpb.FieldDescriptorProto_TYPE_BOOL.Enum(),
Number: proto.Int32(2),
},
},
}
- meth := &protodescriptor.MethodDescriptorProto{
+ meth := &descriptorpb.MethodDescriptorProto{
Name: proto.String("Echo"),
InputType: proto.String("ExampleMessage"),
OutputType: proto.String("ExampleMessage"),
ClientStreaming: proto.Bool(true),
}
- svc := &protodescriptor.ServiceDescriptorProto{
+ svc := &descriptorpb.ServiceDescriptorProto{
Name: proto.String("ExampleService"),
- Method: []*protodescriptor.MethodDescriptorProto{meth},
+ Method: []*descriptorpb.MethodDescriptorProto{meth},
}
for _, spec := range []struct {
serverStreaming bool
@@ -325,11 +336,11 @@ func TestApplyTemplateRequestWithClientStreaming(t *testing.T) {
FieldDescriptorProto: nested.GetField()[1],
}
file := descriptor.File{
- FileDescriptorProto: &protodescriptor.FileDescriptorProto{
+ FileDescriptorProto: &descriptorpb.FileDescriptorProto{
Name: proto.String("example.proto"),
Package: proto.String("example"),
- MessageType: []*protodescriptor.DescriptorProto{msgdesc, nesteddesc},
- Service: []*protodescriptor.ServiceDescriptorProto{svc},
+ MessageType: []*descriptorpb.DescriptorProto{msgdesc, nesteddesc},
+ Service: []*descriptorpb.ServiceDescriptorProto{svc},
},
GoPkg: descriptor.GoPackage{
Path: "example.com/path/to/example/example.pb",
@@ -396,51 +407,51 @@ func TestApplyTemplateRequestWithClientStreaming(t *testing.T) {
if want := `func RegisterExampleServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {`; !strings.Contains(got, want) {
t.Errorf("applyTemplate(%#v) = %s; want to contain %s", file, got, want)
}
- if want := `pattern_ExampleService_Echo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{0, 0}, []string(nil), "", runtime.AssumeColonVerbOpt(true)))`; !strings.Contains(got, want) {
+ if want := `pattern_ExampleService_Echo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{0, 0}, []string(nil), ""))`; !strings.Contains(got, want) {
t.Errorf("applyTemplate(%#v) = %s; want to contain %s", file, got, want)
}
}
}
func TestApplyTemplateInProcess(t *testing.T) {
- msgdesc := &protodescriptor.DescriptorProto{
+ msgdesc := &descriptorpb.DescriptorProto{
Name: proto.String("ExampleMessage"),
- Field: []*protodescriptor.FieldDescriptorProto{
+ Field: []*descriptorpb.FieldDescriptorProto{
{
Name: proto.String("nested"),
- Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
+ Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
+ Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
TypeName: proto.String("NestedMessage"),
Number: proto.Int32(1),
},
},
}
- nesteddesc := &protodescriptor.DescriptorProto{
+ nesteddesc := &descriptorpb.DescriptorProto{
Name: proto.String("NestedMessage"),
- Field: []*protodescriptor.FieldDescriptorProto{
+ Field: []*descriptorpb.FieldDescriptorProto{
{
Name: proto.String("int32"),
- Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
- Type: protodescriptor.FieldDescriptorProto_TYPE_INT32.Enum(),
+ Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
+ Type: descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
Number: proto.Int32(1),
},
{
Name: proto.String("bool"),
- Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
- Type: protodescriptor.FieldDescriptorProto_TYPE_BOOL.Enum(),
+ Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
+ Type: descriptorpb.FieldDescriptorProto_TYPE_BOOL.Enum(),
Number: proto.Int32(2),
},
},
}
- meth := &protodescriptor.MethodDescriptorProto{
+ meth := &descriptorpb.MethodDescriptorProto{
Name: proto.String("Echo"),
InputType: proto.String("ExampleMessage"),
OutputType: proto.String("ExampleMessage"),
ClientStreaming: proto.Bool(true),
}
- svc := &protodescriptor.ServiceDescriptorProto{
+ svc := &descriptorpb.ServiceDescriptorProto{
Name: proto.String("ExampleService"),
- Method: []*protodescriptor.MethodDescriptorProto{meth},
+ Method: []*descriptorpb.MethodDescriptorProto{meth},
}
for _, spec := range []struct {
clientStreaming bool
@@ -452,7 +463,7 @@ func TestApplyTemplateInProcess(t *testing.T) {
serverStreaming: false,
sigWant: []string{
`func local_request_ExampleService_Echo_0(ctx context.Context, marshaler runtime.Marshaler, server ExampleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {`,
- `resp, md, err := local_request_ExampleService_Echo_0(rctx, inboundMarshaler, server, req, pathParams)`,
+ `resp, md, err := local_request_ExampleService_Echo_0(ctx, inboundMarshaler, server, req, pathParams)`,
},
},
{
@@ -500,11 +511,11 @@ func TestApplyTemplateInProcess(t *testing.T) {
FieldDescriptorProto: nested.GetField()[1],
}
file := descriptor.File{
- FileDescriptorProto: &protodescriptor.FileDescriptorProto{
+ FileDescriptorProto: &descriptorpb.FileDescriptorProto{
Name: proto.String("example.proto"),
Package: proto.String("example"),
- MessageType: []*protodescriptor.DescriptorProto{msgdesc, nesteddesc},
- Service: []*protodescriptor.ServiceDescriptorProto{svc},
+ MessageType: []*descriptorpb.DescriptorProto{msgdesc, nesteddesc},
+ Service: []*descriptorpb.ServiceDescriptorProto{svc},
},
GoPkg: descriptor.GoPackage{
Path: "example.com/path/to/example/example.pb",
@@ -579,25 +590,25 @@ func TestApplyTemplateInProcess(t *testing.T) {
}
func TestAllowPatchFeature(t *testing.T) {
- updateMaskDesc := &protodescriptor.FieldDescriptorProto{
+ updateMaskDesc := &descriptorpb.FieldDescriptorProto{
Name: proto.String("UpdateMask"),
- Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
+ Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
+ Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
TypeName: proto.String(".google.protobuf.FieldMask"),
Number: proto.Int32(1),
}
- msgdesc := &protodescriptor.DescriptorProto{
+ msgdesc := &descriptorpb.DescriptorProto{
Name: proto.String("ExampleMessage"),
- Field: []*protodescriptor.FieldDescriptorProto{updateMaskDesc},
+ Field: []*descriptorpb.FieldDescriptorProto{updateMaskDesc},
}
- meth := &protodescriptor.MethodDescriptorProto{
+ meth := &descriptorpb.MethodDescriptorProto{
Name: proto.String("Example"),
InputType: proto.String("ExampleMessage"),
OutputType: proto.String("ExampleMessage"),
}
- svc := &protodescriptor.ServiceDescriptorProto{
+ svc := &descriptorpb.ServiceDescriptorProto{
Name: proto.String("ExampleService"),
- Method: []*protodescriptor.MethodDescriptorProto{meth},
+ Method: []*descriptorpb.MethodDescriptorProto{meth},
}
msg := &descriptor.Message{
DescriptorProto: msgdesc,
@@ -608,11 +619,11 @@ func TestAllowPatchFeature(t *testing.T) {
}
msg.Fields = append(msg.Fields, updateMaskField)
file := descriptor.File{
- FileDescriptorProto: &protodescriptor.FileDescriptorProto{
+ FileDescriptorProto: &descriptorpb.FileDescriptorProto{
Name: proto.String("example.proto"),
Package: proto.String("example"),
- MessageType: []*protodescriptor.DescriptorProto{msgdesc},
- Service: []*protodescriptor.ServiceDescriptorProto{svc},
+ MessageType: []*descriptorpb.DescriptorProto{msgdesc},
+ Service: []*descriptorpb.ServiceDescriptorProto{svc},
},
GoPkg: descriptor.GoPackage{
Path: "example.com/path/to/example/example.pb",
@@ -661,25 +672,25 @@ func TestAllowPatchFeature(t *testing.T) {
}
func TestIdentifierCapitalization(t *testing.T) {
- msgdesc1 := &protodescriptor.DescriptorProto{
+ msgdesc1 := &descriptorpb.DescriptorProto{
Name: proto.String("Exam_pleRequest"),
}
- msgdesc2 := &protodescriptor.DescriptorProto{
+ msgdesc2 := &descriptorpb.DescriptorProto{
Name: proto.String("example_response"),
}
- meth1 := &protodescriptor.MethodDescriptorProto{
+ meth1 := &descriptorpb.MethodDescriptorProto{
Name: proto.String("ExampleGe2t"),
InputType: proto.String("Exam_pleRequest"),
OutputType: proto.String("example_response"),
}
- meth2 := &protodescriptor.MethodDescriptorProto{
- Name: proto.String("Exampl_eGet"),
+ meth2 := &descriptorpb.MethodDescriptorProto{
+ Name: proto.String("Exampl_ePost"),
InputType: proto.String("Exam_pleRequest"),
OutputType: proto.String("example_response"),
}
- svc := &protodescriptor.ServiceDescriptorProto{
+ svc := &descriptorpb.ServiceDescriptorProto{
Name: proto.String("Example"),
- Method: []*protodescriptor.MethodDescriptorProto{meth1, meth2},
+ Method: []*descriptorpb.MethodDescriptorProto{meth1, meth2},
}
msg1 := &descriptor.Message{
DescriptorProto: msgdesc1,
@@ -688,12 +699,12 @@ func TestIdentifierCapitalization(t *testing.T) {
DescriptorProto: msgdesc2,
}
file := descriptor.File{
- FileDescriptorProto: &protodescriptor.FileDescriptorProto{
+ FileDescriptorProto: &descriptorpb.FileDescriptorProto{
Name: proto.String("example.proto"),
Package: proto.String("example"),
Dependency: []string{"a.example/b/c.proto", "a.example/d/e.proto"},
- MessageType: []*protodescriptor.DescriptorProto{msgdesc1, msgdesc2},
- Service: []*protodescriptor.ServiceDescriptorProto{svc},
+ MessageType: []*descriptorpb.DescriptorProto{msgdesc1, msgdesc2},
+ Service: []*descriptorpb.ServiceDescriptorProto{svc},
},
GoPkg: descriptor.GoPackage{
Path: "example.com/path/to/example/example.pb",
@@ -726,7 +737,7 @@ func TestIdentifierCapitalization(t *testing.T) {
ResponseType: msg2,
Bindings: []*descriptor.Binding{
{
- HTTPMethod: "GET",
+ HTTPMethod: "POST",
Body: &descriptor.Body{FieldPath: nil},
},
},
@@ -744,7 +755,7 @@ func TestIdentifierCapitalization(t *testing.T) {
if want := `msg, err := client.ExampleGe2T(ctx, &protoReq, grpc.Header(&metadata.HeaderMD)`; !strings.Contains(got, want) {
t.Errorf("applyTemplate(%#v) = %s; want to contain %s", file, got, want)
}
- if want := `msg, err := client.ExamplEGet(ctx, &protoReq, grpc.Header(&metadata.HeaderMD)`; !strings.Contains(got, want) {
+ if want := `msg, err := client.ExamplEPost(ctx, &protoReq, grpc.Header(&metadata.HeaderMD)`; !strings.Contains(got, want) {
t.Errorf("applyTemplate(%#v) = %s; want to contain %s", file, got, want)
}
if want := `var protoReq ExamPleRequest`; !strings.Contains(got, want) {
@@ -754,3 +765,164 @@ func TestIdentifierCapitalization(t *testing.T) {
t.Errorf("applyTemplate(%#v) = %s; want to contain %s", file, got, want)
}
}
+
+func TestDuplicatePathsInSameService(t *testing.T) {
+ msgdesc := &descriptorpb.DescriptorProto{
+ Name: proto.String("ExampleMessage"),
+ Field: []*descriptorpb.FieldDescriptorProto{
+ {
+ Name: proto.String("nested"),
+ Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
+ Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
+ TypeName: proto.String(".google.protobuf.StringValue"),
+ Number: proto.Int32(1),
+ },
+ },
+ }
+ meth1 := &descriptorpb.MethodDescriptorProto{
+ Name: proto.String("Echo"),
+ InputType: proto.String("ExampleMessage"),
+ OutputType: proto.String("ExampleMessage"),
+ }
+ meth2 := &descriptorpb.MethodDescriptorProto{
+ Name: proto.String("Echo2"),
+ InputType: proto.String("ExampleMessage"),
+ OutputType: proto.String("ExampleMessage"),
+ }
+ svc := &descriptorpb.ServiceDescriptorProto{
+ Name: proto.String("ExampleService"),
+ Method: []*descriptorpb.MethodDescriptorProto{meth1, meth2},
+ }
+ msg := &descriptor.Message{
+ DescriptorProto: msgdesc,
+ }
+ binding := &descriptor.Binding{
+ Index: 1,
+ PathTmpl: compilePath(t, "/v1/example/echo"),
+ HTTPMethod: "GET",
+ PathParams: nil,
+ Body: nil,
+ }
+ file := descriptor.File{
+ FileDescriptorProto: &descriptorpb.FileDescriptorProto{
+ Name: proto.String("example.proto"),
+ Package: proto.String("example"),
+ MessageType: []*descriptorpb.DescriptorProto{msgdesc},
+ Service: []*descriptorpb.ServiceDescriptorProto{svc},
+ },
+ GoPkg: descriptor.GoPackage{
+ Path: "example.com/path/to/example/example.pb",
+ Name: "example_pb",
+ },
+ Messages: []*descriptor.Message{msg},
+ Services: []*descriptor.Service{
+ {
+ ServiceDescriptorProto: svc,
+ Methods: []*descriptor.Method{
+ {
+ MethodDescriptorProto: meth1,
+ RequestType: msg,
+ ResponseType: msg,
+ Bindings: []*descriptor.Binding{binding},
+ },
+ {
+ MethodDescriptorProto: meth2,
+ RequestType: msg,
+ ResponseType: msg,
+ Bindings: []*descriptor.Binding{binding},
+ },
+ },
+ },
+ },
+ }
+ _, err := applyTemplate(param{File: crossLinkFixture(&file), RegisterFuncSuffix: "Handler", AllowPatchFeature: true}, descriptor.NewRegistry())
+ if err == nil {
+ t.Errorf("applyTemplate(%#v) succeeded; want an error", file)
+ return
+ }
+}
+
+func TestDuplicatePathsInDifferentService(t *testing.T) {
+ msgdesc := &descriptorpb.DescriptorProto{
+ Name: proto.String("ExampleMessage"),
+ Field: []*descriptorpb.FieldDescriptorProto{
+ {
+ Name: proto.String("nested"),
+ Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
+ Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
+ TypeName: proto.String(".google.protobuf.StringValue"),
+ Number: proto.Int32(1),
+ },
+ },
+ }
+ meth1 := &descriptorpb.MethodDescriptorProto{
+ Name: proto.String("Echo"),
+ InputType: proto.String("ExampleMessage"),
+ OutputType: proto.String("ExampleMessage"),
+ }
+ meth2 := &descriptorpb.MethodDescriptorProto{
+ Name: proto.String("Echo2"),
+ InputType: proto.String("ExampleMessage"),
+ OutputType: proto.String("ExampleMessage"),
+ }
+ svc1 := &descriptorpb.ServiceDescriptorProto{
+ Name: proto.String("ExampleServiceNumberOne"),
+ Method: []*descriptorpb.MethodDescriptorProto{meth1, meth2},
+ }
+ svc2 := &descriptorpb.ServiceDescriptorProto{
+ Name: proto.String("ExampleServiceNumberTwo"),
+ Method: []*descriptorpb.MethodDescriptorProto{meth1, meth2},
+ }
+ msg := &descriptor.Message{
+ DescriptorProto: msgdesc,
+ }
+ binding := &descriptor.Binding{
+ Index: 1,
+ PathTmpl: compilePath(t, "/v1/example/echo"),
+ HTTPMethod: "GET",
+ PathParams: nil,
+ Body: nil,
+ }
+ file := descriptor.File{
+ FileDescriptorProto: &descriptorpb.FileDescriptorProto{
+ Name: proto.String("example.proto"),
+ Package: proto.String("example"),
+ MessageType: []*descriptorpb.DescriptorProto{msgdesc},
+ Service: []*descriptorpb.ServiceDescriptorProto{svc1, svc2},
+ },
+ GoPkg: descriptor.GoPackage{
+ Path: "example.com/path/to/example/example.pb",
+ Name: "example_pb",
+ },
+ Messages: []*descriptor.Message{msg},
+ Services: []*descriptor.Service{
+ {
+ ServiceDescriptorProto: svc1,
+ Methods: []*descriptor.Method{
+ {
+ MethodDescriptorProto: meth1,
+ RequestType: msg,
+ ResponseType: msg,
+ Bindings: []*descriptor.Binding{binding},
+ },
+ },
+ },
+ {
+ ServiceDescriptorProto: svc2,
+ Methods: []*descriptor.Method{
+ {
+ MethodDescriptorProto: meth2,
+ RequestType: msg,
+ ResponseType: msg,
+ Bindings: []*descriptor.Binding{binding},
+ },
+ },
+ },
+ },
+ }
+ _, err := applyTemplate(param{File: crossLinkFixture(&file), RegisterFuncSuffix: "Handler", AllowPatchFeature: true}, descriptor.NewRegistry())
+ if err != nil {
+ t.Errorf("applyTemplate(%#v) failed; want success", file)
+ return
+ }
+}
diff --git a/gateway/protoc-gen-grpc-gateway/main.go b/gateway/protoc-gen-grpc-gateway/main.go
index 2ff25a2..ff91461 100644
--- a/gateway/protoc-gen-grpc-gateway/main.go
+++ b/gateway/protoc-gen-grpc-gateway/main.go
@@ -15,32 +15,28 @@ import (
"strings"
"github.com/golang/glog"
- "github.com/golang/protobuf/proto"
- plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
+ "github.com/grpc-ecosystem/grpc-gateway/v2/internal/codegenerator"
- // "github.com/grpc-ecosystem/grpc-gateway/codegenerator"
- "github.com/binchencoder/ease-gateway/gateway/codegenerator"
-
- // "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
- "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/descriptor"
-
- // "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/gengateway"
- "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/gengateway"
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor"
+ "github.com/binchencoder/janus-gateway/gateway/internal/descriptor"
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway/internal/gengateway"
+ "github.com/binchencoder/janus-gateway/gateway/protoc-gen-grpc-gateway/internal/gengateway"
+ "google.golang.org/protobuf/compiler/protogen"
)
var (
- importPrefix = flag.String("import_prefix", "", "prefix to be added to go package paths for imported proto files")
- importPath = flag.String("import_path", "", "used as the package if no input files declare go_package. If it contains slashes, everything up to the rightmost slash is ignored.")
registerFuncSuffix = flag.String("register_func_suffix", "Handler", "used to construct names of generated Register* methods.")
useRequestContext = flag.Bool("request_context", true, "determine whether to use http.Request's context or not")
allowDeleteBody = flag.Bool("allow_delete_body", false, "unless set, HTTP DELETE methods may not have a body")
grpcAPIConfiguration = flag.String("grpc_api_configuration", "", "path to gRPC API Configuration in YAML format")
- pathType = flag.String("paths", "", "specifies how the paths of generated files are structured")
allowRepeatedFieldsInBody = flag.Bool("allow_repeated_fields_in_body", false, "allows to use repeated field in `body` and `response_body` field of `google.api.http` annotation option")
repeatedPathParamSeparator = flag.String("repeated_path_param_separator", "csv", "configures how repeated fields should be split. Allowed values are `csv`, `pipes`, `ssv` and `tsv`.")
allowPatchFeature = flag.Bool("allow_patch_feature", true, "determines whether to use PATCH feature involving update masks (using google.protobuf.FieldMask).")
- allowColonFinalSegments = flag.Bool("allow_colon_final_segments", false, "determines whether colons are permitted in the final segment of a path")
- versionFlag = flag.Bool("version", false, "print the current verison")
+ omitPackageDoc = flag.Bool("omit_package_doc", false, "if true, no package comment will be included in the generated code")
+ standalone = flag.Bool("standalone", false, "generates a standalone gateway package, which imports the target service package")
+ versionFlag = flag.Bool("version", false, "print the current version")
+ warnOnUnboundMethods = flag.Bool("warn_on_unbound_methods", false, "emit a warning message if an RPC method has no HttpRule annotation")
+ generateUnboundMethods = flag.Bool("generate_unbound_methods", false, "generate proxy methods even for RPC methods that have no HttpRule annotation")
)
// Variables set by goreleaser at build time
@@ -59,90 +55,96 @@ func main() {
os.Exit(0)
}
- reg := descriptor.NewRegistry()
- descriptor.Reg = reg
+ protogen.Options{
+ ParamFunc: flag.CommandLine.Set,
+ }.Run(func(gen *protogen.Plugin) error {
+ reg := descriptor.NewRegistry()
+ descriptor.Reg = reg
- glog.V(1).Info("Parsing code generator request")
- req, err := codegenerator.ParseRequest(os.Stdin)
- if err != nil {
- glog.Fatal(err)
- }
- glog.V(1).Info("Parsed code generator request")
- if req.Parameter != nil {
- for _, p := range strings.Split(req.GetParameter(), ",") {
- spec := strings.SplitN(p, "=", 2)
- if len(spec) == 1 {
- if err := flag.CommandLine.Set(spec[0], ""); err != nil {
- glog.Fatalf("Cannot set flag %s", p)
- }
- continue
- }
- name, value := spec[0], spec[1]
- if strings.HasPrefix(name, "M") {
- reg.AddPkgMap(name[1:], value)
- continue
- }
- if err := flag.CommandLine.Set(name, value); err != nil {
- glog.Fatalf("Cannot set flag %s", p)
- }
+ err := applyFlags(reg)
+ if err != nil {
+ return err
}
- }
- g := gengateway.New(reg, *useRequestContext, *registerFuncSuffix, *pathType, *allowPatchFeature)
+ codegenerator.SetSupportedFeaturesOnPluginGen(gen)
- if *grpcAPIConfiguration != "" {
- if err := reg.LoadGrpcAPIServiceFromYAML(*grpcAPIConfiguration); err != nil {
- emitError(err)
- return
+ generator := gengateway.New(reg, *useRequestContext, *registerFuncSuffix, *allowPatchFeature, *standalone)
+
+ glog.V(1).Infof("Parsing code generator request")
+
+ if err := reg.LoadFromPlugin(gen); err != nil {
+ return err
}
- }
- reg.SetPrefix(*importPrefix)
- reg.SetImportPath(*importPath)
- reg.SetAllowDeleteBody(*allowDeleteBody)
- reg.SetAllowRepeatedFieldsInBody(*allowRepeatedFieldsInBody)
- reg.SetAllowColonFinalSegments(*allowColonFinalSegments)
- if err := reg.SetRepeatedPathParamSeparator(*repeatedPathParamSeparator); err != nil {
- emitError(err)
- return
- }
- if err := reg.Load(req); err != nil {
- emitError(err)
- return
- }
+ unboundHTTPRules := reg.UnboundExternalHTTPRules()
+ if len(unboundHTTPRules) != 0 {
+ return fmt.Errorf("HTTP rules without a matching selector: %s", strings.Join(unboundHTTPRules, ", "))
+ }
- var targets []*descriptor.File
- for _, target := range req.FileToGenerate {
- f, err := reg.LookupFile(target)
- if err != nil {
- glog.Fatal(err)
+ var targets []*descriptor.File
+ for _, target := range gen.Request.FileToGenerate {
+ f, err := reg.LookupFile(target)
+ if err != nil {
+ return err
+ }
+ targets = append(targets, f)
}
- targets = append(targets, f)
- }
- out, err := g.Generate(targets)
- glog.V(1).Info("Processed code generator request")
- if err != nil {
- emitError(err)
+ files, err := generator.Generate(targets)
+ for _, f := range files {
+ glog.V(1).Infof("NewGeneratedFile %q in %s", f.GetName(), f.GoPkg)
+ genFile := gen.NewGeneratedFile(f.GetName(), protogen.GoImportPath(f.GoPkg.Path))
+ if _, err := genFile.Write([]byte(f.GetContent())); err != nil {
+ return err
+ }
+ }
+
+ glog.V(1).Info("Processed code generator request")
+
+ return err
+ })
+}
+
+func parseFlags(reg *descriptor.Registry, parameter string) {
+ if parameter == "" {
return
}
- emitFiles(out)
-}
-func emitFiles(out []*plugin.CodeGeneratorResponse_File) {
- emitResp(&plugin.CodeGeneratorResponse{File: out})
-}
+ for _, p := range strings.Split(parameter, ",") {
+ spec := strings.SplitN(p, "=", 2)
+ if len(spec) == 1 {
+ if err := flag.CommandLine.Set(spec[0], ""); err != nil {
+ glog.Fatalf("Cannot set flag %s", p)
+ }
+ continue
+ }
+
+ name, value := spec[0], spec[1]
-func emitError(err error) {
- emitResp(&plugin.CodeGeneratorResponse{Error: proto.String(err.Error())})
+ if strings.HasPrefix(name, "M") {
+ reg.AddPkgMap(name[1:], value)
+ continue
+ }
+ if err := flag.CommandLine.Set(name, value); err != nil {
+ glog.Fatalf("Cannot set flag %s", p)
+ }
+ }
}
-func emitResp(resp *plugin.CodeGeneratorResponse) {
- buf, err := proto.Marshal(resp)
- if err != nil {
- glog.Fatal(err)
+func applyFlags(reg *descriptor.Registry) error {
+ if *grpcAPIConfiguration != "" {
+ if err := reg.LoadGrpcAPIServiceFromYAML(*grpcAPIConfiguration); err != nil {
+ return err
+ }
}
- if _, err := os.Stdout.Write(buf); err != nil {
- glog.Fatal(err)
+ if *warnOnUnboundMethods && *generateUnboundMethods {
+ glog.Warningf("Option warn_on_unbound_methods has no effect when generate_unbound_methods is used.")
}
+ reg.SetStandalone(*standalone)
+ reg.SetAllowDeleteBody(*allowDeleteBody)
+ reg.SetAllowRepeatedFieldsInBody(*allowRepeatedFieldsInBody)
+ reg.SetOmitPackageDoc(*omitPackageDoc)
+ reg.SetWarnOnUnboundMethods(*warnOnUnboundMethods)
+ reg.SetGenerateUnboundMethods(*generateUnboundMethods)
+ return reg.SetRepeatedPathParamSeparator(*repeatedPathParamSeparator)
}
diff --git a/gateway/protoc-gen-grpc-gateway/main_test.go b/gateway/protoc-gen-grpc-gateway/main_test.go
new file mode 100644
index 0000000..78068b3
--- /dev/null
+++ b/gateway/protoc-gen-grpc-gateway/main_test.go
@@ -0,0 +1,32 @@
+package main
+
+import (
+ "testing"
+
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor"
+ "github.com/binchencoder/janus-gateway/gateway/internal/descriptor"
+)
+
+func TestParseFlagsEmptyNoPanic(t *testing.T) {
+ reg := descriptor.NewRegistry()
+ parseFlags(reg, "")
+}
+
+func TestParseFlags(t *testing.T) {
+ reg := descriptor.NewRegistry()
+ parseFlags(reg, "allow_repeated_fields_in_body=true")
+ if *allowRepeatedFieldsInBody != true {
+ t.Errorf("flag allow_repeated_fields_in_body was not set correctly, wanted true got %v", *allowRepeatedFieldsInBody)
+ }
+}
+
+func TestParseFlagsMultiple(t *testing.T) {
+ reg := descriptor.NewRegistry()
+ parseFlags(reg, "allow_repeated_fields_in_body=true,repeated_path_param_separator=csv")
+ if *allowRepeatedFieldsInBody != true {
+ t.Errorf("flag allow_repeated_fields_in_body was not set correctly, wanted 'true' got '%v'", *allowRepeatedFieldsInBody)
+ }
+ if *repeatedPathParamSeparator != "csv" {
+ t.Errorf("flag importPrefix was not set correctly, wanted 'csv' got '%v'", *repeatedPathParamSeparator)
+ }
+}
diff --git a/gateway/protoc-gen-openapiv2/BUILD.bazel b/gateway/protoc-gen-openapiv2/BUILD.bazel
new file mode 100644
index 0000000..948ef3e
--- /dev/null
+++ b/gateway/protoc-gen-openapiv2/BUILD.bazel
@@ -0,0 +1,31 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test")
+
+package(default_visibility = ["//visibility:private"])
+
+go_library(
+ name = "protoc-gen-openapiv2_lib",
+ srcs = ["main.go"],
+ importpath = "github.com/binchencoder/janus-gateway/gateway/protoc-gen-openapiv2",
+ deps = [
+ "@com_github_grpc_ecosystem_grpc_gateway//internal/codegenerator",
+ "//gateway/internal/descriptor",
+ "//gateway/protoc-gen-openapiv2/internal/genopenapi",
+ "@com_github_grpc_ecosystem_grpc_gateway//utilities",
+ "@com_github_golang_glog//:glog",
+ "@org_golang_google_protobuf//proto",
+ "@org_golang_google_protobuf//types/pluginpb",
+ ],
+)
+
+go_binary(
+ name = "protoc-gen-openapiv2",
+ embed = [":protoc-gen-openapiv2_lib"],
+ visibility = ["//visibility:public"],
+)
+
+go_test(
+ name = "protoc-gen-openapiv2_test",
+ size = "small",
+ srcs = ["main_test.go"],
+ embed = [":protoc-gen-openapiv2_lib"],
+)
diff --git a/gateway/protoc-gen-openapiv2/defs.bzl b/gateway/protoc-gen-openapiv2/defs.bzl
new file mode 100644
index 0000000..1dbdfc4
--- /dev/null
+++ b/gateway/protoc-gen-openapiv2/defs.bzl
@@ -0,0 +1,365 @@
+"""Generated an open-api spec for a grpc api spec.
+
+Reads the the api spec in protobuf format and generate an open-api spec.
+Optionally applies settings from the grpc-service configuration.
+"""
+
+load("@rules_proto//proto:defs.bzl", "ProtoInfo")
+
+# TODO(yannic): Replace with |proto_common.direct_source_infos| when
+# https://github.com/bazelbuild/rules_proto/pull/22 lands.
+def _direct_source_infos(proto_info, provided_sources = []):
+ """Returns sequence of `ProtoFileInfo` for `proto_info`'s direct sources.
+
+ Files that are both in `proto_info`'s direct sources and in
+ `provided_sources` are skipped. This is useful, e.g., for well-known
+ protos that are already provided by the Protobuf runtime.
+
+ Args:
+ proto_info: An instance of `ProtoInfo`.
+ provided_sources: Optional. A sequence of files to ignore.
+ Usually, these files are already provided by the
+ Protocol Buffer runtime (e.g. Well-Known protos).
+
+ Returns: A sequence of `ProtoFileInfo` containing information about
+ `proto_info`'s direct sources.
+ """
+
+ source_root = proto_info.proto_source_root
+ if "." == source_root:
+ return [struct(file = src, import_path = src.path) for src in proto_info.check_deps_sources.to_list()]
+
+ offset = len(source_root) + 1 # + '/'.
+
+ infos = []
+ for src in proto_info.check_deps_sources.to_list():
+ # TODO(yannic): Remove this hack when we drop support for Bazel < 1.0.
+ local_offset = offset
+ if src.root.path and not source_root.startswith(src.root.path):
+ # Before Bazel 1.0, `proto_source_root` wasn't guaranteed to be a
+ # prefix of `src.path`. This could happend, e.g., if `file` was
+ # generated (https://github.com/bazelbuild/bazel/issues/9215).
+ local_offset += len(src.root.path) + 1 # + '/'.
+ infos.append(struct(file = src, import_path = src.path[local_offset:]))
+
+ return infos
+
+def _run_proto_gen_openapi(
+ actions,
+ proto_info,
+ target_name,
+ transitive_proto_srcs,
+ protoc,
+ protoc_gen_openapiv2,
+ single_output,
+ allow_delete_body,
+ grpc_api_configuration,
+ json_names_for_fields,
+ repeated_path_param_separator,
+ include_package_in_tags,
+ fqn_for_openapi_name,
+ openapi_naming_strategy,
+ use_go_templates,
+ disable_default_errors,
+ enums_as_ints,
+ omit_enum_default_value,
+ output_format,
+ simple_operation_ids,
+ proto3_optional_nullable,
+ openapi_configuration,
+ generate_unbound_methods,
+ visibility_restriction_selectors):
+ args = actions.args()
+
+ args.add("--plugin", "protoc-gen-openapiv2=%s" % protoc_gen_openapiv2.path)
+
+ args.add("--openapiv2_opt", "logtostderr=true")
+ args.add("--openapiv2_opt", "allow_repeated_fields_in_body=true")
+
+ extra_inputs = []
+ if grpc_api_configuration:
+ extra_inputs.append(grpc_api_configuration)
+ args.add("--openapiv2_opt", "grpc_api_configuration=%s" % grpc_api_configuration.path)
+
+ if openapi_configuration:
+ extra_inputs.append(openapi_configuration)
+ args.add("--openapiv2_opt", "openapi_configuration=%s" % openapi_configuration.path)
+
+ if not json_names_for_fields:
+ args.add("--openapiv2_opt", "json_names_for_fields=false")
+
+ if fqn_for_openapi_name:
+ args.add("--openapiv2_opt", "fqn_for_openapi_name=true")
+
+ if openapi_naming_strategy:
+ args.add("--openapiv2_opt", "openapi_naming_strategy=%s" % openapi_naming_strategy)
+
+ if generate_unbound_methods:
+ args.add("--openapiv2_opt", "generate_unbound_methods=true")
+
+ if simple_operation_ids:
+ args.add("--openapiv2_opt", "simple_operation_ids=true")
+
+ if allow_delete_body:
+ args.add("--openapiv2_opt", "allow_delete_body=true")
+
+ if include_package_in_tags:
+ args.add("--openapiv2_opt", "include_package_in_tags=true")
+
+ if use_go_templates:
+ args.add("--openapiv2_opt", "use_go_templates=true")
+
+ if disable_default_errors:
+ args.add("--openapiv2_opt", "disable_default_errors=true")
+
+ if enums_as_ints:
+ args.add("--openapiv2_opt", "enums_as_ints=true")
+
+ if omit_enum_default_value:
+ args.add("--openapiv2_opt", "omit_enum_default_value=true")
+
+ if output_format:
+ args.add("--openapiv2_opt", "output_format=%s" % output_format)
+
+ if proto3_optional_nullable:
+ args.add("--openapiv2_opt", "proto3_optional_nullable=true")
+
+ for visibility_restriction_selector in visibility_restriction_selectors:
+ args.add("--openapiv2_opt", "visibility_restriction_selectors=%s" % visibility_restriction_selector)
+
+ args.add("--openapiv2_opt", "repeated_path_param_separator=%s" % repeated_path_param_separator)
+
+ proto_file_infos = _direct_source_infos(proto_info)
+
+ # TODO(yannic): Use |proto_info.transitive_descriptor_sets| when
+ # https://github.com/bazelbuild/bazel/issues/9337 is fixed.
+ args.add_all(proto_info.transitive_proto_path, format_each = "--proto_path=%s")
+
+ if single_output:
+ args.add("--openapiv2_opt", "allow_merge=true")
+ args.add("--openapiv2_opt", "merge_file_name=%s" % target_name)
+
+ openapi_file = actions.declare_file("%s.swagger.json" % target_name)
+ args.add("--openapiv2_out", openapi_file.dirname)
+
+ args.add_all([f.import_path for f in proto_file_infos])
+
+ actions.run(
+ executable = protoc,
+ tools = [protoc_gen_openapiv2],
+ inputs = depset(
+ direct = extra_inputs,
+ transitive = [transitive_proto_srcs],
+ ),
+ outputs = [openapi_file],
+ arguments = [args],
+ )
+
+ return [openapi_file]
+
+ # TODO(yannic): We may be able to generate all files in a single action,
+ # but that will change at least the semantics of `use_go_template.proto`.
+ openapi_files = []
+ for proto_file_info in proto_file_infos:
+ # TODO(yannic): This probably doesn't work as expected: we only add this
+ # option after we have seen it, so `.proto` sources that happen to be
+ # in the list of `.proto` files before `use_go_template.proto` will be
+ # compiled without this option, and all sources that get compiled after
+ # `use_go_template.proto` will have this option on.
+ if proto_file_info.file.basename == "use_go_template.proto":
+ args.add("--openapiv2_opt", "use_go_templates=true")
+
+ file_name = "%s.swagger.json" % proto_file_info.import_path[:-len(".proto")]
+ openapi_file = actions.declare_file(
+ "_virtual_imports/%s/%s" % (target_name, file_name),
+ )
+
+ file_args = actions.args()
+
+ offset = len(file_name) + 1 # + '/'.
+ file_args.add("--openapiv2_out", openapi_file.path[:-offset])
+
+ file_args.add(proto_file_info.import_path)
+
+ actions.run(
+ executable = protoc,
+ tools = [protoc_gen_openapiv2],
+ inputs = depset(
+ direct = extra_inputs,
+ transitive = [transitive_proto_srcs],
+ ),
+ outputs = [openapi_file],
+ arguments = [args, file_args],
+ )
+ openapi_files.append(openapi_file)
+
+ return openapi_files
+
+def _proto_gen_openapi_impl(ctx):
+ proto = ctx.attr.proto[ProtoInfo]
+ return [
+ DefaultInfo(
+ files = depset(
+ _run_proto_gen_openapi(
+ actions = ctx.actions,
+ proto_info = proto,
+ target_name = ctx.attr.name,
+ transitive_proto_srcs = depset(
+ direct = ctx.files._well_known_protos,
+ transitive = [proto.transitive_sources],
+ ),
+ protoc = ctx.executable._protoc,
+ protoc_gen_openapiv2 = ctx.executable._protoc_gen_openapi,
+ single_output = ctx.attr.single_output,
+ allow_delete_body = ctx.attr.allow_delete_body,
+ grpc_api_configuration = ctx.file.grpc_api_configuration,
+ json_names_for_fields = ctx.attr.json_names_for_fields,
+ repeated_path_param_separator = ctx.attr.repeated_path_param_separator,
+ include_package_in_tags = ctx.attr.include_package_in_tags,
+ fqn_for_openapi_name = ctx.attr.fqn_for_openapi_name,
+ openapi_naming_strategy = ctx.attr.openapi_naming_strategy,
+ use_go_templates = ctx.attr.use_go_templates,
+ disable_default_errors = ctx.attr.disable_default_errors,
+ enums_as_ints = ctx.attr.enums_as_ints,
+ omit_enum_default_value = ctx.attr.omit_enum_default_value,
+ output_format = ctx.attr.output_format,
+ simple_operation_ids = ctx.attr.simple_operation_ids,
+ proto3_optional_nullable = ctx.attr.proto3_optional_nullable,
+ openapi_configuration = ctx.file.openapi_configuration,
+ generate_unbound_methods = ctx.attr.generate_unbound_methods,
+ visibility_restriction_selectors = ctx.attr.visibility_restriction_selectors,
+ ),
+ ),
+ ),
+ ]
+
+protoc_gen_openapiv2 = rule(
+ attrs = {
+ "proto": attr.label(
+ mandatory = True,
+ providers = [ProtoInfo],
+ ),
+ "single_output": attr.bool(
+ default = False,
+ mandatory = False,
+ doc = "if set, the rule will generate a single OpenAPI file",
+ ),
+ "allow_delete_body": attr.bool(
+ default = False,
+ mandatory = False,
+ doc = "unless set, HTTP DELETE methods may not have a body",
+ ),
+ "grpc_api_configuration": attr.label(
+ allow_single_file = True,
+ mandatory = False,
+ doc = "path to file which describes the gRPC API Configuration in YAML format",
+ ),
+ "json_names_for_fields": attr.bool(
+ default = True,
+ mandatory = False,
+ doc = "if disabled, the original proto name will be used for generating OpenAPI definitions",
+ ),
+ "repeated_path_param_separator": attr.string(
+ default = "csv",
+ mandatory = False,
+ values = ["csv", "pipes", "ssv", "tsv"],
+ doc = "configures how repeated fields should be split." +
+ " Allowed values are `csv`, `pipes`, `ssv` and `tsv`",
+ ),
+ "include_package_in_tags": attr.bool(
+ default = False,
+ mandatory = False,
+ doc = "if unset, the gRPC service name is added to the `Tags`" +
+ " field of each operation. If set and the `package` directive" +
+ " is shown in the proto file, the package name will be " +
+ " prepended to the service name",
+ ),
+ "fqn_for_openapi_name": attr.bool(
+ default = False,
+ mandatory = False,
+ doc = "if set, the object's OpenAPI names will use the fully" +
+ " qualified names from the proto definition" +
+ " (ie my.package.MyMessage.MyInnerMessage",
+ ),
+ "openapi_naming_strategy": attr.string(
+ default = "",
+ mandatory = False,
+ values = ["", "simple", "legacy", "fqn"],
+ doc = "configures how OpenAPI names are determined." +
+ " Allowed values are `` (empty), `simple`, `legacy` and `fqn`." +
+ " If unset, either `legacy` or `fqn` are selected, depending" +
+ " on the value of the `fqn_for_openapi_name` setting",
+ ),
+ "use_go_templates": attr.bool(
+ default = False,
+ mandatory = False,
+ doc = "if set, you can use Go templates in protofile comments",
+ ),
+ "disable_default_errors": attr.bool(
+ default = False,
+ mandatory = False,
+ doc = "if set, disables generation of default errors." +
+ " This is useful if you have defined custom error handling",
+ ),
+ "enums_as_ints": attr.bool(
+ default = False,
+ mandatory = False,
+ doc = "whether to render enum values as integers, as opposed to string values",
+ ),
+ "omit_enum_default_value": attr.bool(
+ default = False,
+ mandatory = False,
+ doc = "if set, omit default enum value",
+ ),
+ "output_format": attr.string(
+ default = "json",
+ mandatory = False,
+ values = ["json", "yaml"],
+ doc = "output content format. Allowed values are: `json`, `yaml`",
+ ),
+ "simple_operation_ids": attr.bool(
+ default = False,
+ mandatory = False,
+ doc = "whether to remove the service prefix in the operationID" +
+ " generation. Can introduce duplicate operationIDs, use with caution.",
+ ),
+ "proto3_optional_nullable": attr.bool(
+ default = False,
+ mandatory = False,
+ doc = "whether Proto3 Optional fields should be marked as x-nullable",
+ ),
+ "openapi_configuration": attr.label(
+ allow_single_file = True,
+ mandatory = False,
+ doc = "path to file which describes the OpenAPI Configuration in YAML format",
+ ),
+ "generate_unbound_methods": attr.bool(
+ default = False,
+ mandatory = False,
+ doc = "generate swagger metadata even for RPC methods that have" +
+ " no HttpRule annotation",
+ ),
+ "visibility_restriction_selectors": attr.string_list(
+ mandatory = False,
+ doc = "list of `google.api.VisibilityRule` visibility labels to include" +
+ " in the generated output when a visibility annotation is defined." +
+ " Repeat this option to supply multiple values. Elements without" +
+ " visibility annotations are unaffected by this setting.",
+ ),
+ "_protoc": attr.label(
+ default = "@com_google_protobuf//:protoc",
+ executable = True,
+ cfg = "host",
+ ),
+ "_well_known_protos": attr.label(
+ default = "@com_google_protobuf//:well_known_protos",
+ allow_files = True,
+ ),
+ "_protoc_gen_openapi": attr.label(
+ default = Label("//gateway/protoc-gen-openapiv2:protoc-gen-openapiv2"),
+ executable = True,
+ cfg = "host",
+ ),
+ },
+ implementation = _proto_gen_openapi_impl,
+)
diff --git a/gateway/protoc-gen-openapiv2/internal/genopenapi/BUILD.bazel b/gateway/protoc-gen-openapiv2/internal/genopenapi/BUILD.bazel
new file mode 100644
index 0000000..9285616
--- /dev/null
+++ b/gateway/protoc-gen-openapiv2/internal/genopenapi/BUILD.bazel
@@ -0,0 +1,73 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+
+package(default_visibility = ["//visibility:public"])
+
+go_library(
+ name = "genopenapi",
+ srcs = [
+ "doc.go",
+ "format.go",
+ "generator.go",
+ "helpers.go",
+ "helpers_go111_old.go",
+ "naming.go",
+ "template.go",
+ "types.go",
+ ],
+ importpath = "github.com/binchencoder/janus-gateway/gateway/protoc-gen-openapiv2/internal/genopenapi",
+ deps = [
+ "//gateway/internal/casing",
+ "//gateway/internal/descriptor",
+ "//gateway/internal/generator",
+ "//gateway/protoc-gen-openapiv2/options",
+ "//httpoptions",
+ "@com_github_golang_glog//:glog",
+ "@com_github_golang_protobuf//descriptor:go_default_library_gen",
+ "@go_googleapis//google/api:annotations_go_proto",
+ "@go_googleapis//google/api:visibility_go_proto",
+ "@go_googleapis//google/rpc:status_go_proto",
+ "@in_gopkg_yaml_v2//:yaml_v2",
+ "@io_bazel_rules_go//proto/wkt:any_go_proto",
+ "@org_golang_google_protobuf//encoding/protojson",
+ "@org_golang_google_protobuf//proto",
+ "@org_golang_google_protobuf//types/descriptorpb",
+ "@org_golang_google_protobuf//types/known/structpb",
+ "@org_golang_google_protobuf//types/pluginpb",
+ ],
+)
+
+go_test(
+ name = "genopenapi_test",
+ size = "small",
+ srcs = [
+ "cycle_test.go",
+ ],
+ embed = [":genopenapi"],
+ deps = [
+ "//gateway/internal/descriptor",
+ "//gateway/internal/descriptor/openapiconfig",
+ "@com_github_grpc_ecosystem_grpc_gateway//internal/httprule",
+ "//gateway/protoc-gen-openapiv2/options",
+ "//gateway/runtime",
+ "@com_github_google_go_cmp//cmp",
+ "@go_googleapis//google/api:annotations_go_proto",
+ "@go_googleapis//google/api:visibility_go_proto",
+ "@in_gopkg_yaml_v2//:yaml_v2",
+ "@io_bazel_rules_go//proto/wkt:field_mask_go_proto",
+ "@org_golang_google_protobuf//proto",
+ "@org_golang_google_protobuf//reflect/protodesc",
+ "@org_golang_google_protobuf//types/descriptorpb",
+ "@org_golang_google_protobuf//types/known/anypb",
+ "@org_golang_google_protobuf//types/known/durationpb",
+ "@org_golang_google_protobuf//types/known/structpb",
+ "@org_golang_google_protobuf//types/known/timestamppb",
+ "@org_golang_google_protobuf//types/known/wrapperspb",
+ "@org_golang_google_protobuf//types/pluginpb",
+ ],
+)
+
+alias(
+ name = "go_default_library",
+ actual = ":genopenapi",
+ visibility = ["//protoc-gen-openapiv2:__subpackages__"],
+)
diff --git a/gateway/protoc-gen-openapiv2/internal/genopenapi/cycle_test.go b/gateway/protoc-gen-openapiv2/internal/genopenapi/cycle_test.go
new file mode 100644
index 0000000..8861315
--- /dev/null
+++ b/gateway/protoc-gen-openapiv2/internal/genopenapi/cycle_test.go
@@ -0,0 +1,41 @@
+package genopenapi
+
+import (
+ "testing"
+)
+
+func TestCycle(t *testing.T) {
+ for _, tt := range []struct {
+ max int
+ attempt int
+ e bool
+ }{
+ {
+ max: 3,
+ attempt: 3,
+ e: true,
+ },
+ {
+ max: 5,
+ attempt: 6,
+ },
+ {
+ max: 1000,
+ attempt: 1001,
+ },
+ } {
+
+ c := newCycleChecker(tt.max)
+ var final bool
+ for i := 0; i < tt.attempt; i++ {
+ final = c.Check("a")
+ if !final {
+ break
+ }
+ }
+
+ if final != tt.e {
+ t.Errorf("got: %t wanted: %t", final, tt.e)
+ }
+ }
+}
diff --git a/gateway/protoc-gen-openapiv2/internal/genopenapi/doc.go b/gateway/protoc-gen-openapiv2/internal/genopenapi/doc.go
new file mode 100644
index 0000000..42f9237
--- /dev/null
+++ b/gateway/protoc-gen-openapiv2/internal/genopenapi/doc.go
@@ -0,0 +1,2 @@
+// Package genopenapi provides a code generator for OpenAPI v2.
+package genopenapi
diff --git a/gateway/protoc-gen-openapiv2/internal/genopenapi/format.go b/gateway/protoc-gen-openapiv2/internal/genopenapi/format.go
new file mode 100644
index 0000000..e957acc
--- /dev/null
+++ b/gateway/protoc-gen-openapiv2/internal/genopenapi/format.go
@@ -0,0 +1,43 @@
+package genopenapi
+
+import (
+ "encoding/json"
+ "errors"
+ "io"
+
+ "gopkg.in/yaml.v2"
+)
+
+type Format string
+
+const (
+ FormatJSON Format = "json"
+ FormatYAML Format = "yaml"
+)
+
+type ContentEncoder interface {
+ Encode(v interface{}) (err error)
+}
+
+func (f Format) Validate() error {
+ switch f {
+ case FormatJSON, FormatYAML:
+ return nil
+ default:
+ return errors.New("unknown format: " + string(f))
+ }
+}
+
+func (f Format) NewEncoder(w io.Writer) (ContentEncoder, error) {
+ switch f {
+ case FormatYAML:
+ return yaml.NewEncoder(w), nil
+ case FormatJSON:
+ enc := json.NewEncoder(w)
+ enc.SetIndent("", " ")
+
+ return enc, nil
+ default:
+ return nil, errors.New("unknown format: " + string(f))
+ }
+}
diff --git a/gateway/protoc-gen-swagger/genswagger/generator.go b/gateway/protoc-gen-openapiv2/internal/genopenapi/generator.go
similarity index 52%
rename from gateway/protoc-gen-swagger/genswagger/generator.go
rename to gateway/protoc-gen-openapiv2/internal/genopenapi/generator.go
index 122d834..06c317d 100644
--- a/gateway/protoc-gen-swagger/genswagger/generator.go
+++ b/gateway/protoc-gen-openapiv2/internal/genopenapi/generator.go
@@ -1,4 +1,4 @@
-package genswagger
+package genopenapi
import (
"bytes"
@@ -10,21 +10,20 @@ import (
"strings"
"github.com/golang/glog"
- pbdescriptor "github.com/golang/protobuf/descriptor"
- "github.com/golang/protobuf/proto"
- protocdescriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
- plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
- "github.com/golang/protobuf/ptypes/any"
- "github.com/grpc-ecosystem/grpc-gateway/internal"
+ anypb "github.com/golang/protobuf/ptypes/any"
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor"
+ "github.com/binchencoder/janus-gateway/gateway/internal/descriptor"
+ // gen "github.com/grpc-ecosystem/grpc-gateway/v2/internal/generator"
+ gen "github.com/binchencoder/janus-gateway/gateway/internal/generator"
+ // openapi_options "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
+ openapi_options "github.com/binchencoder/janus-gateway/gateway/protoc-gen-openapiv2/options"
+ statuspb "google.golang.org/genproto/googleapis/rpc/status"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/types/descriptorpb"
+ "google.golang.org/protobuf/types/pluginpb"
- // "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
- "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/descriptor"
-
- // gen "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/generator"
- gen "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/generator"
-
- // swagger_options "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options"
- swagger_options "github.com/binchencoder/ease-gateway/gateway/protoc-gen-swagger/options"
+ //nolint:staticcheck // Known issue, will be replaced when possible
+ legacydescriptor "github.com/golang/protobuf/descriptor"
)
var (
@@ -32,20 +31,29 @@ var (
)
type generator struct {
- reg *descriptor.Registry
+ reg *descriptor.Registry
+ format Format
}
type wrapper struct {
fileName string
- swagger *swaggerObject
+ swagger *openapiSwaggerObject
+}
+
+type GeneratorOptions struct {
+ Registry *descriptor.Registry
+ RecursiveDepth int
}
// New returns a new generator which generates grpc gateway files.
-func New(reg *descriptor.Registry) gen.Generator {
- return &generator{reg: reg}
+func New(reg *descriptor.Registry, format Format) gen.Generator {
+ return &generator{
+ reg: reg,
+ format: format,
+ }
}
-// Merge a lot of swagger file (wrapper) to single one swagger file
+// Merge a lot of OpenAPI file (wrapper) to single one OpenAPI file
func mergeTargetFile(targets []*wrapper, mergeFileName string) *wrapper {
var mergedTarget *wrapper
for _, f := range targets {
@@ -58,9 +66,6 @@ func mergeTargetFile(targets []*wrapper, mergeFileName string) *wrapper {
for k, v := range f.swagger.Definitions {
mergedTarget.swagger.Definitions[k] = v
}
- for k, v := range f.swagger.StreamDefinitions {
- mergedTarget.swagger.StreamDefinitions[k] = v
- }
for k, v := range f.swagger.Paths {
mergedTarget.swagger.Paths[k] = v
}
@@ -82,28 +87,28 @@ func mergeTargetFile(targets []*wrapper, mergeFileName string) *wrapper {
// on them. See http://choly.ca/post/go-json-marshalling/ (or, if it ever
// goes away, use
// https://web.archive.org/web/20190806073003/http://choly.ca/post/go-json-marshalling/.
-func (so swaggerObject) MarshalJSON() ([]byte, error) {
- type alias swaggerObject
+func (so openapiSwaggerObject) MarshalJSON() ([]byte, error) {
+ type alias openapiSwaggerObject
return extensionMarshalJSON(alias(so), so.extensions)
}
-func (so swaggerInfoObject) MarshalJSON() ([]byte, error) {
- type alias swaggerInfoObject
+func (so openapiInfoObject) MarshalJSON() ([]byte, error) {
+ type alias openapiInfoObject
return extensionMarshalJSON(alias(so), so.extensions)
}
-func (so swaggerSecuritySchemeObject) MarshalJSON() ([]byte, error) {
- type alias swaggerSecuritySchemeObject
+func (so openapiSecuritySchemeObject) MarshalJSON() ([]byte, error) {
+ type alias openapiSecuritySchemeObject
return extensionMarshalJSON(alias(so), so.extensions)
}
-func (so swaggerOperationObject) MarshalJSON() ([]byte, error) {
- type alias swaggerOperationObject
+func (so openapiOperationObject) MarshalJSON() ([]byte, error) {
+ type alias openapiOperationObject
return extensionMarshalJSON(alias(so), so.extensions)
}
-func (so swaggerResponseObject) MarshalJSON() ([]byte, error) {
- type alias swaggerResponseObject
+func (so openapiResponseObject) MarshalJSON() ([]byte, error) {
+ type alias openapiResponseObject
return extensionMarshalJSON(alias(so), so.extensions)
}
@@ -114,14 +119,14 @@ func extensionMarshalJSON(so interface{}, extensions []extension) ([]byte, error
//
// The struct will look like
// struct {
- // *swaggerCore
+ // *openapiCore
// XGrpcGatewayFoo json.RawMessage `json:"x-grpc-gateway-foo"`
// XGrpcGatewayBar json.RawMessage `json:"x-grpc-gateway-bar"`
// }
- // and thus render into what we want -- the JSON of swaggerCore with the
+ // and thus render into what we want -- the JSON of openapiCore with the
// extensions appended.
fields := []reflect.StructField{
- reflect.StructField{ // embedded
+ { // embedded
Name: "Embedded",
Type: reflect.TypeOf(so),
Anonymous: true,
@@ -144,31 +149,37 @@ func extensionMarshalJSON(so interface{}, extensions []extension) ([]byte, error
return json.Marshal(s.Interface())
}
-// encodeSwagger converts swagger file obj to plugin.CodeGeneratorResponse_File
-func encodeSwagger(file *wrapper) (*plugin.CodeGeneratorResponse_File, error) {
- var formatted bytes.Buffer
- enc := json.NewEncoder(&formatted)
- enc.SetIndent("", " ")
+// encodeOpenAPI converts OpenAPI file obj to pluginpb.CodeGeneratorResponse_File
+func encodeOpenAPI(file *wrapper, format Format) (*descriptor.ResponseFile, error) {
+ var contentBuf bytes.Buffer
+ enc, err := format.NewEncoder(&contentBuf)
+ if err != nil {
+ return nil, err
+ }
+
if err := enc.Encode(*file.swagger); err != nil {
return nil, err
}
+
name := file.fileName
ext := filepath.Ext(name)
base := strings.TrimSuffix(name, ext)
- output := fmt.Sprintf("%s.swagger.json", base)
- return &plugin.CodeGeneratorResponse_File{
- Name: proto.String(output),
- Content: proto.String(formatted.String()),
+ output := fmt.Sprintf("%s.swagger."+string(format), base)
+ return &descriptor.ResponseFile{
+ CodeGeneratorResponse_File: &pluginpb.CodeGeneratorResponse_File{
+ Name: proto.String(output),
+ Content: proto.String(contentBuf.String()),
+ },
}, nil
}
-func (g *generator) Generate(targets []*descriptor.File) ([]*plugin.CodeGeneratorResponse_File, error) {
- var files []*plugin.CodeGeneratorResponse_File
+func (g *generator) Generate(targets []*descriptor.File) ([]*descriptor.ResponseFile, error) {
+ var files []*descriptor.ResponseFile
if g.reg.IsAllowMerge() {
var mergedTarget *descriptor.File
// try to find proto leader
for _, f := range targets {
- if proto.HasExtension(f.Options, swagger_options.E_Openapiv2Swagger) {
+ if proto.HasExtension(f.Options, openapi_options.E_Openapiv2Swagger) {
mergedTarget = f
break
}
@@ -177,7 +188,7 @@ func (g *generator) Generate(targets []*descriptor.File) ([]*plugin.CodeGenerato
for _, f := range targets {
if mergedTarget == nil {
mergedTarget = f
- } else {
+ } else if mergedTarget != f {
mergedTarget.Enums = append(mergedTarget.Enums, f.Enums...)
mergedTarget.Messages = append(mergedTarget.Messages, f.Messages...)
mergedTarget.Services = append(mergedTarget.Services, f.Services...)
@@ -188,7 +199,7 @@ func (g *generator) Generate(targets []*descriptor.File) ([]*plugin.CodeGenerato
targets = append(targets, mergedTarget)
}
- var swaggers []*wrapper
+ var openapis []*wrapper
for _, file := range targets {
glog.V(1).Infof("Processing %s", file.GetName())
swagger, err := applyTemplate(param{File: file, reg: g.reg})
@@ -199,51 +210,48 @@ func (g *generator) Generate(targets []*descriptor.File) ([]*plugin.CodeGenerato
if err != nil {
return nil, err
}
- swaggers = append(swaggers, &wrapper{
+ openapis = append(openapis, &wrapper{
fileName: file.GetName(),
swagger: swagger,
})
}
if g.reg.IsAllowMerge() {
- targetSwagger := mergeTargetFile(swaggers, g.reg.GetMergeFileName())
- f, err := encodeSwagger(targetSwagger)
+ targetOpenAPI := mergeTargetFile(openapis, g.reg.GetMergeFileName())
+ f, err := encodeOpenAPI(targetOpenAPI, g.format)
if err != nil {
- return nil, fmt.Errorf("failed to encode swagger for %s: %s", g.reg.GetMergeFileName(), err)
+ return nil, fmt.Errorf("failed to encode OpenAPI for %s: %s", g.reg.GetMergeFileName(), err)
}
files = append(files, f)
- glog.V(1).Infof("New swagger file will emit")
+ glog.V(1).Infof("New OpenAPI file will emit")
} else {
- for _, file := range swaggers {
- f, err := encodeSwagger(file)
+ for _, file := range openapis {
+ f, err := encodeOpenAPI(file, g.format)
if err != nil {
- return nil, fmt.Errorf("failed to encode swagger for %s: %s", file.fileName, err)
+ return nil, fmt.Errorf("failed to encode OpenAPI for %s: %s", file.fileName, err)
}
files = append(files, f)
- glog.V(1).Infof("New swagger file will emit")
+ glog.V(1).Infof("New OpenAPI file will emit")
}
}
return files, nil
}
-//AddStreamError Adds grpc.gateway.runtime.StreamError and google.protobuf.Any to registry for stream responses
-func AddStreamError(reg *descriptor.Registry) error {
- //load internal protos
- any := fileDescriptorProtoForMessage(&any.Any{})
- streamError := fileDescriptorProtoForMessage(&internal.StreamError{})
- if err := reg.Load(&plugin.CodeGeneratorRequest{
- ProtoFile: []*protocdescriptor.FileDescriptorProto{
+// AddErrorDefs Adds google.rpc.Status and google.protobuf.Any
+// to registry (used for error-related API responses)
+func AddErrorDefs(reg *descriptor.Registry) error {
+ // load internal protos
+ any, _ := legacydescriptor.MessageDescriptorProto(&anypb.Any{})
+ any.SourceCodeInfo = new(descriptorpb.SourceCodeInfo)
+ status, _ := legacydescriptor.MessageDescriptorProto(&statuspb.Status{})
+ status.SourceCodeInfo = new(descriptorpb.SourceCodeInfo)
+ // TODO(johanbrandhorst): Use new conversion later when possible
+ // any := protodesc.ToFileDescriptorProto((&anypb.Any{}).ProtoReflect().Descriptor().ParentFile())
+ // status := protodesc.ToFileDescriptorProto((&statuspb.Status{}).ProtoReflect().Descriptor().ParentFile())
+ return reg.Load(&pluginpb.CodeGeneratorRequest{
+ ProtoFile: []*descriptorpb.FileDescriptorProto{
any,
- streamError,
+ status,
},
- }); err != nil {
- return err
- }
- return nil
-}
-
-func fileDescriptorProtoForMessage(msg pbdescriptor.Message) *protocdescriptor.FileDescriptorProto {
- fdp, _ := pbdescriptor.ForMessage(msg)
- fdp.SourceCodeInfo = &protocdescriptor.SourceCodeInfo{}
- return fdp
+ })
}
diff --git a/gateway/protoc-gen-swagger/genswagger/helpers.go b/gateway/protoc-gen-openapiv2/internal/genopenapi/helpers.go
similarity index 86%
rename from gateway/protoc-gen-swagger/genswagger/helpers.go
rename to gateway/protoc-gen-openapiv2/internal/genopenapi/helpers.go
index 3615596..c53d680 100644
--- a/gateway/protoc-gen-swagger/genswagger/helpers.go
+++ b/gateway/protoc-gen-openapiv2/internal/genopenapi/helpers.go
@@ -1,6 +1,6 @@
//+build go1.12
-package genswagger
+package genopenapi
import "strings"
diff --git a/gateway/protoc-gen-swagger/genswagger/helpers_go111_old.go b/gateway/protoc-gen-openapiv2/internal/genopenapi/helpers_go111_old.go
similarity index 87%
rename from gateway/protoc-gen-swagger/genswagger/helpers_go111_old.go
rename to gateway/protoc-gen-openapiv2/internal/genopenapi/helpers_go111_old.go
index 8e9458d..b8db119 100644
--- a/gateway/protoc-gen-swagger/genswagger/helpers_go111_old.go
+++ b/gateway/protoc-gen-openapiv2/internal/genopenapi/helpers_go111_old.go
@@ -1,6 +1,6 @@
//+build !go1.12
-package genswagger
+package genopenapi
import "strings"
diff --git a/gateway/protoc-gen-openapiv2/internal/genopenapi/naming.go b/gateway/protoc-gen-openapiv2/internal/genopenapi/naming.go
new file mode 100644
index 0000000..338ea2d
--- /dev/null
+++ b/gateway/protoc-gen-openapiv2/internal/genopenapi/naming.go
@@ -0,0 +1,110 @@
+package genopenapi
+
+import (
+ "reflect"
+ "strings"
+)
+
+// LookupNamingStrategy looks up the given naming strategy and returns the naming
+// strategy function for it. The naming strategy function takes in the list of all
+// fully-qualified proto message names, and returns a mapping from fully-qualified
+// name to OpenAPI name.
+func LookupNamingStrategy(strategyName string) func([]string) map[string]string {
+ switch strings.ToLower(strategyName) {
+ case "fqn":
+ return resolveNamesFQN
+ case "legacy":
+ return resolveNamesLegacy
+ case "simple":
+ return resolveNamesSimple
+ }
+ return nil
+}
+
+// resolveNamesFQN uses the fully-qualified proto message name as the
+// OpenAPI name, stripping the leading dot.
+func resolveNamesFQN(messages []string) map[string]string {
+ uniqueNames := make(map[string]string, len(messages))
+ for _, p := range messages {
+ // strip leading dot from proto fqn
+ uniqueNames[p] = p[1:]
+ }
+ return uniqueNames
+}
+
+// resolveNamesLegacy takes the names of all proto messages and generates unique references by
+// applying the legacy heuristics for deriving unique names: starting from the bottom of the name hierarchy, it
+// determines the minimum number of components necessary to yield a unique name, adds one
+// to that number, and then concatenates those last components with no separator in between
+// to form a unique name.
+//
+// E.g., if the fully qualified name is `.a.b.C.D`, and there are other messages with fully
+// qualified names ending in `.D` but not in `.C.D`, it assigns the unique name `bCD`.
+func resolveNamesLegacy(messages []string) map[string]string {
+ return resolveNamesUniqueWithContext(messages, 1, "")
+}
+
+// resolveNamesSimple takes the names of all proto messages and generates unique references by using a simple
+// heuristic: starting from the bottom of the name hierarchy, it determines the minimum
+// number of components necessary to yield a unique name, and then concatenates those last
+// components with a "." separator in between to form a unique name.
+//
+// E.g., if the fully qualified name is `.a.b.C.D`, and there are other messages with
+// fully qualified names ending in `.D` but not in `.C.D`, it assigns the unique name `C.D`.
+func resolveNamesSimple(messages []string) map[string]string {
+ return resolveNamesUniqueWithContext(messages, 0, ".")
+}
+
+// Take the names of every proto message and generates a unique reference by:
+// first, separating each message name into its components by splitting at dots. Then,
+// take the shortest suffix slice from each components slice that is unique among all
+// messages, and convert it into a component name by taking extraContext additional
+// components into consideration and joining all components with componentSeparator.
+func resolveNamesUniqueWithContext(messages []string, extraContext int, componentSeparator string) map[string]string {
+ packagesByDepth := make(map[int][][]string)
+ uniqueNames := make(map[string]string)
+
+ hierarchy := func(pkg string) []string {
+ return strings.Split(pkg, ".")
+ }
+
+ for _, p := range messages {
+ h := hierarchy(p)
+ for depth := range h {
+ if _, ok := packagesByDepth[depth]; !ok {
+ packagesByDepth[depth] = make([][]string, 0)
+ }
+ packagesByDepth[depth] = append(packagesByDepth[depth], h[len(h)-depth:])
+ }
+ }
+
+ count := func(list [][]string, item []string) int {
+ i := 0
+ for _, element := range list {
+ if reflect.DeepEqual(element, item) {
+ i++
+ }
+ }
+ return i
+ }
+
+ for _, p := range messages {
+ h := hierarchy(p)
+ depth := 0
+ for ; depth < len(h); depth++ {
+ // depth + extraContext > 0 ensures that we only break for values of depth when the
+ // resulting slice of name components is non-empty. Otherwise, we would return the
+ // empty string as the concise unique name is len(messages) == 1 (which is
+ // technically correct).
+ if depth+extraContext > 0 && count(packagesByDepth[depth], h[len(h)-depth:]) == 1 {
+ break
+ }
+ }
+ start := len(h) - depth - extraContext
+ if start < 0 {
+ start = 0
+ }
+ uniqueNames[p] = strings.Join(h[start:], componentSeparator)
+ }
+ return uniqueNames
+}
diff --git a/gateway/protoc-gen-openapiv2/internal/genopenapi/template.go b/gateway/protoc-gen-openapiv2/internal/genopenapi/template.go
new file mode 100644
index 0000000..ca82733
--- /dev/null
+++ b/gateway/protoc-gen-openapiv2/internal/genopenapi/template.go
@@ -0,0 +1,2775 @@
+package genopenapi
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "math"
+ "net/textproto"
+ "os"
+ "reflect"
+ "regexp"
+ "sort"
+ "strconv"
+ "strings"
+ "sync"
+ "text/template"
+ "time"
+
+ "github.com/golang/glog"
+
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/internal/casing"
+ "github.com/binchencoder/janus-gateway/gateway/internal/casing"
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor"
+ "github.com/binchencoder/janus-gateway/gateway/internal/descriptor"
+ // openapi_options "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
+ openapi_options "github.com/binchencoder/janus-gateway/gateway/protoc-gen-openapiv2/options"
+ "google.golang.org/genproto/googleapis/api/annotations"
+ "google.golang.org/genproto/googleapis/api/visibility"
+ "google.golang.org/protobuf/encoding/protojson"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/types/descriptorpb"
+
+ "google.golang.org/protobuf/types/known/structpb"
+
+ options "github.com/binchencoder/janus-gateway/httpoptions"
+)
+
+// The OpenAPI specification does not allow for more than one endpoint with the same HTTP method and path.
+// This prevents multiple gRPC service methods from sharing the same stripped version of the path and method.
+// For example: `GET /v1/{name=organizations/*}/roles` and `GET /v1/{name=users/*}/roles` both get stripped to `GET /v1/{name}/roles`.
+// We must make the URL unique by adding a suffix and an incrementing index to each path parameter
+// to differentiate the endpoints.
+// Since path parameter names do not affect the request contents (i.e. they're replaced in the path)
+// this will be hidden from the real grpc gateway consumer.
+const pathParamUniqueSuffixDeliminator = "_"
+
+const paragraphDeliminator = "\n\n"
+
+// wktSchemas are the schemas of well-known-types.
+// The schemas must match with the behavior of the JSON unmarshaler in
+// https://github.com/protocolbuffers/protobuf-go/blob/v1.25.0/encoding/protojson/well_known_types.go
+var wktSchemas = map[string]schemaCore{
+ ".google.protobuf.FieldMask": {
+ Type: "string",
+ },
+ ".google.protobuf.Timestamp": {
+ Type: "string",
+ Format: "date-time",
+ },
+ ".google.protobuf.Duration": {
+ Type: "string",
+ },
+ ".google.protobuf.StringValue": {
+ Type: "string",
+ },
+ ".google.protobuf.BytesValue": {
+ Type: "string",
+ Format: "byte",
+ },
+ ".google.protobuf.Int32Value": {
+ Type: "integer",
+ Format: "int32",
+ },
+ ".google.protobuf.UInt32Value": {
+ Type: "integer",
+ Format: "int64",
+ },
+ ".google.protobuf.Int64Value": {
+ Type: "string",
+ Format: "int64",
+ },
+ ".google.protobuf.UInt64Value": {
+ Type: "string",
+ Format: "uint64",
+ },
+ ".google.protobuf.FloatValue": {
+ Type: "number",
+ Format: "float",
+ },
+ ".google.protobuf.DoubleValue": {
+ Type: "number",
+ Format: "double",
+ },
+ ".google.protobuf.BoolValue": {
+ Type: "boolean",
+ },
+ ".google.protobuf.Empty": {},
+ ".google.protobuf.Struct": {
+ Type: "object",
+ },
+ ".google.protobuf.Value": {
+ Type: "object",
+ },
+ ".google.protobuf.ListValue": {
+ Type: "array",
+ Items: (*openapiItemsObject)(&schemaCore{
+ Type: "object",
+ }),
+ },
+ ".google.protobuf.NullValue": {
+ Type: "string",
+ },
+}
+
+func listEnumNames(reg *descriptor.Registry, enum *descriptor.Enum) (names []string) {
+ for _, value := range enum.GetValue() {
+ if !isVisible(getEnumValueVisibilityOption(value), reg) {
+ continue
+ }
+ if reg.GetOmitEnumDefaultValue() && value.GetNumber() == 0 {
+ continue
+ }
+ names = append(names, value.GetName())
+ }
+ return names
+}
+
+func listEnumNumbers(reg *descriptor.Registry, enum *descriptor.Enum) (numbers []string) {
+ for _, value := range enum.GetValue() {
+ if reg.GetOmitEnumDefaultValue() && value.GetNumber() == 0 {
+ continue
+ }
+ if !isVisible(getEnumValueVisibilityOption(value), reg) {
+ continue
+ }
+ numbers = append(numbers, strconv.Itoa(int(value.GetNumber())))
+ }
+ return
+}
+
+func getEnumDefault(reg *descriptor.Registry, enum *descriptor.Enum) string {
+ if !reg.GetOmitEnumDefaultValue() {
+ for _, value := range enum.GetValue() {
+ if value.GetNumber() == 0 {
+ return value.GetName()
+ }
+ }
+ }
+ return ""
+}
+
+// messageToQueryParameters converts a message to a list of OpenAPI query parameters.
+func messageToQueryParameters(message *descriptor.Message, reg *descriptor.Registry, pathParams []descriptor.Parameter, body *descriptor.Body) (params []openapiParameterObject, err error) {
+ for _, field := range message.Fields {
+ if !isVisible(getFieldVisibilityOption(field), reg) {
+ continue
+ }
+
+ p, err := queryParams(message, field, "", reg, pathParams, body, reg.GetRecursiveDepth())
+ if err != nil {
+ return nil, err
+ }
+ params = append(params, p...)
+ }
+ return params, nil
+}
+
+// queryParams converts a field to a list of OpenAPI query parameters recursively through the use of nestedQueryParams.
+func queryParams(message *descriptor.Message, field *descriptor.Field, prefix string, reg *descriptor.Registry, pathParams []descriptor.Parameter, body *descriptor.Body, recursiveCount int) (params []openapiParameterObject, err error) {
+ return nestedQueryParams(message, field, prefix, reg, pathParams, body, newCycleChecker(recursiveCount))
+}
+
+type cycleChecker struct {
+ m map[string]int
+ count int
+}
+
+func newCycleChecker(recursive int) *cycleChecker {
+ return &cycleChecker{
+ m: make(map[string]int),
+ count: recursive,
+ }
+}
+
+// Check returns whether name is still within recursion
+// toleration
+func (c *cycleChecker) Check(name string) bool {
+ count, ok := c.m[name]
+ count = count + 1
+ isCycle := count > c.count
+
+ if isCycle {
+ return false
+ }
+
+ // provision map entry if not available
+ if !ok {
+ c.m[name] = 1
+ return true
+ }
+
+ c.m[name] = count
+
+ return true
+}
+
+func (c *cycleChecker) Branch() *cycleChecker {
+ copy := &cycleChecker{
+ count: c.count,
+ m: map[string]int{},
+ }
+
+ for k, v := range c.m {
+ copy.m[k] = v
+ }
+
+ return copy
+}
+
+// nestedQueryParams converts a field to a list of OpenAPI query parameters recursively.
+// This function is a helper function for queryParams, that keeps track of cyclical message references
+// through the use of
+// touched map[string]int
+// If a cycle is discovered, an error is returned, as cyclical data structures are dangerous
+// in query parameters.
+func nestedQueryParams(message *descriptor.Message, field *descriptor.Field, prefix string, reg *descriptor.Registry, pathParams []descriptor.Parameter, body *descriptor.Body, cycle *cycleChecker) (params []openapiParameterObject, err error) {
+ // make sure the parameter is not already listed as a path parameter
+ for _, pathParam := range pathParams {
+ if pathParam.Target == field {
+ return nil, nil
+ }
+ }
+ // make sure the parameter is not already listed as a body parameter
+ if body != nil {
+ if body.FieldPath == nil {
+ return nil, nil
+ }
+ for _, fieldPath := range body.FieldPath {
+ if fieldPath.Target == field {
+ return nil, nil
+ }
+ }
+ }
+ schema := schemaOfField(field, reg, nil)
+ fieldType := field.GetTypeName()
+ if message.File != nil {
+ comments := fieldProtoComments(reg, message, field)
+ if err := updateOpenAPIDataFromComments(reg, &schema, message, comments, false); err != nil {
+ return nil, err
+ }
+ }
+
+ isEnum := field.GetType() == descriptorpb.FieldDescriptorProto_TYPE_ENUM
+ items := schema.Items
+ if schema.Type != "" || isEnum {
+ if schema.Type == "object" {
+ return nil, nil // TODO: currently, mapping object in query parameter is not supported
+ }
+ if items != nil && (items.Type == "" || items.Type == "object") && !isEnum {
+ return nil, nil // TODO: currently, mapping object in query parameter is not supported
+ }
+ desc := mergeDescription(schema)
+
+ // verify if the field is required
+ required := false
+ for _, fieldName := range schema.Required {
+ if fieldName == reg.FieldName(field) {
+ required = true
+ break
+ }
+ }
+
+ param := openapiParameterObject{
+ Description: desc,
+ In: "query",
+ Default: schema.Default,
+ Type: schema.Type,
+ Items: schema.Items,
+ Format: schema.Format,
+ Pattern: schema.Pattern,
+ Required: required,
+ }
+ if param.Type == "array" {
+ param.CollectionFormat = "multi"
+ }
+
+ param.Name = prefix + reg.FieldName(field)
+
+ if isEnum {
+ enum, err := reg.LookupEnum("", fieldType)
+ if err != nil {
+ return nil, fmt.Errorf("unknown enum type %s", fieldType)
+ }
+ if items != nil { // array
+ param.Items = &openapiItemsObject{
+ Type: "string",
+ Enum: listEnumNames(reg, enum),
+ }
+ if reg.GetEnumsAsInts() {
+ param.Items.Type = "integer"
+ param.Items.Enum = listEnumNumbers(reg, enum)
+ }
+ } else {
+ param.Type = "string"
+ param.Enum = listEnumNames(reg, enum)
+ param.Default = getEnumDefault(reg, enum)
+ if reg.GetEnumsAsInts() {
+ param.Type = "integer"
+ param.Enum = listEnumNumbers(reg, enum)
+ if !reg.GetOmitEnumDefaultValue() {
+ param.Default = "0"
+ }
+ }
+ }
+ valueComments := enumValueProtoComments(reg, enum)
+ if valueComments != "" {
+ param.Description = strings.TrimLeft(param.Description+"\n\n "+valueComments, "\n")
+ }
+ }
+ return []openapiParameterObject{param}, nil
+ }
+
+ // nested type, recurse
+ msg, err := reg.LookupMsg("", fieldType)
+ if err != nil {
+ return nil, fmt.Errorf("unknown message type %s", fieldType)
+ }
+
+ // Check for cyclical message reference:
+ isOK := cycle.Check(*msg.Name)
+ if !isOK {
+ return nil, fmt.Errorf("exceeded recursive count (%d) for query parameter %q", cycle.count, fieldType)
+ }
+
+ // Construct a new map with the message name so a cycle further down the recursive path can be detected.
+ // Do not keep anything in the original touched reference and do not pass that reference along. This will
+ // prevent clobbering adjacent records while recursing.
+ touchedOut := cycle.Branch()
+
+ for _, nestedField := range msg.Fields {
+ if !isVisible(getFieldVisibilityOption(nestedField), reg) {
+ continue
+ }
+
+ fieldName := reg.FieldName(field)
+ p, err := nestedQueryParams(msg, nestedField, prefix+fieldName+".", reg, pathParams, body, touchedOut)
+ if err != nil {
+ return nil, err
+ }
+ params = append(params, p...)
+ }
+ return params, nil
+}
+
+// findServicesMessagesAndEnumerations discovers all messages and enums defined in the RPC methods of the service.
+func findServicesMessagesAndEnumerations(s []*descriptor.Service, reg *descriptor.Registry, m messageMap, ms messageMap, e enumMap, refs refMap) {
+ for _, svc := range s {
+ for _, meth := range svc.Methods {
+ // Request may be fully included in query
+ {
+ swgReqName, ok := fullyQualifiedNameToOpenAPIName(meth.RequestType.FQMN(), reg)
+ if !ok {
+ glog.Errorf("couldn't resolve OpenAPI name for FQMN '%v'", meth.RequestType.FQMN())
+ continue
+ }
+ if _, ok := refs[fmt.Sprintf("#/definitions/%s", swgReqName)]; ok {
+ if !skipRenderingRef(meth.RequestType.FQMN()) {
+ m[swgReqName] = meth.RequestType
+ }
+ }
+ }
+
+ swgRspName, ok := fullyQualifiedNameToOpenAPIName(meth.ResponseType.FQMN(), reg)
+ if !ok && !skipRenderingRef(meth.ResponseType.FQMN()) {
+ glog.Errorf("couldn't resolve OpenAPI name for FQMN '%v'", meth.ResponseType.FQMN())
+ continue
+ }
+
+ findNestedMessagesAndEnumerations(meth.RequestType, reg, m, e)
+
+ if !skipRenderingRef(meth.ResponseType.FQMN()) {
+ m[swgRspName] = meth.ResponseType
+ }
+ findNestedMessagesAndEnumerations(meth.ResponseType, reg, m, e)
+ }
+ }
+}
+
+// findNestedMessagesAndEnumerations those can be generated by the services.
+func findNestedMessagesAndEnumerations(message *descriptor.Message, reg *descriptor.Registry, m messageMap, e enumMap) {
+ // Iterate over all the fields that
+ for _, t := range message.Fields {
+ if !isVisible(getFieldVisibilityOption(t), reg) {
+ continue
+ }
+
+ fieldType := t.GetTypeName()
+ // If the type is an empty string then it is a proto primitive
+ if fieldType != "" {
+ if _, ok := m[fieldType]; !ok {
+ msg, err := reg.LookupMsg("", fieldType)
+ if err != nil {
+ enum, err := reg.LookupEnum("", fieldType)
+ if err != nil {
+ panic(err)
+ }
+ e[fieldType] = enum
+ continue
+ }
+ m[fieldType] = msg
+ findNestedMessagesAndEnumerations(msg, reg, m, e)
+ }
+ }
+ }
+}
+
+func skipRenderingRef(refName string) bool {
+ _, ok := wktSchemas[refName]
+ return ok
+}
+
+func renderMessageAsDefinition(msg *descriptor.Message, reg *descriptor.Registry, customRefs refMap, pathParams []descriptor.Parameter) (openapiSchemaObject, error) {
+ schema := openapiSchemaObject{
+ schemaCore: schemaCore{
+ Type: "object",
+ },
+ }
+ msgComments := protoComments(reg, msg.File, msg.Outers, "MessageType", int32(msg.Index))
+ if err := updateOpenAPIDataFromComments(reg, &schema, msg, msgComments, false); err != nil {
+ return openapiSchemaObject{}, err
+ }
+ opts, err := getMessageOpenAPIOption(reg, msg)
+ if err != nil {
+ return openapiSchemaObject{}, err
+ }
+ if opts != nil {
+ protoSchema := openapiSchemaFromProtoSchema(opts, reg, customRefs, msg)
+
+ // Warning: Make sure not to overwrite any fields already set on the schema type.
+ schema.ExternalDocs = protoSchema.ExternalDocs
+ schema.ReadOnly = protoSchema.ReadOnly
+ schema.MultipleOf = protoSchema.MultipleOf
+ schema.Maximum = protoSchema.Maximum
+ schema.ExclusiveMaximum = protoSchema.ExclusiveMaximum
+ schema.Minimum = protoSchema.Minimum
+ schema.ExclusiveMinimum = protoSchema.ExclusiveMinimum
+ schema.MaxLength = protoSchema.MaxLength
+ schema.MinLength = protoSchema.MinLength
+ schema.Pattern = protoSchema.Pattern
+ schema.Default = protoSchema.Default
+ schema.MaxItems = protoSchema.MaxItems
+ schema.MinItems = protoSchema.MinItems
+ schema.UniqueItems = protoSchema.UniqueItems
+ schema.MaxProperties = protoSchema.MaxProperties
+ schema.MinProperties = protoSchema.MinProperties
+ schema.Required = protoSchema.Required
+ schema.XNullable = protoSchema.XNullable
+ if protoSchema.schemaCore.Type != "" || protoSchema.schemaCore.Ref != "" {
+ schema.schemaCore = protoSchema.schemaCore
+ }
+ if protoSchema.Title != "" {
+ schema.Title = protoSchema.Title
+ }
+ if protoSchema.Description != "" {
+ schema.Description = protoSchema.Description
+ }
+ if protoSchema.Example != nil {
+ schema.Example = protoSchema.Example
+ }
+ }
+
+ schema.Required = filterOutExcludedFields(schema.Required, pathParams)
+
+ for _, f := range msg.Fields {
+ if !isVisible(getFieldVisibilityOption(f), reg) {
+ continue
+ }
+
+ if shouldExcludeField(f.GetName(), pathParams) {
+ continue
+ }
+ subPathParams := subPathParams(f.GetName(), pathParams)
+ fieldSchema, err := renderFieldAsDefinition(f, reg, customRefs, subPathParams)
+ if err != nil {
+ return openapiSchemaObject{}, err
+ }
+ comments := fieldProtoComments(reg, msg, f)
+ if err := updateOpenAPIDataFromComments(reg, &fieldSchema, f, comments, false); err != nil {
+ return openapiSchemaObject{}, err
+ }
+
+ if requiredIdx := find(schema.Required, *f.Name); requiredIdx != -1 && reg.GetUseJSONNamesForFields() {
+ schema.Required[requiredIdx] = f.GetJsonName()
+ }
+
+ if fieldSchema.Required != nil {
+ schema.Required = append(schema.Required, fieldSchema.Required...)
+ }
+
+ kv := keyVal{Value: fieldSchema}
+ kv.Key = reg.FieldName(f)
+ if schema.Properties == nil {
+ schema.Properties = &openapiSchemaObjectProperties{}
+ }
+ *schema.Properties = append(*schema.Properties, kv)
+ }
+
+ if msg.FQMN() == ".google.protobuf.Any" {
+ transformAnyForJSON(&schema, reg.GetUseJSONNamesForFields())
+ }
+
+ return schema, nil
+}
+
+func renderFieldAsDefinition(f *descriptor.Field, reg *descriptor.Registry, refs refMap, pathParams []descriptor.Parameter) (openapiSchemaObject, error) {
+ if len(pathParams) == 0 {
+ return schemaOfField(f, reg, refs), nil
+ }
+ location := ""
+ if ix := strings.LastIndex(f.Message.FQMN(), "."); ix > 0 {
+ location = f.Message.FQMN()[0:ix]
+ }
+ msg, err := reg.LookupMsg(location, f.GetTypeName())
+ if err != nil {
+ return openapiSchemaObject{}, err
+ }
+ schema, err := renderMessageAsDefinition(msg, reg, refs, pathParams)
+ if err != nil {
+ return openapiSchemaObject{}, err
+ }
+ comments := fieldProtoComments(reg, f.Message, f)
+ if len(comments) > 0 {
+ // Use title and description from field instead of nested message if present.
+ paragraphs := strings.Split(comments, paragraphDeliminator)
+ schema.Title = strings.TrimSpace(paragraphs[0])
+ schema.Description = strings.TrimSpace(strings.Join(paragraphs[1:], paragraphDeliminator))
+ }
+ return schema, nil
+}
+
+// transformAnyForJSON should be called when the schema object represents a google.protobuf.Any, and will replace the
+// Properties slice with a single value for '@type'. We mutate the incorrectly named field so that we inherit the same
+// documentation as specified on the original field in the protobuf descriptors.
+func transformAnyForJSON(schema *openapiSchemaObject, useJSONNames bool) {
+ var typeFieldName string
+ if useJSONNames {
+ typeFieldName = "typeUrl"
+ } else {
+ typeFieldName = "type_url"
+ }
+
+ for _, property := range *schema.Properties {
+ if property.Key == typeFieldName {
+ schema.AdditionalProperties = &openapiSchemaObject{}
+ schema.Properties = &openapiSchemaObjectProperties{keyVal{
+ Key: "@type",
+ Value: property.Value,
+ }}
+ break
+ }
+ }
+}
+
+func renderMessagesAsDefinition(messages messageMap, d openapiDefinitionsObject, reg *descriptor.Registry, customRefs refMap, pathParams []descriptor.Parameter) error {
+ for name, msg := range messages {
+ swgName, ok := fullyQualifiedNameToOpenAPIName(msg.FQMN(), reg)
+ if !ok {
+ return fmt.Errorf("can't resolve OpenAPI name from '%v'", msg.FQMN())
+ }
+ if skipRenderingRef(name) {
+ continue
+ }
+
+ if opt := msg.GetOptions(); opt != nil && opt.MapEntry != nil && *opt.MapEntry {
+ continue
+ }
+ var err error
+ d[swgName], err = renderMessageAsDefinition(msg, reg, customRefs, pathParams)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// isVisible checks if a field/RPC is visible based on the visibility restriction
+// combined with the `visibility_restriction_selectors`.
+// Elements with an overlap on `visibility_restriction_selectors` are visible, those without are not visible.
+// Elements without `google.api.VisibilityRule` annotations entirely are always visible.
+func isVisible(r *visibility.VisibilityRule, reg *descriptor.Registry) bool {
+ if r == nil {
+ return true
+ }
+
+ restrictions := strings.Split(strings.TrimSpace(r.Restriction), ",")
+ // No restrictions results in the element always being visible
+ if len(restrictions) == 0 {
+ return true
+ }
+
+ for _, restriction := range restrictions {
+ if reg.GetVisibilityRestrictionSelectors()[strings.TrimSpace(restriction)] {
+ return true
+ }
+ }
+
+ return false
+}
+
+func shouldExcludeField(name string, excluded []descriptor.Parameter) bool {
+ for _, p := range excluded {
+ if len(p.FieldPath) == 1 && name == p.FieldPath[0].Name {
+ return true
+ }
+ }
+ return false
+}
+func filterOutExcludedFields(fields []string, excluded []descriptor.Parameter) []string {
+ var filtered []string
+ for _, f := range fields {
+ if !shouldExcludeField(f, excluded) {
+ filtered = append(filtered, f)
+ }
+ }
+ return filtered
+}
+
+// schemaOfField returns a OpenAPI Schema Object for a protobuf field.
+func schemaOfField(f *descriptor.Field, reg *descriptor.Registry, refs refMap) openapiSchemaObject {
+ const (
+ singular = 0
+ array = 1
+ object = 2
+ )
+ var (
+ core schemaCore
+ aggregate int
+ )
+
+ fd := f.FieldDescriptorProto
+ location := ""
+ if ix := strings.LastIndex(f.Message.FQMN(), "."); ix > 0 {
+ location = f.Message.FQMN()[0:ix]
+ }
+ if m, err := reg.LookupMsg(location, f.GetTypeName()); err == nil {
+ if opt := m.GetOptions(); opt != nil && opt.MapEntry != nil && *opt.MapEntry {
+ fd = m.GetField()[1]
+ aggregate = object
+ }
+ }
+ if fd.GetLabel() == descriptorpb.FieldDescriptorProto_LABEL_REPEATED {
+ aggregate = array
+ }
+
+ var props *openapiSchemaObjectProperties
+
+ switch ft := fd.GetType(); ft {
+ case descriptorpb.FieldDescriptorProto_TYPE_ENUM, descriptorpb.FieldDescriptorProto_TYPE_MESSAGE, descriptorpb.FieldDescriptorProto_TYPE_GROUP:
+ if wktSchema, ok := wktSchemas[fd.GetTypeName()]; ok {
+ core = wktSchema
+
+ if fd.GetTypeName() == ".google.protobuf.Empty" {
+ props = &openapiSchemaObjectProperties{}
+ }
+ } else {
+ swgRef, ok := fullyQualifiedNameToOpenAPIName(fd.GetTypeName(), reg)
+ if !ok {
+ panic(fmt.Sprintf("can't resolve OpenAPI ref from typename '%v'", fd.GetTypeName()))
+ }
+ core = schemaCore{
+ Ref: "#/definitions/" + swgRef,
+ }
+ if refs != nil {
+ refs[fd.GetTypeName()] = struct{}{}
+ }
+ }
+ default:
+ ftype, format, ok := primitiveSchema(ft)
+ if ok {
+ if f.HasRule() {
+ core = schemaCore{Type: ftype, Format: format, Rules: getRules(f.Rules)}
+ } else {
+ core = schemaCore{Type: ftype, Format: format}
+ }
+ } else {
+ core = schemaCore{Type: ft.String(), Format: "UNKNOWN"}
+ }
+ }
+
+ ret := openapiSchemaObject{}
+
+ switch aggregate {
+ case array:
+ ret = openapiSchemaObject{
+ schemaCore: schemaCore{
+ Type: "array",
+ Items: (*openapiItemsObject)(&core),
+ },
+ }
+ case object:
+ ret = openapiSchemaObject{
+ schemaCore: schemaCore{
+ Type: "object",
+ },
+ AdditionalProperties: &openapiSchemaObject{Properties: props, schemaCore: core},
+ }
+ default:
+ ret = openapiSchemaObject{
+ schemaCore: core,
+ Properties: props,
+ }
+ }
+
+ if j, err := getFieldOpenAPIOption(reg, f); err == nil {
+ updateswaggerObjectFromJSONSchema(&ret, j, reg, f)
+ }
+
+ if j, err := getFieldBehaviorOption(reg, f); err == nil {
+ updateSwaggerObjectFromFieldBehavior(&ret, j, reg, f)
+ }
+
+ if reg.GetProto3OptionalNullable() && f.GetProto3Optional() {
+ ret.XNullable = true
+ }
+
+ return ret
+}
+
+// primitiveSchema returns a pair of "Type" and "Format" in JSON Schema for
+// the given primitive field type.
+// The last return parameter is true iff the field type is actually primitive.
+func primitiveSchema(t descriptorpb.FieldDescriptorProto_Type) (ftype, format string, ok bool) {
+ switch t {
+ case descriptorpb.FieldDescriptorProto_TYPE_DOUBLE:
+ return "number", "double", true
+ case descriptorpb.FieldDescriptorProto_TYPE_FLOAT:
+ return "number", "float", true
+ case descriptorpb.FieldDescriptorProto_TYPE_INT64:
+ return "string", "int64", true
+ case descriptorpb.FieldDescriptorProto_TYPE_UINT64:
+ // 64bit integer types are marshaled as string in the default JSONPb marshaler.
+ // TODO(yugui) Add an option to declare 64bit integers as int64.
+ //
+ // NOTE: uint64 is not a predefined format of integer type in OpenAPI spec.
+ // So we cannot expect that uint64 is commonly supported by OpenAPI processor.
+ return "string", "uint64", true
+ case descriptorpb.FieldDescriptorProto_TYPE_INT32:
+ return "integer", "int32", true
+ case descriptorpb.FieldDescriptorProto_TYPE_FIXED64:
+ // Ditto.
+ return "string", "uint64", true
+ case descriptorpb.FieldDescriptorProto_TYPE_FIXED32:
+ // Ditto.
+ return "integer", "int64", true
+ case descriptorpb.FieldDescriptorProto_TYPE_BOOL:
+ // NOTE: in OpenAPI specification, format should be empty on boolean type
+ return "boolean", "", true
+ case descriptorpb.FieldDescriptorProto_TYPE_STRING:
+ // NOTE: in OpenAPI specification, format should be empty on string type
+ return "string", "", true
+ case descriptorpb.FieldDescriptorProto_TYPE_BYTES:
+ return "string", "byte", true
+ case descriptorpb.FieldDescriptorProto_TYPE_UINT32:
+ // Ditto.
+ return "integer", "int64", true
+ case descriptorpb.FieldDescriptorProto_TYPE_SFIXED32:
+ return "integer", "int32", true
+ case descriptorpb.FieldDescriptorProto_TYPE_SFIXED64:
+ return "string", "int64", true
+ case descriptorpb.FieldDescriptorProto_TYPE_SINT32:
+ return "integer", "int32", true
+ case descriptorpb.FieldDescriptorProto_TYPE_SINT64:
+ return "string", "int64", true
+ default:
+ return "", "", false
+ }
+}
+
+// getRules returns a swagger rule slice.
+func getRules(rules []*descriptor.Rule) []options.ValidationRule {
+ rs := []options.ValidationRule{}
+ for _, v := range rules {
+ rs = append(rs, *v.Rule())
+ }
+ return rs
+}
+
+// renderEnumerationsAsDefinition inserts enums into the definitions object.
+func renderEnumerationsAsDefinition(enums enumMap, d openapiDefinitionsObject, reg *descriptor.Registry) {
+ for _, enum := range enums {
+ swgName, ok := fullyQualifiedNameToOpenAPIName(enum.FQEN(), reg)
+ if !ok {
+ panic(fmt.Sprintf("can't resolve OpenAPI name from FQEN '%v'", enum.FQEN()))
+ }
+ enumComments := protoComments(reg, enum.File, enum.Outers, "EnumType", int32(enum.Index))
+
+ // it may be necessary to sort the result of the GetValue function.
+ enumNames := listEnumNames(reg, enum)
+ defaultValue := getEnumDefault(reg, enum)
+ valueComments := enumValueProtoComments(reg, enum)
+ if valueComments != "" {
+ enumComments = strings.TrimLeft(enumComments+"\n\n "+valueComments, "\n")
+ }
+ enumSchemaObject := openapiSchemaObject{
+ schemaCore: schemaCore{
+ Type: "string",
+ Enum: enumNames,
+ Default: defaultValue,
+ },
+ }
+ if reg.GetEnumsAsInts() {
+ enumSchemaObject.Type = "integer"
+ enumSchemaObject.Format = "int32"
+ enumSchemaObject.Default = "0"
+ enumSchemaObject.Enum = listEnumNumbers(reg, enum)
+ }
+ if err := updateOpenAPIDataFromComments(reg, &enumSchemaObject, enum, enumComments, false); err != nil {
+ panic(err)
+ }
+
+ d[swgName] = enumSchemaObject
+ }
+}
+
+// Take in a FQMN or FQEN and return a OpenAPI safe version of the FQMN and
+// a boolean indicating if FQMN was properly resolved.
+func fullyQualifiedNameToOpenAPIName(fqn string, reg *descriptor.Registry) (string, bool) {
+ registriesSeenMutex.Lock()
+ defer registriesSeenMutex.Unlock()
+ if mapping, present := registriesSeen[reg]; present {
+ ret, ok := mapping[fqn]
+ return ret, ok
+ }
+ mapping := resolveFullyQualifiedNameToOpenAPINames(append(reg.GetAllFQMNs(), reg.GetAllFQENs()...), reg.GetOpenAPINamingStrategy())
+ registriesSeen[reg] = mapping
+ ret, ok := mapping[fqn]
+ return ret, ok
+}
+
+// Lookup message type by location.name and return a openapiv2-safe version
+// of its FQMN.
+func lookupMsgAndOpenAPIName(location, name string, reg *descriptor.Registry) (*descriptor.Message, string, error) {
+ msg, err := reg.LookupMsg(location, name)
+ if err != nil {
+ return nil, "", err
+ }
+ swgName, ok := fullyQualifiedNameToOpenAPIName(msg.FQMN(), reg)
+ if !ok {
+ return nil, "", fmt.Errorf("can't map OpenAPI name from FQMN '%v'", msg.FQMN())
+ }
+ return msg, swgName, nil
+}
+
+// registriesSeen is used to memoise calls to resolveFullyQualifiedNameToOpenAPINames so
+// we don't repeat it unnecessarily, since it can take some time.
+var registriesSeen = map[*descriptor.Registry]map[string]string{}
+var registriesSeenMutex sync.Mutex
+
+// Take the names of every proto message and generate a unique reference for each, according to the given strategy.
+func resolveFullyQualifiedNameToOpenAPINames(messages []string, namingStrategy string) map[string]string {
+ strategyFn := LookupNamingStrategy(namingStrategy)
+ if strategyFn == nil {
+ return nil
+ }
+ return strategyFn(messages)
+}
+
+var canRegexp = regexp.MustCompile("{([a-zA-Z][a-zA-Z0-9_.]*)([^}]*)}")
+
+// templateToParts will split a URL template as defined by https://github.com/googleapis/googleapis/blob/master/google/api/http.proto
+// into a string slice with each part as an element of the slice for use by `partsToOpenAPIPath` and `partsToRegexpMap`.
+func templateToParts(path string, reg *descriptor.Registry, fields []*descriptor.Field, msgs []*descriptor.Message) []string {
+ // It seems like the right thing to do here is to just use
+ // strings.Split(path, "/") but that breaks badly when you hit a url like
+ // /{my_field=prefix/*}/ and end up with 2 sections representing my_field.
+ // Instead do the right thing and write a small pushdown (counter) automata
+ // for it.
+ var parts []string
+ depth := 0
+ buffer := ""
+ jsonBuffer := ""
+ for _, char := range path {
+ switch char {
+ case '{':
+ // Push on the stack
+ depth++
+ buffer += string(char)
+ jsonBuffer = ""
+ jsonBuffer += string(char)
+ case '}':
+ if depth == 0 {
+ panic("Encountered } without matching { before it.")
+ }
+ // Pop from the stack
+ depth--
+ buffer += string(char)
+ if reg.GetUseJSONNamesForFields() &&
+ len(jsonBuffer) > 1 {
+ jsonSnakeCaseName := string(jsonBuffer[1:])
+ jsonCamelCaseName := string(lowerCamelCase(jsonSnakeCaseName, fields, msgs))
+ prev := string(buffer[:len(buffer)-len(jsonSnakeCaseName)-2])
+ buffer = strings.Join([]string{prev, "{", jsonCamelCaseName, "}"}, "")
+ jsonBuffer = ""
+ }
+ case '/':
+ if depth == 0 {
+ parts = append(parts, buffer)
+ buffer = ""
+ // Since the stack was empty when we hit the '/' we are done with this
+ // section.
+ continue
+ }
+ buffer += string(char)
+ jsonBuffer += string(char)
+ default:
+ buffer += string(char)
+ jsonBuffer += string(char)
+ }
+ }
+
+ // Now append the last element to parts
+ parts = append(parts, buffer)
+
+ return parts
+}
+
+// partsToOpenAPIPath converts each path part of the form /path/{string_value=strprefix/*} which is defined in
+// https://github.com/googleapis/googleapis/blob/master/google/api/http.proto to the OpenAPI expected form /path/{string_value}.
+// For example this would replace the path segment of "{foo=bar/*}" with "{foo}" or "prefix{bang=bash/**}" with "prefix{bang}".
+// OpenAPI 2 only allows simple path parameters with the constraints on that parameter specified in the OpenAPI
+// schema's "pattern" instead of in the path parameter itself.
+func partsToOpenAPIPath(parts []string) string {
+ for index, part := range parts {
+ parts[index] = canRegexp.ReplaceAllString(part, "{$1}")
+ }
+ return strings.Join(parts, "/")
+}
+
+// partsToRegexpMap returns a map of parameter name to ECMA 262 patterns
+// which is what the "pattern" field on an OpenAPI parameter expects.
+// See https://swagger.io/specification/v2/ (Parameter Object) and
+// https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.2.3.
+// The expression is generated based on expressions defined by https://github.com/googleapis/googleapis/blob/master/google/api/http.proto
+// "Path Template Syntax" section which allow for a "param_name=foobar/*/bang/**" style expressions inside
+// the path parameter placeholders that indicate constraints on the values of those parameters.
+// This function will scan the split parts of a path template for parameters and
+// outputs a map of the name of the parameter to a ECMA regular expression. See the http.proto file for descriptions
+// of the supported syntax. This function will ignore any path parameters that don't contain a "=" after the
+// parameter name. For supported parameters, we assume "*" represent all characters except "/" as it's
+// intended to match a single path element and we assume "**" matches any character as it's intended to match multiple
+// path elements.
+// For example "{name=organizations/*/roles/*}" would produce the regular expression for the "name" parameter of
+// "organizations/[^/]+/roles/[^/]+" or "{bar=bing/*/bang/**}" would produce the regular expression for the "bar"
+// parameter of "bing/[^/]+/bang/.+".
+func partsToRegexpMap(parts []string) map[string]string {
+ regExps := make(map[string]string)
+ for _, part := range parts {
+ if submatch := canRegexp.FindStringSubmatch(part); len(submatch) > 2 {
+ if strings.HasPrefix(submatch[2], "=") { // this part matches the standard and should be made into a regular expression
+ // assume the string's characters other than "**" and "*" are literals (not necessarily a good assumption 100% of the times, but it will support most use cases)
+ regex := submatch[2][1:]
+ regex = strings.ReplaceAll(regex, "**", ".+") // ** implies any character including "/"
+ regex = strings.ReplaceAll(regex, "*", "[^/]+") // * implies any character except "/"
+ regExps[submatch[1]] = regex
+ }
+ }
+ }
+ return regExps
+}
+
+func renderServiceTags(services []*descriptor.Service, reg *descriptor.Registry) []openapiTagObject {
+ var tags []openapiTagObject
+ for _, svc := range services {
+ if !isVisible(getServiceVisibilityOption(svc), reg) {
+ continue
+ }
+ tagName := svc.GetName()
+ if pkg := svc.File.GetPackage(); pkg != "" && reg.IsIncludePackageInTags() {
+ tagName = pkg + "." + tagName
+ }
+
+ tag := openapiTagObject{
+ Name: tagName,
+ }
+ if proto.HasExtension(svc.Options, openapi_options.E_Openapiv2Tag) {
+ ext := proto.GetExtension(svc.Options, openapi_options.E_Openapiv2Tag)
+ opts, ok := ext.(*openapi_options.Tag)
+ if !ok {
+ glog.Errorf("extension is %T; want an OpenAPI Tag object", ext)
+ return nil
+ }
+
+ tag.Description = opts.Description
+ if opts.ExternalDocs != nil {
+ tag.ExternalDocs = &openapiExternalDocumentationObject{
+ Description: opts.ExternalDocs.Description,
+ URL: opts.ExternalDocs.Url,
+ }
+ }
+ }
+ tags = append(tags, tag)
+ }
+ return tags
+}
+
+func renderServices(services []*descriptor.Service, paths openapiPathsObject, reg *descriptor.Registry, requestResponseRefs, customRefs refMap, msgs []*descriptor.Message) error {
+ // Correctness of svcIdx and methIdx depends on 'services' containing the services in the same order as the 'file.Service' array.
+ svcBaseIdx := 0
+ var lastFile *descriptor.File = nil
+ for svcIdx, svc := range services {
+ if svc.File != lastFile {
+ lastFile = svc.File
+ svcBaseIdx = svcIdx
+ }
+
+ if !isVisible(getServiceVisibilityOption(svc), reg) {
+ continue
+ }
+
+ for methIdx, meth := range svc.Methods {
+ if !isVisible(getMethodVisibilityOption(meth), reg) {
+ continue
+ }
+
+ for bIdx, b := range meth.Bindings {
+ operationFunc := operationForMethod(b.HTTPMethod)
+ // Iterate over all the OpenAPI parameters
+ parameters := openapiParametersObject{}
+ // split the path template into its parts
+ parts := templateToParts(b.PathTmpl.Template, reg, meth.RequestType.Fields, msgs)
+ // extract any constraints specified in the path placeholders into ECMA regular expressions
+ pathParamRegexpMap := partsToRegexpMap(parts)
+ for _, parameter := range b.PathParams {
+
+ var paramType, paramFormat, desc, collectionFormat, defaultValue string
+ var enumNames []string
+ var items *openapiItemsObject
+ var minItems *int
+ switch pt := parameter.Target.GetType(); pt {
+ case descriptorpb.FieldDescriptorProto_TYPE_GROUP, descriptorpb.FieldDescriptorProto_TYPE_MESSAGE:
+ if descriptor.IsWellKnownType(parameter.Target.GetTypeName()) {
+ if parameter.IsRepeated() {
+ return fmt.Errorf("only primitive and enum types are allowed in repeated path parameters")
+ }
+ schema := schemaOfField(parameter.Target, reg, customRefs)
+ paramType = schema.Type
+ paramFormat = schema.Format
+ desc = schema.Description
+ defaultValue = schema.Default
+ } else {
+ return fmt.Errorf("only primitive and well-known types are allowed in path parameters")
+ }
+ case descriptorpb.FieldDescriptorProto_TYPE_ENUM:
+ enum, err := reg.LookupEnum("", parameter.Target.GetTypeName())
+ if err != nil {
+ return err
+ }
+ paramType = "string"
+ paramFormat = ""
+ enumNames = listEnumNames(reg, enum)
+ if reg.GetEnumsAsInts() {
+ paramType = "integer"
+ paramFormat = ""
+ enumNames = listEnumNumbers(reg, enum)
+ }
+ schema := schemaOfField(parameter.Target, reg, customRefs)
+ desc = schema.Description
+ defaultValue = schema.Default
+ default:
+ var ok bool
+ paramType, paramFormat, ok = primitiveSchema(pt)
+ if !ok {
+ return fmt.Errorf("unknown field type %v", pt)
+ }
+
+ schema := schemaOfField(parameter.Target, reg, customRefs)
+ desc = schema.Description
+ defaultValue = schema.Default
+ }
+
+ if parameter.IsRepeated() {
+ core := schemaCore{Type: paramType, Format: paramFormat}
+ if parameter.IsEnum() {
+ var s []string
+ core.Enum = enumNames
+ enumNames = s
+ }
+ items = (*openapiItemsObject)(&core)
+ paramType = "array"
+ paramFormat = ""
+ collectionFormat = reg.GetRepeatedPathParamSeparatorName()
+ minItems = new(int)
+ *minItems = 1
+ }
+
+ if desc == "" {
+ desc = fieldProtoComments(reg, parameter.Target.Message, parameter.Target)
+ }
+ parameterString := parameter.String()
+ if reg.GetUseJSONNamesForFields() {
+ parameterString = lowerCamelCase(parameterString, meth.RequestType.Fields, msgs)
+ }
+ var pattern string
+ if regExp, ok := pathParamRegexpMap[parameterString]; ok {
+ pattern = regExp
+ }
+ parameters = append(parameters, openapiParameterObject{
+ Name: parameterString,
+ Description: desc,
+ In: "path",
+ Required: true,
+ Default: defaultValue,
+ // Parameters in gRPC-Gateway can only be strings?
+ Type: paramType,
+ Format: paramFormat,
+ Enum: enumNames,
+ Items: items,
+ CollectionFormat: collectionFormat,
+ MinItems: minItems,
+ Pattern: pattern,
+ })
+ }
+ // Now check if there is a body parameter
+ if b.Body != nil {
+ // Recursively render fields as definitions as long as they contain path parameters.
+ // Special case for top level body if we don't have a body field.
+ var schema openapiSchemaObject
+ desc := ""
+ var bodyFieldName string
+ schema = openapiSchemaObject{
+ schemaCore: schemaCore{},
+ }
+ if len(b.Body.FieldPath) == 0 {
+ // No field for body, use type.
+ bodyFieldName = "body"
+ wknSchemaCore, isWkn := wktSchemas[meth.RequestType.FQMN()]
+ if isWkn {
+ schema.schemaCore = wknSchemaCore
+ // Special workaround for Empty: it's well-known type but wknSchemas only returns schema.schemaCore; but we need to set schema.Properties which is a level higher.
+ if meth.RequestType.FQMN() == ".google.protobuf.Empty" {
+ schema.Properties = &openapiSchemaObjectProperties{}
+ }
+ } else {
+ if len(b.PathParams) == 0 {
+ err := schema.setRefFromFQN(meth.RequestType.FQMN(), reg)
+ if err != nil {
+ return err
+ }
+ } else {
+ var err error
+ schema, err = renderMessageAsDefinition(meth.RequestType, reg, customRefs, b.PathParams)
+ if err != nil {
+ return err
+ }
+ if schema.Properties == nil || len(*schema.Properties) == 0 {
+ glog.Warningf("created a body with 0 properties in the message, this might be unintended: %s", *meth.RequestType)
+ }
+ }
+ }
+ } else {
+ // Body field path is limited to one path component. From google.api.HttpRule.body:
+ // "NOTE: the referred field must be present at the top-level of the request message type."
+ // Ref: https://github.com/googleapis/googleapis/blob/b3397f5febbf21dfc69b875ddabaf76bee765058/google/api/http.proto#L350-L352
+ if len(b.Body.FieldPath) > 1 {
+ return fmt.Errorf("Body of request '%s' is not a top level field: '%v'.", meth.Service.GetName(), b.Body.FieldPath)
+ }
+ bodyField := b.Body.FieldPath[0]
+ if reg.GetUseJSONNamesForFields() {
+ bodyFieldName = lowerCamelCase(bodyField.Name, meth.RequestType.Fields, msgs)
+ } else {
+ bodyFieldName = bodyField.Name
+ }
+ // Align pathParams with body field path.
+ pathParams := subPathParams(bodyFieldName, b.PathParams)
+ var err error
+ schema, err = renderFieldAsDefinition(bodyField.Target, reg, customRefs, pathParams)
+ if err != nil {
+ return err
+ }
+ if schema.Title != "" {
+ desc = mergeDescription(schema)
+ } else {
+ desc = fieldProtoComments(reg, bodyField.Target.Message, bodyField.Target)
+ }
+ }
+
+ if meth.GetClientStreaming() {
+ desc += " (streaming inputs)"
+ }
+ parameters = append(parameters, openapiParameterObject{
+ Name: bodyFieldName,
+ Description: desc,
+ In: "body",
+ Required: true,
+ Schema: &schema,
+ })
+ }
+
+ // add the parameters to the query string
+ queryParams, err := messageToQueryParameters(meth.RequestType, reg, b.PathParams, b.Body)
+ if err != nil {
+ return err
+ }
+ parameters = append(parameters, queryParams...)
+
+ path := partsToOpenAPIPath(parts)
+ pathItemObject, ok := paths[path]
+ if !ok {
+ pathItemObject = openapiPathItemObject{}
+ } else {
+ // handle case where we have an existing mapping for the same path and method
+ existingOperationObject := operationFunc(&pathItemObject)
+ if existingOperationObject != nil {
+ var firstPathParameter *openapiParameterObject
+ var firstParamIndex int
+ for index, param := range parameters {
+ if param.In == "path" {
+ firstPathParameter = ¶m
+ firstParamIndex = index
+ break
+ }
+ }
+ if firstPathParameter == nil {
+ // Without a path parameter, there is nothing to vary to support multiple mappings of the same path/method.
+ // Previously this did not log an error and only overwrote the mapping, we now log the error but
+ // still overwrite the mapping
+ glog.Errorf("Duplicate mapping for path %s %s", b.HTTPMethod, path)
+ } else {
+ newPathCount := 0
+ var newPath string
+ var newPathElement string
+ // Iterate until there is not an existing operation that matches the same escaped path.
+ // Most of the time this will only be a single iteration, but a large API could technically have
+ // a pretty large amount of these if it used similar patterns for all its functions.
+ for existingOperationObject != nil {
+ newPathCount += 1
+ newPathElement = firstPathParameter.Name + pathParamUniqueSuffixDeliminator + strconv.Itoa(newPathCount)
+ newPath = strings.ReplaceAll(path, "{"+firstPathParameter.Name+"}", "{"+newPathElement+"}")
+ if newPathItemObject, ok := paths[newPath]; ok {
+ existingOperationObject = operationFunc(&newPathItemObject)
+ } else {
+ existingOperationObject = nil
+ }
+ }
+ // update the pathItemObject we are adding to with the new path
+ pathItemObject = paths[newPath]
+ firstPathParameter.Name = newPathElement
+ path = newPath
+ parameters[firstParamIndex] = *firstPathParameter
+ }
+ }
+ }
+
+ methProtoPath := protoPathIndex(reflect.TypeOf((*descriptorpb.ServiceDescriptorProto)(nil)), "Method")
+ desc := "A successful response."
+ var responseSchema openapiSchemaObject
+
+ if b.ResponseBody == nil || len(b.ResponseBody.FieldPath) == 0 {
+ responseSchema = openapiSchemaObject{
+ schemaCore: schemaCore{},
+ }
+
+ // Don't link to a full definition for
+ // empty; it's overly verbose.
+ // schema.Properties{} renders it as
+ // well, without a definition
+ wknSchemaCore, isWkn := wktSchemas[meth.ResponseType.FQMN()]
+ if !isWkn {
+ err := responseSchema.setRefFromFQN(meth.ResponseType.FQMN(), reg)
+ if err != nil {
+ return err
+ }
+ } else {
+ responseSchema.schemaCore = wknSchemaCore
+
+ // Special workaround for Empty: it's well-known type but wknSchemas only returns schema.schemaCore; but we need to set schema.Properties which is a level higher.
+ if meth.ResponseType.FQMN() == ".google.protobuf.Empty" {
+ responseSchema.Properties = &openapiSchemaObjectProperties{}
+ }
+ }
+ } else {
+ // This is resolving the value of response_body in the google.api.HttpRule
+ lastField := b.ResponseBody.FieldPath[len(b.ResponseBody.FieldPath)-1]
+ responseSchema = schemaOfField(lastField.Target, reg, customRefs)
+ if responseSchema.Description != "" {
+ desc = responseSchema.Description
+ } else {
+ desc = fieldProtoComments(reg, lastField.Target.Message, lastField.Target)
+ }
+ }
+ if meth.GetServerStreaming() {
+ desc += "(streaming responses)"
+ responseSchema.Type = "object"
+ swgRef, _ := fullyQualifiedNameToOpenAPIName(meth.ResponseType.FQMN(), reg)
+ responseSchema.Title = "Stream result of " + swgRef
+
+ props := openapiSchemaObjectProperties{
+ keyVal{
+ Key: "result",
+ Value: openapiSchemaObject{
+ schemaCore: schemaCore{
+ Ref: responseSchema.Ref,
+ },
+ },
+ },
+ }
+ statusDef, hasStatus := fullyQualifiedNameToOpenAPIName(".google.rpc.Status", reg)
+ if hasStatus {
+ props = append(props, keyVal{
+ Key: "error",
+ Value: openapiSchemaObject{
+ schemaCore: schemaCore{
+ Ref: fmt.Sprintf("#/definitions/%s", statusDef)},
+ },
+ })
+ }
+ responseSchema.Properties = &props
+ responseSchema.Ref = ""
+ }
+
+ tag := svc.GetName()
+ if pkg := svc.File.GetPackage(); pkg != "" && reg.IsIncludePackageInTags() {
+ tag = pkg + "." + tag
+ }
+
+ operationObject := &openapiOperationObject{
+ Tags: []string{tag},
+ Parameters: parameters,
+ Responses: openapiResponsesObject{
+ "200": openapiResponseObject{
+ Description: desc,
+ Schema: responseSchema,
+ Headers: openapiHeadersObject{},
+ },
+ },
+ }
+ if !reg.GetDisableDefaultErrors() {
+ errDef, hasErrDef := fullyQualifiedNameToOpenAPIName(".google.rpc.Status", reg)
+ if hasErrDef {
+ // https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#responses-object
+ operationObject.Responses["default"] = openapiResponseObject{
+ Description: "An unexpected error response.",
+ Schema: openapiSchemaObject{
+ schemaCore: schemaCore{
+ Ref: fmt.Sprintf("#/definitions/%s", errDef),
+ },
+ },
+ }
+ }
+ }
+ operationObject.OperationID = fmt.Sprintf("%s_%s", svc.GetName(), meth.GetName())
+ if reg.GetSimpleOperationIDs() {
+ operationObject.OperationID = meth.GetName()
+ }
+ if bIdx != 0 {
+ // OperationID must be unique in an OpenAPI v2 definition.
+ operationObject.OperationID += strconv.Itoa(bIdx + 1)
+ }
+
+ // Fill reference map with referenced request messages
+ for _, param := range operationObject.Parameters {
+ if param.Schema != nil && param.Schema.Ref != "" {
+ requestResponseRefs[param.Schema.Ref] = struct{}{}
+ }
+ }
+
+ methComments := protoComments(reg, svc.File, nil, "Service", int32(svcIdx-svcBaseIdx), methProtoPath, int32(methIdx))
+ if err := updateOpenAPIDataFromComments(reg, operationObject, meth, methComments, false); err != nil {
+ panic(err)
+ }
+
+ opts, err := getMethodOpenAPIOption(reg, meth)
+ if opts != nil {
+ if err != nil {
+ panic(err)
+ }
+ operationObject.ExternalDocs = protoExternalDocumentationToOpenAPIExternalDocumentation(opts.ExternalDocs, reg, meth)
+ // TODO(ivucica): this would be better supported by looking whether the method is deprecated in the proto file
+ operationObject.Deprecated = opts.Deprecated
+
+ if opts.Summary != "" {
+ operationObject.Summary = opts.Summary
+ }
+ if opts.Description != "" {
+ operationObject.Description = opts.Description
+ }
+ if len(opts.Tags) > 0 {
+ operationObject.Tags = make([]string, len(opts.Tags))
+ copy(operationObject.Tags, opts.Tags)
+ }
+ if opts.OperationId != "" {
+ operationObject.OperationID = opts.OperationId
+ }
+ if opts.Security != nil {
+ newSecurity := []openapiSecurityRequirementObject{}
+ if operationObject.Security != nil {
+ newSecurity = *operationObject.Security
+ }
+ for _, secReq := range opts.Security {
+ newSecReq := openapiSecurityRequirementObject{}
+ for secReqKey, secReqValue := range secReq.SecurityRequirement {
+ if secReqValue == nil {
+ continue
+ }
+
+ newSecReqValue := make([]string, len(secReqValue.Scope))
+ copy(newSecReqValue, secReqValue.Scope)
+ newSecReq[secReqKey] = newSecReqValue
+ }
+
+ if len(newSecReq) > 0 {
+ newSecurity = append(newSecurity, newSecReq)
+ }
+ }
+ operationObject.Security = &newSecurity
+ }
+ if opts.Responses != nil {
+ for name, resp := range opts.Responses {
+ // Merge response data into default response if available.
+ respObj := operationObject.Responses[name]
+ if resp.Description != "" {
+ respObj.Description = resp.Description
+ }
+ if resp.Schema != nil {
+ respObj.Schema = openapiSchemaFromProtoSchema(resp.Schema, reg, customRefs, meth)
+ }
+ if resp.Examples != nil {
+ respObj.Examples = openapiExamplesFromProtoExamples(resp.Examples)
+ }
+ if resp.Headers != nil {
+ hdrs, err := processHeaders(resp.Headers)
+ if err != nil {
+ return err
+ }
+ respObj.Headers = hdrs
+ }
+ if resp.Extensions != nil {
+ exts, err := processExtensions(resp.Extensions)
+ if err != nil {
+ return err
+ }
+ respObj.extensions = exts
+ }
+ operationObject.Responses[name] = respObj
+ }
+ }
+
+ if opts.Extensions != nil {
+ exts, err := processExtensions(opts.Extensions)
+ if err != nil {
+ return err
+ }
+ operationObject.extensions = exts
+ }
+
+ if len(opts.Produces) > 0 {
+ operationObject.Produces = make([]string, len(opts.Produces))
+ copy(operationObject.Produces, opts.Produces)
+ }
+
+ // TODO(ivucica): add remaining fields of operation object
+ }
+
+ switch b.HTTPMethod {
+ case "DELETE":
+ pathItemObject.Delete = operationObject
+ case "GET":
+ pathItemObject.Get = operationObject
+ case "POST":
+ pathItemObject.Post = operationObject
+ case "PUT":
+ pathItemObject.Put = operationObject
+ case "PATCH":
+ pathItemObject.Patch = operationObject
+ }
+ paths[path] = pathItemObject
+ }
+ }
+ }
+
+ // Success! return nil on the error object
+ return nil
+}
+
+func mergeDescription(schema openapiSchemaObject) string {
+ desc := schema.Description
+ if schema.Title != "" { // join title because title of parameter object will be ignored
+ desc = strings.TrimSpace(schema.Title + paragraphDeliminator + schema.Description)
+ }
+ return desc
+}
+
+func operationForMethod(httpMethod string) func(*openapiPathItemObject) *openapiOperationObject {
+ switch httpMethod {
+ case "GET":
+ return func(obj *openapiPathItemObject) *openapiOperationObject { return obj.Get }
+ case "POST":
+ return func(obj *openapiPathItemObject) *openapiOperationObject { return obj.Post }
+ case "PUT":
+ return func(obj *openapiPathItemObject) *openapiOperationObject { return obj.Put }
+ case "DELETE":
+ return func(obj *openapiPathItemObject) *openapiOperationObject { return obj.Delete }
+ case "PATCH":
+ return func(obj *openapiPathItemObject) *openapiOperationObject { return obj.Patch }
+ default:
+ return nil
+ }
+}
+
+// This function is called with a param which contains the entire definition of a method.
+func applyTemplate(p param) (*openapiSwaggerObject, error) {
+ // Create the basic template object. This is the object that everything is
+ // defined off of.
+ s := openapiSwaggerObject{
+ // OpenAPI 2.0 is the version of this document
+ Swagger: "2.0",
+ Consumes: []string{"application/json"},
+ Produces: []string{"application/json"},
+ Paths: make(openapiPathsObject),
+ Definitions: make(openapiDefinitionsObject),
+ Info: openapiInfoObject{
+ Title: *p.File.Name,
+ Version: "version not set",
+ },
+ }
+
+ // Loops through all the services and their exposed GET/POST/PUT/DELETE definitions
+ // and create entries for all of them.
+ // Also adds custom user specified references to second map.
+ requestResponseRefs, customRefs := refMap{}, refMap{}
+ if err := renderServices(p.Services, s.Paths, p.reg, requestResponseRefs, customRefs, p.Messages); err != nil {
+ panic(err)
+ }
+ s.Tags = append(s.Tags, renderServiceTags(p.Services, p.reg)...)
+
+ messages := messageMap{}
+ streamingMessages := messageMap{}
+ enums := enumMap{}
+
+ if !p.reg.GetDisableDefaultErrors() {
+ // Add the error type to the message map
+ runtimeError, swgRef, err := lookupMsgAndOpenAPIName("google.rpc", "Status", p.reg)
+ if err == nil {
+ messages[swgRef] = runtimeError
+ } else {
+ // just in case there is an error looking up runtimeError
+ glog.Error(err)
+ }
+ }
+
+ // Find all the service's messages and enumerations that are defined (recursively)
+ // and write request, response and other custom (but referenced) types out as definition objects.
+ findServicesMessagesAndEnumerations(p.Services, p.reg, messages, streamingMessages, enums, requestResponseRefs)
+ if err := renderMessagesAsDefinition(messages, s.Definitions, p.reg, customRefs, nil); err != nil {
+ return nil, err
+ }
+ renderEnumerationsAsDefinition(enums, s.Definitions, p.reg)
+
+ // File itself might have some comments and metadata.
+ packageProtoPath := protoPathIndex(reflect.TypeOf((*descriptorpb.FileDescriptorProto)(nil)), "Package")
+ packageComments := protoComments(p.reg, p.File, nil, "Package", packageProtoPath)
+ if err := updateOpenAPIDataFromComments(p.reg, &s, p, packageComments, true); err != nil {
+ return nil, err
+ }
+
+ // There may be additional options in the OpenAPI option in the proto.
+ spb, err := getFileOpenAPIOption(p.reg, p.File)
+ if err != nil {
+ return nil, err
+ }
+ if spb != nil {
+ if spb.Swagger != "" {
+ s.Swagger = spb.Swagger
+ }
+ if spb.Info != nil {
+ if spb.Info.Title != "" {
+ s.Info.Title = spb.Info.Title
+ }
+ if spb.Info.Description != "" {
+ s.Info.Description = spb.Info.Description
+ }
+ if spb.Info.TermsOfService != "" {
+ s.Info.TermsOfService = spb.Info.TermsOfService
+ }
+ if spb.Info.Version != "" {
+ s.Info.Version = spb.Info.Version
+ }
+ if spb.Info.Contact != nil {
+ if s.Info.Contact == nil {
+ s.Info.Contact = &openapiContactObject{}
+ }
+ if spb.Info.Contact.Name != "" {
+ s.Info.Contact.Name = spb.Info.Contact.Name
+ }
+ if spb.Info.Contact.Url != "" {
+ s.Info.Contact.URL = spb.Info.Contact.Url
+ }
+ if spb.Info.Contact.Email != "" {
+ s.Info.Contact.Email = spb.Info.Contact.Email
+ }
+ }
+ if spb.Info.License != nil {
+ if s.Info.License == nil {
+ s.Info.License = &openapiLicenseObject{}
+ }
+ if spb.Info.License.Name != "" {
+ s.Info.License.Name = spb.Info.License.Name
+ }
+ if spb.Info.License.Url != "" {
+ s.Info.License.URL = spb.Info.License.Url
+ }
+ }
+ if spb.Info.Extensions != nil {
+ exts, err := processExtensions(spb.Info.Extensions)
+ if err != nil {
+ return nil, err
+ }
+ s.Info.extensions = exts
+ }
+ }
+ if spb.Host != "" {
+ s.Host = spb.Host
+ }
+ if spb.BasePath != "" {
+ s.BasePath = spb.BasePath
+ }
+ if len(spb.Schemes) > 0 {
+ s.Schemes = make([]string, len(spb.Schemes))
+ for i, scheme := range spb.Schemes {
+ s.Schemes[i] = strings.ToLower(scheme.String())
+ }
+ }
+ if len(spb.Consumes) > 0 {
+ s.Consumes = make([]string, len(spb.Consumes))
+ copy(s.Consumes, spb.Consumes)
+ }
+ if len(spb.Produces) > 0 {
+ s.Produces = make([]string, len(spb.Produces))
+ copy(s.Produces, spb.Produces)
+ }
+ if spb.SecurityDefinitions != nil && spb.SecurityDefinitions.Security != nil {
+ if s.SecurityDefinitions == nil {
+ s.SecurityDefinitions = openapiSecurityDefinitionsObject{}
+ }
+ for secDefKey, secDefValue := range spb.SecurityDefinitions.Security {
+ var newSecDefValue openapiSecuritySchemeObject
+ if oldSecDefValue, ok := s.SecurityDefinitions[secDefKey]; !ok {
+ newSecDefValue = openapiSecuritySchemeObject{}
+ } else {
+ newSecDefValue = oldSecDefValue
+ }
+ if secDefValue.Type != openapi_options.SecurityScheme_TYPE_INVALID {
+ switch secDefValue.Type {
+ case openapi_options.SecurityScheme_TYPE_BASIC:
+ newSecDefValue.Type = "basic"
+ case openapi_options.SecurityScheme_TYPE_API_KEY:
+ newSecDefValue.Type = "apiKey"
+ case openapi_options.SecurityScheme_TYPE_OAUTH2:
+ newSecDefValue.Type = "oauth2"
+ }
+ }
+ if secDefValue.Description != "" {
+ newSecDefValue.Description = secDefValue.Description
+ }
+ if secDefValue.Name != "" {
+ newSecDefValue.Name = secDefValue.Name
+ }
+ if secDefValue.In != openapi_options.SecurityScheme_IN_INVALID {
+ switch secDefValue.In {
+ case openapi_options.SecurityScheme_IN_QUERY:
+ newSecDefValue.In = "query"
+ case openapi_options.SecurityScheme_IN_HEADER:
+ newSecDefValue.In = "header"
+ }
+ }
+ if secDefValue.Flow != openapi_options.SecurityScheme_FLOW_INVALID {
+ switch secDefValue.Flow {
+ case openapi_options.SecurityScheme_FLOW_IMPLICIT:
+ newSecDefValue.Flow = "implicit"
+ case openapi_options.SecurityScheme_FLOW_PASSWORD:
+ newSecDefValue.Flow = "password"
+ case openapi_options.SecurityScheme_FLOW_APPLICATION:
+ newSecDefValue.Flow = "application"
+ case openapi_options.SecurityScheme_FLOW_ACCESS_CODE:
+ newSecDefValue.Flow = "accessCode"
+ }
+ }
+ if secDefValue.AuthorizationUrl != "" {
+ newSecDefValue.AuthorizationURL = secDefValue.AuthorizationUrl
+ }
+ if secDefValue.TokenUrl != "" {
+ newSecDefValue.TokenURL = secDefValue.TokenUrl
+ }
+ if secDefValue.Scopes != nil {
+ if newSecDefValue.Scopes == nil {
+ newSecDefValue.Scopes = openapiScopesObject{}
+ }
+ for scopeKey, scopeDesc := range secDefValue.Scopes.Scope {
+ newSecDefValue.Scopes[scopeKey] = scopeDesc
+ }
+ }
+ if secDefValue.Extensions != nil {
+ exts, err := processExtensions(secDefValue.Extensions)
+ if err != nil {
+ return nil, err
+ }
+ newSecDefValue.extensions = exts
+ }
+ s.SecurityDefinitions[secDefKey] = newSecDefValue
+ }
+ }
+ if spb.Security != nil {
+ var newSecurity []openapiSecurityRequirementObject
+ if s.Security != nil {
+ newSecurity = s.Security
+ }
+ for _, secReq := range spb.Security {
+ newSecReq := openapiSecurityRequirementObject{}
+ for secReqKey, secReqValue := range secReq.SecurityRequirement {
+ if secReqValue == nil {
+ return nil, fmt.Errorf("malformed security requirement spec for key %q; value is required", secReqKey)
+ }
+ newSecReqValue := make([]string, len(secReqValue.Scope))
+ copy(newSecReqValue, secReqValue.Scope)
+ newSecReq[secReqKey] = newSecReqValue
+ }
+ newSecurity = append(newSecurity, newSecReq)
+ }
+ s.Security = newSecurity
+ }
+ s.ExternalDocs = protoExternalDocumentationToOpenAPIExternalDocumentation(spb.ExternalDocs, p.reg, spb)
+ // Populate all Paths with Responses set at top level,
+ // preferring Responses already set over those at the top level.
+ if spb.Responses != nil {
+ for _, verbs := range s.Paths {
+ var maps []openapiResponsesObject
+ if verbs.Delete != nil {
+ maps = append(maps, verbs.Delete.Responses)
+ }
+ if verbs.Get != nil {
+ maps = append(maps, verbs.Get.Responses)
+ }
+ if verbs.Post != nil {
+ maps = append(maps, verbs.Post.Responses)
+ }
+ if verbs.Put != nil {
+ maps = append(maps, verbs.Put.Responses)
+ }
+ if verbs.Patch != nil {
+ maps = append(maps, verbs.Patch.Responses)
+ }
+
+ for k, v := range spb.Responses {
+ for _, respMap := range maps {
+ if _, ok := respMap[k]; ok {
+ // Don't overwrite already existing Responses
+ continue
+ }
+ respMap[k] = openapiResponseObject{
+ Description: v.Description,
+ Schema: openapiSchemaFromProtoSchema(v.Schema, p.reg, customRefs, nil),
+ Examples: openapiExamplesFromProtoExamples(v.Examples),
+ }
+ }
+ }
+ }
+ }
+
+ if spb.Extensions != nil {
+ exts, err := processExtensions(spb.Extensions)
+ if err != nil {
+ return nil, err
+ }
+ s.extensions = exts
+ }
+
+ // Additional fields on the OpenAPI v2 spec's "OpenAPI" object
+ // should be added here, once supported in the proto.
+ }
+
+ // Finally add any references added by users that aren't
+ // otherwise rendered.
+ if err := addCustomRefs(s.Definitions, p.reg, customRefs); err != nil {
+ return nil, err
+ }
+
+ return &s, nil
+}
+
+func processExtensions(inputExts map[string]*structpb.Value) ([]extension, error) {
+ exts := []extension{}
+ for k, v := range inputExts {
+ if !strings.HasPrefix(k, "x-") {
+ return nil, fmt.Errorf("extension keys need to start with \"x-\": %q", k)
+ }
+ ext, err := (&protojson.MarshalOptions{Indent: " "}).Marshal(v)
+ if err != nil {
+ return nil, err
+ }
+ exts = append(exts, extension{key: k, value: json.RawMessage(ext)})
+ }
+ sort.Slice(exts, func(i, j int) bool { return exts[i].key < exts[j].key })
+ return exts, nil
+}
+
+func validateHeaderTypeAndFormat(headerType string, format string) error {
+ // The type of the object. The value MUST be one of "string", "number", "integer", "boolean", or "array"
+ // See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#headerObject
+ // Note: currently not implementing array as we are only implementing this in the operation response context
+ switch headerType {
+ // the format property is an open string-valued property, and can have any value to support documentation needs
+ // primary check for format is to ensure that the number/integer formats are extensions of the specified type
+ // See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#dataTypeFormat
+ case "string":
+ return nil
+ case "number":
+ switch format {
+ case "uint",
+ "uint8",
+ "uint16",
+ "uint32",
+ "uint64",
+ "int",
+ "int8",
+ "int16",
+ "int32",
+ "int64",
+ "float",
+ "float32",
+ "float64",
+ "complex64",
+ "complex128",
+ "double",
+ "byte",
+ "rune",
+ "uintptr",
+ "":
+ return nil
+ default:
+ return fmt.Errorf("the provided format %q is not a valid extension of the type %q", format, headerType)
+ }
+ case "integer":
+ switch format {
+ case "uint",
+ "uint8",
+ "uint16",
+ "uint32",
+ "uint64",
+ "int",
+ "int8",
+ "int16",
+ "int32",
+ "int64",
+ "":
+ return nil
+ default:
+ return fmt.Errorf("the provided format %q is not a valid extension of the type %q", format, headerType)
+ }
+ case "boolean":
+ return nil
+ }
+ return fmt.Errorf("the provided header type %q is not supported", headerType)
+}
+
+func validateDefaultValueTypeAndFormat(headerType string, defaultValue string, format string) error {
+ switch headerType {
+ case "string":
+ if !isQuotedString(defaultValue) {
+ return fmt.Errorf("the provided default value %q does not match provider type %q, or is not properly quoted with escaped quotations", defaultValue, headerType)
+ }
+ switch format {
+ case "date-time":
+ unquoteTime := strings.Trim(defaultValue, `"`)
+ _, err := time.Parse(time.RFC3339, unquoteTime)
+ if err != nil {
+ return fmt.Errorf("the provided default value %q is not a valid RFC3339 date-time string", defaultValue)
+ }
+ case "date":
+ const (
+ layoutRFC3339Date = "2006-01-02"
+ )
+ unquoteDate := strings.Trim(defaultValue, `"`)
+ _, err := time.Parse(layoutRFC3339Date, unquoteDate)
+ if err != nil {
+ return fmt.Errorf("the provided default value %q is not a valid RFC3339 date-time string", defaultValue)
+ }
+ }
+ case "number":
+ err := isJSONNumber(defaultValue, headerType)
+ if err != nil {
+ return err
+ }
+ case "integer":
+ switch format {
+ case "int32":
+ _, err := strconv.ParseInt(defaultValue, 0, 32)
+ if err != nil {
+ return fmt.Errorf("the provided default value %q does not match provided format %q", defaultValue, format)
+ }
+ case "uint32":
+ _, err := strconv.ParseUint(defaultValue, 0, 32)
+ if err != nil {
+ return fmt.Errorf("the provided default value %q does not match provided format %q", defaultValue, format)
+ }
+ case "int64":
+ _, err := strconv.ParseInt(defaultValue, 0, 64)
+ if err != nil {
+ return fmt.Errorf("the provided default value %q does not match provided format %q", defaultValue, format)
+ }
+ case "uint64":
+ _, err := strconv.ParseUint(defaultValue, 0, 64)
+ if err != nil {
+ return fmt.Errorf("the provided default value %q does not match provided format %q", defaultValue, format)
+ }
+ default:
+ _, err := strconv.ParseInt(defaultValue, 0, 64)
+ if err != nil {
+ return fmt.Errorf("the provided default value %q does not match provided type %q", defaultValue, headerType)
+ }
+ }
+ case "boolean":
+ if !isBool(defaultValue) {
+ return fmt.Errorf("the provided default value %q does not match provider type %q", defaultValue, headerType)
+ }
+ }
+ return nil
+}
+
+func isQuotedString(s string) bool {
+ return len(s) >= 2 && s[0] == '"' && s[len(s)-1] == '"'
+}
+
+func isJSONNumber(s string, t string) error {
+ val, err := strconv.ParseFloat(s, 64)
+ if err != nil {
+ return fmt.Errorf("the provided default value %q does not match provider type %q", s, t)
+ }
+ // Floating point values that cannot be represented as sequences of digits (such as Infinity and NaN) are not permitted.
+ // See: https://tools.ietf.org/html/rfc4627#section-2.4
+ if math.IsInf(val, 0) || math.IsNaN(val) {
+ return fmt.Errorf("the provided number %q is not a valid JSON number", s)
+ }
+
+ return nil
+}
+
+func isBool(s string) bool {
+ // Unable to use strconv.ParseBool because it returns truthy values https://golang.org/pkg/strconv/#example_ParseBool
+ // per https://swagger.io/specification/v2/#data-types
+ // type: boolean represents two values: true and false. Note that truthy and falsy values such as "true", "", 0 or null are not considered boolean values.
+ return s == "true" || s == "false"
+}
+
+func processHeaders(inputHdrs map[string]*openapi_options.Header) (openapiHeadersObject, error) {
+ hdrs := map[string]openapiHeaderObject{}
+ for k, v := range inputHdrs {
+ header := textproto.CanonicalMIMEHeaderKey(k)
+ ret := openapiHeaderObject{
+ Description: v.Description,
+ Format: v.Format,
+ Pattern: v.Pattern,
+ }
+ err := validateHeaderTypeAndFormat(v.Type, v.Format)
+ if err != nil {
+ return nil, err
+ }
+ ret.Type = v.Type
+ if v.Default != "" {
+ err := validateDefaultValueTypeAndFormat(v.Type, v.Default, v.Format)
+ if err != nil {
+ return nil, err
+ }
+ ret.Default = RawExample(v.Default)
+ }
+ hdrs[header] = ret
+ }
+ return hdrs, nil
+}
+
+// updateOpenAPIDataFromComments updates a OpenAPI object based on a comment
+// from the proto file.
+//
+// First paragraph of a comment is used for summary. Remaining paragraphs of
+// a comment are used for description. If 'Summary' field is not present on
+// the passed swaggerObject, the summary and description are joined by \n\n.
+//
+// If there is a field named 'Info', its 'Summary' and 'Description' fields
+// will be updated instead.
+//
+// If there is no 'Summary', the same behavior will be attempted on 'Title',
+// but only if the last character is not a period.
+func updateOpenAPIDataFromComments(reg *descriptor.Registry, swaggerObject interface{}, data interface{}, comment string, isPackageObject bool) error {
+ if len(comment) == 0 {
+ return nil
+ }
+
+ // Checks whether the "use_go_templates" flag is set to true
+ if reg.GetUseGoTemplate() {
+ comment = goTemplateComments(comment, data, reg)
+ }
+
+ // Figure out what to apply changes to.
+ swaggerObjectValue := reflect.ValueOf(swaggerObject)
+ infoObjectValue := swaggerObjectValue.Elem().FieldByName("Info")
+ if !infoObjectValue.CanSet() {
+ // No such field? Apply summary and description directly to
+ // passed object.
+ infoObjectValue = swaggerObjectValue.Elem()
+ }
+
+ // Figure out which properties to update.
+ summaryValue := infoObjectValue.FieldByName("Summary")
+ descriptionValue := infoObjectValue.FieldByName("Description")
+ readOnlyValue := infoObjectValue.FieldByName("ReadOnly")
+
+ if readOnlyValue.Kind() == reflect.Bool && readOnlyValue.CanSet() && strings.Contains(comment, "Output only.") {
+ readOnlyValue.Set(reflect.ValueOf(true))
+ }
+
+ usingTitle := false
+ if !summaryValue.CanSet() {
+ summaryValue = infoObjectValue.FieldByName("Title")
+ usingTitle = true
+ }
+
+ paragraphs := strings.Split(comment, paragraphDeliminator)
+
+ // If there is a summary (or summary-equivalent) and it's empty, use the first
+ // paragraph as summary, and the rest as description.
+ if summaryValue.CanSet() {
+ summary := strings.TrimSpace(paragraphs[0])
+ description := strings.TrimSpace(strings.Join(paragraphs[1:], paragraphDeliminator))
+ if !usingTitle || (len(summary) > 0 && summary[len(summary)-1] != '.') {
+ // overrides the schema value only if it's empty
+ // keep the comment precedence when updating the package definition
+ if summaryValue.Len() == 0 || isPackageObject {
+ summaryValue.Set(reflect.ValueOf(summary))
+ }
+ if len(description) > 0 {
+ if !descriptionValue.CanSet() {
+ return fmt.Errorf("encountered object type with a summary, but no description")
+ }
+ // overrides the schema value only if it's empty
+ // keep the comment precedence when updating the package definition
+ if descriptionValue.Len() == 0 || isPackageObject {
+ descriptionValue.Set(reflect.ValueOf(description))
+ }
+ }
+ return nil
+ }
+ }
+
+ // There was no summary field on the swaggerObject. Try to apply the
+ // whole comment into description if the OpenAPI object description is empty.
+ if descriptionValue.CanSet() {
+ if descriptionValue.Len() == 0 || isPackageObject {
+ descriptionValue.Set(reflect.ValueOf(strings.Join(paragraphs, paragraphDeliminator)))
+ }
+ return nil
+ }
+
+ return fmt.Errorf("no description nor summary property")
+}
+
+func fieldProtoComments(reg *descriptor.Registry, msg *descriptor.Message, field *descriptor.Field) string {
+ protoPath := protoPathIndex(reflect.TypeOf((*descriptorpb.DescriptorProto)(nil)), "Field")
+ for i, f := range msg.Fields {
+ if f == field {
+ return protoComments(reg, msg.File, msg.Outers, "MessageType", int32(msg.Index), protoPath, int32(i))
+ }
+ }
+ return ""
+}
+
+func enumValueProtoComments(reg *descriptor.Registry, enum *descriptor.Enum) string {
+ protoPath := protoPathIndex(reflect.TypeOf((*descriptorpb.EnumDescriptorProto)(nil)), "Value")
+ var comments []string
+ for idx, value := range enum.GetValue() {
+ if !isVisible(getEnumValueVisibilityOption(value), reg) {
+ continue
+ }
+ name := value.GetName()
+ if reg.GetEnumsAsInts() {
+ name = strconv.Itoa(int(value.GetNumber()))
+ }
+ str := protoComments(reg, enum.File, enum.Outers, "EnumType", int32(enum.Index), protoPath, int32(idx))
+ if str != "" {
+ comments = append(comments, name+": "+str)
+ }
+ }
+ if len(comments) > 0 {
+ return "- " + strings.Join(comments, "\n - ")
+ }
+ return ""
+}
+
+func protoComments(reg *descriptor.Registry, file *descriptor.File, outers []string, typeName string, typeIndex int32, fieldPaths ...int32) string {
+ if file.SourceCodeInfo == nil {
+ fmt.Fprintln(os.Stderr, "descriptor.File should not contain nil SourceCodeInfo")
+ return ""
+ }
+
+ outerPaths := make([]int32, len(outers))
+ for i := range outers {
+ location := ""
+ if file.Package != nil {
+ location = file.GetPackage()
+ }
+
+ msg, err := reg.LookupMsg(location, strings.Join(outers[:i+1], "."))
+ if err != nil {
+ panic(err)
+ }
+ outerPaths[i] = int32(msg.Index)
+ }
+
+ for _, loc := range file.SourceCodeInfo.Location {
+ if !isProtoPathMatches(loc.Path, outerPaths, typeName, typeIndex, fieldPaths) {
+ continue
+ }
+ comments := ""
+ if loc.LeadingComments != nil {
+ comments = strings.TrimRight(*loc.LeadingComments, "\n")
+ comments = strings.TrimSpace(comments)
+ // TODO(ivucica): this is a hack to fix "// " being interpreted as "//".
+ // perhaps we should:
+ // - split by \n
+ // - determine if every (but first and last) line begins with " "
+ // - trim every line only if that is the case
+ // - join by \n
+ comments = strings.Replace(comments, "\n ", "\n", -1)
+ }
+ return comments
+ }
+ return ""
+}
+
+func goTemplateComments(comment string, data interface{}, reg *descriptor.Registry) string {
+ var temp bytes.Buffer
+ tpl, err := template.New("").Funcs(template.FuncMap{
+ // Allows importing documentation from a file
+ "import": func(name string) string {
+ file, err := ioutil.ReadFile(name)
+ if err != nil {
+ return err.Error()
+ }
+ // Runs template over imported file
+ return goTemplateComments(string(file), data, reg)
+ },
+ // Grabs title and description from a field
+ "fieldcomments": func(msg *descriptor.Message, field *descriptor.Field) string {
+ return strings.Replace(fieldProtoComments(reg, msg, field), "\n", "
", -1)
+ },
+ }).Parse(comment)
+ if err != nil {
+ // If there is an error parsing the templating insert the error as string in the comment
+ // to make it easier to debug the template error
+ return err.Error()
+ }
+ err = tpl.Execute(&temp, data)
+ if err != nil {
+ // If there is an error executing the templating insert the error as string in the comment
+ // to make it easier to debug the error
+ return err.Error()
+ }
+ return temp.String()
+}
+
+var messageProtoPath = protoPathIndex(reflect.TypeOf((*descriptorpb.FileDescriptorProto)(nil)), "MessageType")
+var nestedProtoPath = protoPathIndex(reflect.TypeOf((*descriptorpb.DescriptorProto)(nil)), "NestedType")
+var packageProtoPath = protoPathIndex(reflect.TypeOf((*descriptorpb.FileDescriptorProto)(nil)), "Package")
+var serviceProtoPath = protoPathIndex(reflect.TypeOf((*descriptorpb.FileDescriptorProto)(nil)), "Service")
+var methodProtoPath = protoPathIndex(reflect.TypeOf((*descriptorpb.ServiceDescriptorProto)(nil)), "Method")
+
+func isProtoPathMatches(paths []int32, outerPaths []int32, typeName string, typeIndex int32, fieldPaths []int32) bool {
+ if typeName == "Package" && typeIndex == packageProtoPath {
+ // path for package comments is just [2], and all the other processing
+ // is too complex for it.
+ if len(paths) == 0 || typeIndex != paths[0] {
+ return false
+ }
+ return true
+ }
+
+ if len(paths) != len(outerPaths)*2+2+len(fieldPaths) {
+ return false
+ }
+
+ if typeName == "Method" {
+ if paths[0] != serviceProtoPath || paths[2] != methodProtoPath {
+ return false
+ }
+ paths = paths[2:]
+ } else {
+ typeNameDescriptor := reflect.TypeOf((*descriptorpb.FileDescriptorProto)(nil))
+
+ if len(outerPaths) > 0 {
+ if paths[0] != messageProtoPath || paths[1] != outerPaths[0] {
+ return false
+ }
+ paths = paths[2:]
+ outerPaths = outerPaths[1:]
+
+ for i, v := range outerPaths {
+ if paths[i*2] != nestedProtoPath || paths[i*2+1] != v {
+ return false
+ }
+ }
+ paths = paths[len(outerPaths)*2:]
+
+ if typeName == "MessageType" {
+ typeName = "NestedType"
+ }
+ typeNameDescriptor = reflect.TypeOf((*descriptorpb.DescriptorProto)(nil))
+ }
+
+ if paths[0] != protoPathIndex(typeNameDescriptor, typeName) || paths[1] != typeIndex {
+ return false
+ }
+ paths = paths[2:]
+ }
+
+ for i, v := range fieldPaths {
+ if paths[i] != v {
+ return false
+ }
+ }
+ return true
+}
+
+// protoPathIndex returns a path component for google.protobuf.descriptor.SourceCode_Location.
+//
+// Specifically, it returns an id as generated from descriptor proto which
+// can be used to determine what type the id following it in the path is.
+// For example, if we are trying to locate comments related to a field named
+// `Address` in a message named `Person`, the path will be:
+//
+// [4, a, 2, b]
+//
+// While `a` gets determined by the order in which the messages appear in
+// the proto file, and `b` is the field index specified in the proto
+// file itself, the path actually needs to specify that `a` refers to a
+// message and not, say, a service; and that `b` refers to a field and not
+// an option.
+//
+// protoPathIndex figures out the values 4 and 2 in the above example. Because
+// messages are top level objects, the value of 4 comes from field id for
+// `MessageType` inside `google.protobuf.descriptor.FileDescriptor` message.
+// This field has a message type `google.protobuf.descriptor.DescriptorProto`.
+// And inside message `DescriptorProto`, there is a field named `Field` with id
+// 2.
+//
+// Some code generators seem to be hardcoding these values; this method instead
+// interprets them from `descriptor.proto`-derived Go source as necessary.
+func protoPathIndex(descriptorType reflect.Type, what string) int32 {
+ field, ok := descriptorType.Elem().FieldByName(what)
+ if !ok {
+ panic(fmt.Errorf("could not find protobuf descriptor type id for %s", what))
+ }
+ pbtag := field.Tag.Get("protobuf")
+ if pbtag == "" {
+ panic(fmt.Errorf("no Go tag 'protobuf' on protobuf descriptor for %s", what))
+ }
+ path, err := strconv.Atoi(strings.Split(pbtag, ",")[1])
+ if err != nil {
+ panic(fmt.Errorf("protobuf descriptor id for %s cannot be converted to a number: %s", what, err.Error()))
+ }
+
+ return int32(path)
+}
+
+// extractOperationOptionFromMethodDescriptor extracts the message of type
+// openapi_options.Operation from a given proto method's descriptor.
+func extractOperationOptionFromMethodDescriptor(meth *descriptorpb.MethodDescriptorProto) (*openapi_options.Operation, error) {
+ if meth.Options == nil {
+ return nil, nil
+ }
+ if !proto.HasExtension(meth.Options, openapi_options.E_Openapiv2Operation) {
+ return nil, nil
+ }
+ ext := proto.GetExtension(meth.Options, openapi_options.E_Openapiv2Operation)
+ opts, ok := ext.(*openapi_options.Operation)
+ if !ok {
+ return nil, fmt.Errorf("extension is %T; want an Operation", ext)
+ }
+ return opts, nil
+}
+
+// extractSchemaOptionFromMessageDescriptor extracts the message of type
+// openapi_options.Schema from a given proto message's descriptor.
+func extractSchemaOptionFromMessageDescriptor(msg *descriptorpb.DescriptorProto) (*openapi_options.Schema, error) {
+ if msg.Options == nil {
+ return nil, nil
+ }
+ if !proto.HasExtension(msg.Options, openapi_options.E_Openapiv2Schema) {
+ return nil, nil
+ }
+ ext := proto.GetExtension(msg.Options, openapi_options.E_Openapiv2Schema)
+ opts, ok := ext.(*openapi_options.Schema)
+ if !ok {
+ return nil, fmt.Errorf("extension is %T; want a Schema", ext)
+ }
+ return opts, nil
+}
+
+// extractOpenAPIOptionFromFileDescriptor extracts the message of type
+// openapi_options.OpenAPI from a given proto method's descriptor.
+func extractOpenAPIOptionFromFileDescriptor(file *descriptorpb.FileDescriptorProto) (*openapi_options.Swagger, error) {
+ if file.Options == nil {
+ return nil, nil
+ }
+ if !proto.HasExtension(file.Options, openapi_options.E_Openapiv2Swagger) {
+ return nil, nil
+ }
+ ext := proto.GetExtension(file.Options, openapi_options.E_Openapiv2Swagger)
+ opts, ok := ext.(*openapi_options.Swagger)
+ if !ok {
+ return nil, fmt.Errorf("extension is %T; want a OpenAPI object", ext)
+ }
+ return opts, nil
+}
+
+func extractJSONSchemaFromFieldDescriptor(fd *descriptorpb.FieldDescriptorProto) (*openapi_options.JSONSchema, error) {
+ if fd.Options == nil {
+ return nil, nil
+ }
+ if !proto.HasExtension(fd.Options, openapi_options.E_Openapiv2Field) {
+ return nil, nil
+ }
+ ext := proto.GetExtension(fd.Options, openapi_options.E_Openapiv2Field)
+ opts, ok := ext.(*openapi_options.JSONSchema)
+ if !ok {
+ return nil, fmt.Errorf("extension is %T; want a JSONSchema object", ext)
+ }
+ return opts, nil
+}
+
+func extractFieldBehaviorFromFieldDescriptor(fd *descriptorpb.FieldDescriptorProto) ([]annotations.FieldBehavior, error) {
+ if fd.Options == nil {
+ return nil, nil
+ }
+ if !proto.HasExtension(fd.Options, annotations.E_FieldBehavior) {
+ return nil, nil
+ }
+ ext := proto.GetExtension(fd.Options, annotations.E_FieldBehavior)
+ opts, ok := ext.([]annotations.FieldBehavior)
+ if !ok {
+ return nil, fmt.Errorf("extension is %T; want a []FieldBehavior object", ext)
+ }
+ return opts, nil
+}
+
+func getFieldVisibilityOption(fd *descriptor.Field) *visibility.VisibilityRule {
+ if fd.Options == nil {
+ return nil
+ }
+ if !proto.HasExtension(fd.Options, visibility.E_FieldVisibility) {
+ return nil
+ }
+ ext := proto.GetExtension(fd.Options, visibility.E_FieldVisibility)
+ opts, ok := ext.(*visibility.VisibilityRule)
+ if !ok {
+ return nil
+ }
+ return opts
+}
+
+func getServiceVisibilityOption(fd *descriptor.Service) *visibility.VisibilityRule {
+ if fd.Options == nil {
+ return nil
+ }
+ if !proto.HasExtension(fd.Options, visibility.E_ApiVisibility) {
+ return nil
+ }
+ ext := proto.GetExtension(fd.Options, visibility.E_ApiVisibility)
+ opts, ok := ext.(*visibility.VisibilityRule)
+ if !ok {
+ return nil
+ }
+ return opts
+}
+
+func getMethodVisibilityOption(fd *descriptor.Method) *visibility.VisibilityRule {
+ if fd.Options == nil {
+ return nil
+ }
+ if !proto.HasExtension(fd.Options, visibility.E_MethodVisibility) {
+ return nil
+ }
+ ext := proto.GetExtension(fd.Options, visibility.E_MethodVisibility)
+ opts, ok := ext.(*visibility.VisibilityRule)
+ if !ok {
+ return nil
+ }
+ return opts
+}
+
+func getEnumValueVisibilityOption(fd *descriptorpb.EnumValueDescriptorProto) *visibility.VisibilityRule {
+ if fd.Options == nil {
+ return nil
+ }
+ if !proto.HasExtension(fd.Options, visibility.E_ValueVisibility) {
+ return nil
+ }
+ ext := proto.GetExtension(fd.Options, visibility.E_ValueVisibility)
+ opts, ok := ext.(*visibility.VisibilityRule)
+ if !ok {
+ return nil
+ }
+ return opts
+}
+
+func getMethodOpenAPIOption(reg *descriptor.Registry, meth *descriptor.Method) (*openapi_options.Operation, error) {
+ opts, err := extractOperationOptionFromMethodDescriptor(meth.MethodDescriptorProto)
+ if err != nil {
+ return nil, err
+ }
+ if opts != nil {
+ return opts, nil
+ }
+ opts, ok := reg.GetOpenAPIMethodOption(meth.FQMN())
+ if !ok {
+ return nil, nil
+ }
+ return opts, nil
+}
+
+func getMessageOpenAPIOption(reg *descriptor.Registry, msg *descriptor.Message) (*openapi_options.Schema, error) {
+ opts, err := extractSchemaOptionFromMessageDescriptor(msg.DescriptorProto)
+ if err != nil {
+ return nil, err
+ }
+ if opts != nil {
+ return opts, nil
+ }
+ opts, ok := reg.GetOpenAPIMessageOption(msg.FQMN())
+ if !ok {
+ return nil, nil
+ }
+ return opts, nil
+}
+
+func getFileOpenAPIOption(reg *descriptor.Registry, file *descriptor.File) (*openapi_options.Swagger, error) {
+ opts, err := extractOpenAPIOptionFromFileDescriptor(file.FileDescriptorProto)
+ if err != nil {
+ return nil, err
+ }
+ if opts != nil {
+ return opts, nil
+ }
+ opts, ok := reg.GetOpenAPIFileOption(*file.Name)
+ if !ok {
+ return nil, nil
+ }
+ return opts, nil
+}
+
+func getFieldOpenAPIOption(reg *descriptor.Registry, fd *descriptor.Field) (*openapi_options.JSONSchema, error) {
+ opts, err := extractJSONSchemaFromFieldDescriptor(fd.FieldDescriptorProto)
+ if err != nil {
+ return nil, err
+ }
+ if opts != nil {
+ return opts, nil
+ }
+ opts, ok := reg.GetOpenAPIFieldOption(fd.FQFN())
+ if !ok {
+ return nil, nil
+ }
+ return opts, nil
+}
+
+func getFieldBehaviorOption(reg *descriptor.Registry, fd *descriptor.Field) ([]annotations.FieldBehavior, error) {
+ opts, err := extractFieldBehaviorFromFieldDescriptor(fd.FieldDescriptorProto)
+ if err != nil {
+ return nil, err
+ }
+ if opts != nil {
+ return opts, nil
+ }
+ return opts, nil
+}
+
+func protoJSONSchemaToOpenAPISchemaCore(j *openapi_options.JSONSchema, reg *descriptor.Registry, refs refMap) schemaCore {
+ ret := schemaCore{}
+
+ if j.GetRef() != "" {
+ openapiName, ok := fullyQualifiedNameToOpenAPIName(j.GetRef(), reg)
+ if ok {
+ ret.Ref = "#/definitions/" + openapiName
+ if refs != nil {
+ refs[j.GetRef()] = struct{}{}
+ }
+ } else {
+ ret.Ref += j.GetRef()
+ }
+ } else {
+ f, t := protoJSONSchemaTypeToFormat(j.GetType())
+ ret.Format = f
+ ret.Type = t
+ }
+
+ return ret
+}
+
+func updateswaggerObjectFromJSONSchema(s *openapiSchemaObject, j *openapi_options.JSONSchema, reg *descriptor.Registry, data interface{}) {
+ s.Title = j.GetTitle()
+ s.Description = j.GetDescription()
+ if reg.GetUseGoTemplate() {
+ s.Title = goTemplateComments(s.Title, data, reg)
+ s.Description = goTemplateComments(s.Description, data, reg)
+ }
+
+ s.ReadOnly = j.GetReadOnly()
+ s.MultipleOf = j.GetMultipleOf()
+ s.Maximum = j.GetMaximum()
+ s.ExclusiveMaximum = j.GetExclusiveMaximum()
+ s.Minimum = j.GetMinimum()
+ s.ExclusiveMinimum = j.GetExclusiveMinimum()
+ s.MaxLength = j.GetMaxLength()
+ s.MinLength = j.GetMinLength()
+ s.Pattern = j.GetPattern()
+ s.Default = j.GetDefault()
+ s.MaxItems = j.GetMaxItems()
+ s.MinItems = j.GetMinItems()
+ s.UniqueItems = j.GetUniqueItems()
+ s.MaxProperties = j.GetMaxProperties()
+ s.MinProperties = j.GetMinProperties()
+ s.Required = j.GetRequired()
+ if reg.GetUseJSONNamesForFields() {
+ for i, r := range s.Required {
+ // TODO(oyvindwe): Look up field and use field.GetJsonName()?
+ s.Required[i] = doCamelCase(r)
+ }
+ }
+ s.Enum = j.GetEnum()
+ if overrideType := j.GetType(); len(overrideType) > 0 {
+ s.Type = strings.ToLower(overrideType[0].String())
+ }
+ if j != nil && j.GetExample() != "" {
+ s.Example = RawExample(j.GetExample())
+ }
+ if j != nil && j.GetFormat() != "" {
+ s.Format = j.GetFormat()
+ }
+}
+
+func updateSwaggerObjectFromFieldBehavior(s *openapiSchemaObject, j []annotations.FieldBehavior, reg *descriptor.Registry, field *descriptor.Field) {
+ // Per the JSON Reference syntax: Any members other than "$ref" in a JSON Reference object SHALL be ignored.
+ // https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03#section-3
+ if s.Ref != "" {
+ return
+ }
+
+ for _, fb := range j {
+ switch fb {
+ case annotations.FieldBehavior_REQUIRED:
+ if reg.GetUseJSONNamesForFields() {
+ s.Required = append(s.Required, *field.JsonName)
+ } else {
+ s.Required = append(s.Required, *field.Name)
+ }
+ case annotations.FieldBehavior_OUTPUT_ONLY:
+ s.ReadOnly = true
+ case annotations.FieldBehavior_FIELD_BEHAVIOR_UNSPECIFIED:
+ case annotations.FieldBehavior_OPTIONAL:
+ case annotations.FieldBehavior_INPUT_ONLY:
+ // OpenAPI v3 supports a writeOnly property, but this is not supported in Open API v2
+ case annotations.FieldBehavior_IMMUTABLE:
+ }
+ }
+}
+
+func openapiSchemaFromProtoSchema(s *openapi_options.Schema, reg *descriptor.Registry, refs refMap, data interface{}) openapiSchemaObject {
+ ret := openapiSchemaObject{
+ ExternalDocs: protoExternalDocumentationToOpenAPIExternalDocumentation(s.GetExternalDocs(), reg, data),
+ }
+
+ ret.schemaCore = protoJSONSchemaToOpenAPISchemaCore(s.GetJsonSchema(), reg, refs)
+ updateswaggerObjectFromJSONSchema(&ret, s.GetJsonSchema(), reg, data)
+
+ if s != nil && s.Example != "" {
+ ret.Example = RawExample(s.Example)
+ }
+
+ return ret
+}
+
+func openapiExamplesFromProtoExamples(in map[string]string) map[string]interface{} {
+ if len(in) == 0 {
+ return nil
+ }
+ out := make(map[string]interface{})
+ for mimeType, exampleStr := range in {
+ switch mimeType {
+ case "application/json":
+ // JSON example objects are rendered raw.
+ out[mimeType] = json.RawMessage(exampleStr)
+ default:
+ // All other mimetype examples are rendered as strings.
+ out[mimeType] = exampleStr
+ }
+ }
+ return out
+}
+
+func protoJSONSchemaTypeToFormat(in []openapi_options.JSONSchema_JSONSchemaSimpleTypes) (string, string) {
+ if len(in) == 0 {
+ return "", ""
+ }
+
+ // Can't support more than 1 type, just return the first element.
+ // This is due to an inconsistency in the design of the openapiv2 proto
+ // and that used in schemaCore. schemaCore uses the v3 definition of types,
+ // which only allows a single string, while the openapiv2 proto uses the OpenAPI v2
+ // definition, which defers to the JSON schema definition, which allows a string or an array.
+ // Sources:
+ // https://swagger.io/specification/#itemsObject
+ // https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.5.2
+ switch in[0] {
+ case openapi_options.JSONSchema_UNKNOWN, openapi_options.JSONSchema_NULL:
+ return "", ""
+ case openapi_options.JSONSchema_OBJECT:
+ return "object", ""
+ case openapi_options.JSONSchema_ARRAY:
+ return "array", ""
+ case openapi_options.JSONSchema_BOOLEAN:
+ // NOTE: in OpenAPI specification, format should be empty on boolean type
+ return "boolean", ""
+ case openapi_options.JSONSchema_INTEGER:
+ return "integer", "int32"
+ case openapi_options.JSONSchema_NUMBER:
+ return "number", "double"
+ case openapi_options.JSONSchema_STRING:
+ // NOTE: in OpenAPI specification, format should be empty on string type
+ return "string", ""
+ default:
+ // Maybe panic?
+ return "", ""
+ }
+}
+
+func protoExternalDocumentationToOpenAPIExternalDocumentation(in *openapi_options.ExternalDocumentation, reg *descriptor.Registry, data interface{}) *openapiExternalDocumentationObject {
+ if in == nil {
+ return nil
+ }
+
+ if reg.GetUseGoTemplate() {
+ in.Description = goTemplateComments(in.Description, data, reg)
+ }
+
+ return &openapiExternalDocumentationObject{
+ Description: in.Description,
+ URL: in.Url,
+ }
+}
+
+func addCustomRefs(d openapiDefinitionsObject, reg *descriptor.Registry, refs refMap) error {
+ if len(refs) == 0 {
+ return nil
+ }
+ msgMap := make(messageMap)
+ enumMap := make(enumMap)
+ for ref := range refs {
+ swgName, swgOk := fullyQualifiedNameToOpenAPIName(ref, reg)
+ if !swgOk {
+ glog.Errorf("can't resolve OpenAPI name from CustomRef '%v'", ref)
+ continue
+ }
+ if _, ok := d[swgName]; ok {
+ // Skip already existing definitions
+ delete(refs, ref)
+ continue
+ }
+ msg, err := reg.LookupMsg("", ref)
+ if err == nil {
+ msgMap[swgName] = msg
+ continue
+ }
+ enum, err := reg.LookupEnum("", ref)
+ if err == nil {
+ enumMap[swgName] = enum
+ continue
+ }
+
+ // ?? Should be either enum or msg
+ }
+ if err := renderMessagesAsDefinition(msgMap, d, reg, refs, nil); err != nil {
+ return err
+ }
+ renderEnumerationsAsDefinition(enumMap, d, reg)
+
+ // Run again in case any new refs were added
+ return addCustomRefs(d, reg, refs)
+}
+
+func lowerCamelCase(fieldName string, fields []*descriptor.Field, msgs []*descriptor.Message) string {
+ for _, oneField := range fields {
+ if oneField.GetName() == fieldName {
+ return oneField.GetJsonName()
+ }
+ }
+ messageNameToFieldsToJSONName := make(map[string]map[string]string)
+ fieldNameToType := make(map[string]string)
+ for _, msg := range msgs {
+ fieldNameToJSONName := make(map[string]string)
+ for _, oneField := range msg.GetField() {
+ fieldNameToJSONName[oneField.GetName()] = oneField.GetJsonName()
+ fieldNameToType[oneField.GetName()] = oneField.GetTypeName()
+ }
+ messageNameToFieldsToJSONName[msg.GetName()] = fieldNameToJSONName
+ }
+ if strings.Contains(fieldName, ".") {
+ fieldNames := strings.Split(fieldName, ".")
+ fieldNamesWithCamelCase := make([]string, 0)
+ for i := 0; i < len(fieldNames)-1; i++ {
+ fieldNamesWithCamelCase = append(fieldNamesWithCamelCase, doCamelCase(string(fieldNames[i])))
+ }
+ prefix := strings.Join(fieldNamesWithCamelCase, ".")
+ reservedJSONName := getReservedJSONName(fieldName, messageNameToFieldsToJSONName, fieldNameToType)
+ if reservedJSONName != "" {
+ return prefix + "." + reservedJSONName
+ }
+ }
+ return doCamelCase(fieldName)
+}
+
+func doCamelCase(input string) string {
+ parameterString := casing.Camel(input)
+ builder := &strings.Builder{}
+ builder.WriteString(strings.ToLower(string(parameterString[0])))
+ builder.WriteString(parameterString[1:])
+ return builder.String()
+}
+
+func getReservedJSONName(fieldName string, messageNameToFieldsToJSONName map[string]map[string]string, fieldNameToType map[string]string) string {
+ if len(strings.Split(fieldName, ".")) == 2 {
+ fieldNames := strings.Split(fieldName, ".")
+ firstVariable := fieldNames[0]
+ firstType := fieldNameToType[firstVariable]
+ firstTypeShortNames := strings.Split(firstType, ".")
+ firstTypeShortName := firstTypeShortNames[len(firstTypeShortNames)-1]
+ return messageNameToFieldsToJSONName[firstTypeShortName][fieldNames[1]]
+ }
+ fieldNames := strings.Split(fieldName, ".")
+ return getReservedJSONName(strings.Join(fieldNames[1:], "."), messageNameToFieldsToJSONName, fieldNameToType)
+}
+
+func find(a []string, x string) int {
+ // This is a linear search but we are dealing with a small number of fields
+ for i, n := range a {
+ if x == n {
+ return i
+ }
+ }
+ return -1
+}
+
+// Make a deep copy of the outer parameters that has paramName as the first component,
+// but remove the first component of the field path.
+func subPathParams(paramName string, outerParams []descriptor.Parameter) []descriptor.Parameter {
+ var innerParams []descriptor.Parameter
+ for _, p := range outerParams {
+ if len(p.FieldPath) > 1 && p.FieldPath[0].Name == paramName {
+ subParam := descriptor.Parameter{
+ FieldPath: p.FieldPath[1:],
+ Target: p.Target,
+ Method: p.Method,
+ }
+ innerParams = append(innerParams, subParam)
+ }
+ }
+ return innerParams
+}
diff --git a/gateway/protoc-gen-openapiv2/internal/genopenapi/types.go b/gateway/protoc-gen-openapiv2/internal/genopenapi/types.go
new file mode 100644
index 0000000..3c40929
--- /dev/null
+++ b/gateway/protoc-gen-openapiv2/internal/genopenapi/types.go
@@ -0,0 +1,334 @@
+package genopenapi
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor"
+ "github.com/binchencoder/janus-gateway/gateway/internal/descriptor"
+ options "github.com/binchencoder/janus-gateway/httpoptions"
+ "gopkg.in/yaml.v2"
+)
+
+type param struct {
+ *descriptor.File
+ reg *descriptor.Registry
+}
+
+// http://swagger.io/specification/#infoObject
+type openapiInfoObject struct {
+ Title string `json:"title" yaml:"title"`
+ Description string `json:"description,omitempty" yaml:"description,omitempty"`
+ TermsOfService string `json:"termsOfService,omitempty" yaml:"termsOfService,omitempty"`
+ Version string `json:"version" yaml:"version"`
+
+ Contact *openapiContactObject `json:"contact,omitempty" yaml:"contact,omitempty"`
+ License *openapiLicenseObject `json:"license,omitempty" yaml:"license,omitempty"`
+
+ extensions []extension `json:"-" yaml:"-"`
+}
+
+// https://swagger.io/specification/#tagObject
+type openapiTagObject struct {
+ Name string `json:"name" yaml:"name"`
+ Description string `json:"description,omitempty" yaml:"description,omitempty"`
+ ExternalDocs *openapiExternalDocumentationObject `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
+}
+
+// http://swagger.io/specification/#contactObject
+type openapiContactObject struct {
+ Name string `json:"name,omitempty" yaml:"name,omitempty"`
+ URL string `json:"url,omitempty" yaml:"url,omitempty"`
+ Email string `json:"email,omitempty" yaml:"email,omitempty"`
+}
+
+// http://swagger.io/specification/#licenseObject
+type openapiLicenseObject struct {
+ Name string `json:"name,omitempty" yaml:"name,omitempty"`
+ URL string `json:"url,omitempty" yaml:"url,omitempty"`
+}
+
+// http://swagger.io/specification/#externalDocumentationObject
+type openapiExternalDocumentationObject struct {
+ Description string `json:"description,omitempty" yaml:"description,omitempty"`
+ URL string `json:"url,omitempty" yaml:"url,omitempty"`
+}
+
+type extension struct {
+ key string `json:"-" yaml:"-"`
+ value json.RawMessage `json:"-" yaml:"-"`
+}
+
+// http://swagger.io/specification/#swaggerObject
+type openapiSwaggerObject struct {
+ Swagger string `json:"swagger" yaml:"swagger"`
+ Info openapiInfoObject `json:"info" yaml:"info"`
+ Tags []openapiTagObject `json:"tags,omitempty" yaml:"tags,omitempty"`
+ Host string `json:"host,omitempty" yaml:"host,omitempty"`
+ BasePath string `json:"basePath,omitempty" yaml:"basePath,omitempty"`
+ Schemes []string `json:"schemes,omitempty" yaml:"schemes,omitempty"`
+ Consumes []string `json:"consumes" yaml:"consumes"`
+ Produces []string `json:"produces" yaml:"produces"`
+ Paths openapiPathsObject `json:"paths" yaml:"paths"`
+ Definitions openapiDefinitionsObject `json:"definitions" yaml:"definitions"`
+ SecurityDefinitions openapiSecurityDefinitionsObject `json:"securityDefinitions,omitempty" yaml:"securityDefinitions,omitempty"`
+ Security []openapiSecurityRequirementObject `json:"security,omitempty" yaml:"security,omitempty"`
+ ExternalDocs *openapiExternalDocumentationObject `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
+
+ extensions []extension `json:"-" yaml:"-"`
+}
+
+// http://swagger.io/specification/#securityDefinitionsObject
+type openapiSecurityDefinitionsObject map[string]openapiSecuritySchemeObject
+
+// http://swagger.io/specification/#securitySchemeObject
+type openapiSecuritySchemeObject struct {
+ Type string `json:"type" yaml:"type"`
+ Description string `json:"description,omitempty" yaml:"description,omitempty"`
+ Name string `json:"name,omitempty" yaml:"name,omitempty"`
+ In string `json:"in,omitempty" yaml:"in,omitempty"`
+ Flow string `json:"flow,omitempty" yaml:"flow,omitempty"`
+ AuthorizationURL string `json:"authorizationUrl,omitempty" yaml:"authorizationUrl,omitempty"`
+ TokenURL string `json:"tokenUrl,omitempty" yaml:"tokenUrl,omitempty"`
+ Scopes openapiScopesObject `json:"scopes,omitempty" yaml:"scopes,omitempty"`
+
+ extensions []extension `json:"-" yaml:"-"`
+}
+
+// http://swagger.io/specification/#scopesObject
+type openapiScopesObject map[string]string
+
+// http://swagger.io/specification/#securityRequirementObject
+type openapiSecurityRequirementObject map[string][]string
+
+// http://swagger.io/specification/#pathsObject
+type openapiPathsObject map[string]openapiPathItemObject
+
+// http://swagger.io/specification/#pathItemObject
+type openapiPathItemObject struct {
+ Get *openapiOperationObject `json:"get,omitempty" yaml:"get,omitempty"`
+ Delete *openapiOperationObject `json:"delete,omitempty" yaml:"delete,omitempty"`
+ Post *openapiOperationObject `json:"post,omitempty" yaml:"post,omitempty"`
+ Put *openapiOperationObject `json:"put,omitempty" yaml:"put,omitempty"`
+ Patch *openapiOperationObject `json:"patch,omitempty" yaml:"patch,omitempty"`
+}
+
+// http://swagger.io/specification/#operationObject
+type openapiOperationObject struct {
+ Summary string `json:"summary,omitempty" yaml:"summary,omitempty"`
+ Description string `json:"description,omitempty" yaml:"description,omitempty"`
+ OperationID string `json:"operationId" yaml:"operationId"`
+ Responses openapiResponsesObject `json:"responses" yaml:"responses"`
+ Parameters openapiParametersObject `json:"parameters,omitempty" yaml:"parameters,omitempty"`
+ Tags []string `json:"tags,omitempty" yaml:"tags,omitempty"`
+ Deprecated bool `json:"deprecated,omitempty" yaml:"deprecated,omitempty"`
+ Produces []string `json:"produces,omitempty" yaml:"produces,omitempty"`
+
+ Security *[]openapiSecurityRequirementObject `json:"security,omitempty" yaml:"security,omitempty"`
+ ExternalDocs *openapiExternalDocumentationObject `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
+
+ extensions []extension `json:"-" yaml:"-"`
+}
+
+type openapiParametersObject []openapiParameterObject
+
+// http://swagger.io/specification/#parameterObject
+type openapiParameterObject struct {
+ Name string `json:"name" yaml:"name"`
+ Description string `json:"description,omitempty" yaml:"description,omitempty"`
+ In string `json:"in,omitempty" yaml:"in,omitempty"`
+ Required bool `json:"required" yaml:"required"`
+ Type string `json:"type,omitempty" yaml:"type,omitempty"`
+ Format string `json:"format,omitempty" yaml:"format,omitempty"`
+ Items *openapiItemsObject `json:"items,omitempty" yaml:"items,omitempty"`
+ Enum []string `json:"enum,omitempty" yaml:"enum,omitempty"`
+ CollectionFormat string `json:"collectionFormat,omitempty" yaml:"collectionFormat,omitempty"`
+ Default string `json:"default,omitempty" yaml:"default,omitempty"`
+ MinItems *int `json:"minItems,omitempty" yaml:"minItems,omitempty"`
+ Pattern string `json:"pattern,omitempty" yaml:"pattern,omitempty"`
+
+ // Or you can explicitly refer to another type. If this is defined all
+ // other fields should be empty
+ Schema *openapiSchemaObject `json:"schema,omitempty" yaml:"schema,omitempty"`
+}
+
+// core part of schema, which is common to itemsObject and schemaObject.
+// http://swagger.io/specification/v2/#itemsObject
+// The OAS3 spec (https://swagger.io/specification/#schemaObject) defines the
+// `nullable` field as part of a Schema Object. This behavior has been
+// "back-ported" to OAS2 as the Specification Extension `x-nullable`, and is
+// supported by generation tools such as swagger-codegen and go-swagger.
+// For protoc-gen-openapiv3, we'd want to add `nullable` instead.
+type schemaCore struct {
+ Type string `json:"type,omitempty" yaml:"type,omitempty"`
+ Format string `json:"format,omitempty" yaml:"format,omitempty"`
+ Ref string `json:"$ref,omitempty" yaml:"$ref,omitempty"`
+ XNullable bool `json:"x-nullable,omitempty" yaml:"x-nullable,omitempty"`
+ Example RawExample `json:"example,omitempty" yaml:"example,omitempty"`
+
+ Items *openapiItemsObject `json:"items,omitempty" yaml:"items,omitempty"`
+
+ // If the item is an enumeration include a list of all the *NAMES* of the
+ // enum values. I'm not sure how well this will work but assuming all enums
+ // start from 0 index it will be great. I don't think that is a good assumption.
+ Enum []string `json:"enum,omitempty" yaml:"enum,omitempty"`
+ Default string `json:"default,omitempty" yaml:"default,omitempty"`
+ Rules []options.ValidationRule `json:"rules,omitempty"`
+}
+
+type RawExample json.RawMessage
+
+func (m RawExample) MarshalJSON() ([]byte, error) {
+ return (json.RawMessage)(m).MarshalJSON()
+}
+
+func (m *RawExample) UnmarshalJSON(data []byte) error {
+ return (*json.RawMessage)(m).UnmarshalJSON(data)
+}
+
+// MarshalYAML implements yaml.Marshaler interface.
+//
+// It converts RawExample to one of yaml-supported types and returns it.
+//
+// From yaml.Marshaler docs: The Marshaler interface may be implemented
+// by types to customize their behavior when being marshaled into a YAML
+// document. The returned value is marshaled in place of the original
+// value implementing Marshaler.
+func (e RawExample) MarshalYAML() (interface{}, error) {
+ // From docs, json.Unmarshal will store one of next types to data:
+ // - bool, for JSON booleans;
+ // - float64, for JSON numbers;
+ // - string, for JSON strings;
+ // - []interface{}, for JSON arrays;
+ // - map[string]interface{}, for JSON objects;
+ // - nil for JSON null.
+ var data interface{}
+ if err := json.Unmarshal(e, &data); err != nil {
+ return nil, err
+ }
+
+ return data, nil
+}
+
+func (s *schemaCore) setRefFromFQN(ref string, reg *descriptor.Registry) error {
+ name, ok := fullyQualifiedNameToOpenAPIName(ref, reg)
+ if !ok {
+ return fmt.Errorf("setRefFromFQN: can't resolve OpenAPI name from '%v'", ref)
+ }
+ s.Ref = fmt.Sprintf("#/definitions/%s", name)
+ return nil
+}
+
+type openapiItemsObject schemaCore
+
+// http://swagger.io/specification/#responsesObject
+type openapiResponsesObject map[string]openapiResponseObject
+
+// http://swagger.io/specification/#responseObject
+type openapiResponseObject struct {
+ Description string `json:"description" yaml:"description"`
+ Schema openapiSchemaObject `json:"schema" yaml:"schema"`
+ Examples map[string]interface{} `json:"examples,omitempty" yaml:"examples,omitempty"`
+ Headers openapiHeadersObject `json:"headers,omitempty" yaml:"headers,omitempty"`
+
+ extensions []extension `json:"-" yaml:"-"`
+}
+
+type openapiHeadersObject map[string]openapiHeaderObject
+
+// http://swagger.io/specification/#headerObject
+type openapiHeaderObject struct {
+ Description string `json:"description,omitempty" yaml:"description,omitempty"`
+ Type string `json:"type,omitempty" yaml:"type,omitempty"`
+ Format string `json:"format,omitempty" yaml:"format,omitempty"`
+ Default RawExample `json:"default,omitempty" yaml:"default,omitempty"`
+ Pattern string `json:"pattern,omitempty" yaml:"pattern,omitempty"`
+}
+
+type keyVal struct {
+ Key string
+ Value interface{}
+}
+
+type openapiSchemaObjectProperties []keyVal
+
+func (p openapiSchemaObjectProperties) MarshalYAML() (interface{}, error) {
+ ms := make(yaml.MapSlice, len(p))
+
+ for i, v := range p {
+ ms[i] = yaml.MapItem{
+ Key: v.Key,
+ Value: v.Value,
+ }
+ }
+
+ return ms, nil
+}
+
+func (op openapiSchemaObjectProperties) MarshalJSON() ([]byte, error) {
+ var buf bytes.Buffer
+ buf.WriteString("{")
+ for i, kv := range op {
+ if i != 0 {
+ buf.WriteString(",")
+ }
+ key, err := json.Marshal(kv.Key)
+ if err != nil {
+ return nil, err
+ }
+ buf.Write(key)
+ buf.WriteString(":")
+ val, err := json.Marshal(kv.Value)
+ if err != nil {
+ return nil, err
+ }
+ buf.Write(val)
+ }
+
+ buf.WriteString("}")
+ return buf.Bytes(), nil
+}
+
+// http://swagger.io/specification/#schemaObject
+type openapiSchemaObject struct {
+ schemaCore `yaml:",inline"`
+ // Properties can be recursively defined
+ Properties *openapiSchemaObjectProperties `json:"properties,omitempty" yaml:"properties,omitempty"`
+ AdditionalProperties *openapiSchemaObject `json:"additionalProperties,omitempty" yaml:"additionalProperties,omitempty"`
+
+ Description string `json:"description,omitempty" yaml:"description,omitempty"`
+ Title string `json:"title,omitempty" yaml:"title,omitempty"`
+
+ ExternalDocs *openapiExternalDocumentationObject `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
+
+ ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"`
+ MultipleOf float64 `json:"multipleOf,omitempty" yaml:"multipleOf,omitempty"`
+ Maximum float64 `json:"maximum,omitempty" yaml:"maximum,omitempty"`
+ ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty" yaml:"exclusiveMaximum,omitempty"`
+ Minimum float64 `json:"minimum,omitempty" yaml:"minimum,omitempty"`
+ ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty" yaml:"exclusiveMinimum,omitempty"`
+ MaxLength uint64 `json:"maxLength,omitempty" yaml:"maxLength,omitempty"`
+ MinLength uint64 `json:"minLength,omitempty" yaml:"minLength,omitempty"`
+ Pattern string `json:"pattern,omitempty" yaml:"pattern,omitempty"`
+ MaxItems uint64 `json:"maxItems,omitempty" yaml:"maxItems,omitempty"`
+ MinItems uint64 `json:"minItems,omitempty" yaml:"minItems,omitempty"`
+ UniqueItems bool `json:"uniqueItems,omitempty" yaml:"uniqueItems,omitempty"`
+ MaxProperties uint64 `json:"maxProperties,omitempty" yaml:"maxProperties,omitempty"`
+ MinProperties uint64 `json:"minProperties,omitempty" yaml:"minProperties,omitempty"`
+ Required []string `json:"required,omitempty" yaml:"required,omitempty"`
+}
+
+// http://swagger.io/specification/#definitionsObject
+type openapiDefinitionsObject map[string]openapiSchemaObject
+
+// Internal type mapping from FQMN to descriptor.Message. Used as a set by the
+// findServiceMessages function.
+type messageMap map[string]*descriptor.Message
+
+// Internal type mapping from FQEN to descriptor.Enum. Used as a set by the
+// findServiceMessages function.
+type enumMap map[string]*descriptor.Enum
+
+// Internal type to store used references.
+type refMap map[string]struct{}
diff --git a/gateway/protoc-gen-openapiv2/main.go b/gateway/protoc-gen-openapiv2/main.go
new file mode 100644
index 0000000..63cbaf3
--- /dev/null
+++ b/gateway/protoc-gen-openapiv2/main.go
@@ -0,0 +1,260 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "os"
+ "strings"
+
+ "github.com/golang/glog"
+ "github.com/grpc-ecosystem/grpc-gateway/v2/internal/codegenerator"
+
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor"
+ "github.com/binchencoder/janus-gateway/gateway/internal/descriptor"
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/internal/genopenapi"
+ genopenapi "github.com/binchencoder/janus-gateway/gateway/protoc-gen-openapiv2/internal/genopenapi"
+ "github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/types/pluginpb"
+)
+
+var (
+ importPrefix = flag.String("import_prefix", "", "prefix to be added to go package paths for imported proto files")
+ file = flag.String("file", "-", "where to load data from")
+ allowDeleteBody = flag.Bool("allow_delete_body", false, "unless set, HTTP DELETE methods may not have a body")
+ grpcAPIConfiguration = flag.String("grpc_api_configuration", "", "path to file which describes the gRPC API Configuration in YAML format")
+ allowMerge = flag.Bool("allow_merge", false, "if set, generation one OpenAPI file out of multiple protos")
+ mergeFileName = flag.String("merge_file_name", "apidocs", "target OpenAPI file name prefix after merge")
+ useJSONNamesForFields = flag.Bool("json_names_for_fields", true, "if disabled, the original proto name will be used for generating OpenAPI definitions")
+ repeatedPathParamSeparator = flag.String("repeated_path_param_separator", "csv", "configures how repeated fields should be split. Allowed values are `csv`, `pipes`, `ssv` and `tsv`")
+ versionFlag = flag.Bool("version", false, "print the current version")
+ allowRepeatedFieldsInBody = flag.Bool("allow_repeated_fields_in_body", false, "allows to use repeated field in `body` and `response_body` field of `google.api.http` annotation option")
+ includePackageInTags = flag.Bool("include_package_in_tags", false, "if unset, the gRPC service name is added to the `Tags` field of each operation. If set and the `package` directive is shown in the proto file, the package name will be prepended to the service name")
+ useFQNForOpenAPIName = flag.Bool("fqn_for_openapi_name", false, "if set, the object's OpenAPI names will use the fully qualified names from the proto definition (ie my.package.MyMessage.MyInnerMessage). DEPRECATED: prefer `openapi_naming_strategy=fqn`")
+ openAPINamingStrategy = flag.String("openapi_naming_strategy", "", "use the given OpenAPI naming strategy. Allowed values are `legacy`, `fqn`, `simple`. If unset, either `legacy` or `fqn` are selected, depending on the value of the `fqn_for_openapi_name` flag")
+ useGoTemplate = flag.Bool("use_go_templates", false, "if set, you can use Go templates in protofile comments")
+ disableDefaultErrors = flag.Bool("disable_default_errors", false, "if set, disables generation of default errors. This is useful if you have defined custom error handling")
+ enumsAsInts = flag.Bool("enums_as_ints", false, "whether to render enum values as integers, as opposed to string values")
+ simpleOperationIDs = flag.Bool("simple_operation_ids", false, "whether to remove the service prefix in the operationID generation. Can introduce duplicate operationIDs, use with caution.")
+ proto3OptionalNullable = flag.Bool("proto3_optional_nullable", false, "whether Proto3 Optional fields should be marked as x-nullable")
+ openAPIConfiguration = flag.String("openapi_configuration", "", "path to file which describes the OpenAPI Configuration in YAML format")
+ generateUnboundMethods = flag.Bool("generate_unbound_methods", false, "generate swagger metadata even for RPC methods that have no HttpRule annotation")
+ recursiveDepth = flag.Int("recursive-depth", 1000, "maximum recursion count allowed for a field type")
+ omitEnumDefaultValue = flag.Bool("omit_enum_default_value", false, "if set, omit default enum value")
+ outputFormat = flag.String("output_format", string(genopenapi.FormatJSON), fmt.Sprintf("output content format. Allowed values are: `%s`, `%s`", genopenapi.FormatJSON, genopenapi.FormatYAML))
+ visibilityRestrictionSelectors = utilities.StringArrayFlag(flag.CommandLine, "visibility_restriction_selectors", "list of `google.api.VisibilityRule` visibility labels to include in the generated output when a visibility annotation is defined. Repeat this option to supply multiple values. Elements without visibility annotations are unaffected by this setting.")
+)
+
+// Variables set by goreleaser at build time
+var (
+ version = "dev"
+ commit = "unknown"
+ date = "unknown"
+)
+
+func main() {
+ flag.Parse()
+ defer glog.Flush()
+
+ if *versionFlag {
+ fmt.Printf("Version %v, commit %v, built at %v\n", version, commit, date)
+ os.Exit(0)
+ }
+
+ reg := descriptor.NewRegistry()
+
+ glog.V(1).Info("Processing code generator request")
+ f := os.Stdin
+ if *file != "-" {
+ var err error
+ f, err = os.Open(*file)
+ if err != nil {
+ glog.Fatal(err)
+ }
+ }
+ glog.V(1).Info("Parsing code generator request")
+ req, err := codegenerator.ParseRequest(f)
+ if err != nil {
+ glog.Fatal(err)
+ }
+ glog.V(1).Info("Parsed code generator request")
+ pkgMap := make(map[string]string)
+ if req.Parameter != nil {
+ err := parseReqParam(req.GetParameter(), flag.CommandLine, pkgMap)
+ if err != nil {
+ glog.Fatalf("Error parsing flags: %v", err)
+ }
+ }
+
+ reg.SetPrefix(*importPrefix)
+ reg.SetAllowDeleteBody(*allowDeleteBody)
+ reg.SetAllowMerge(*allowMerge)
+ reg.SetMergeFileName(*mergeFileName)
+ reg.SetUseJSONNamesForFields(*useJSONNamesForFields)
+ reg.SetAllowRepeatedFieldsInBody(*allowRepeatedFieldsInBody)
+ reg.SetIncludePackageInTags(*includePackageInTags)
+
+ reg.SetUseFQNForOpenAPIName(*useFQNForOpenAPIName)
+ // Set the naming strategy either directly from the flag, or via the value of the legacy fqn_for_openapi_name
+ // flag.
+ namingStrategy := *openAPINamingStrategy
+ if *useFQNForOpenAPIName {
+ if namingStrategy != "" {
+ glog.Fatal("The deprecated `fqn_for_openapi_name` flag must remain unset if `openapi_naming_strategy` is set.")
+ }
+ glog.Warning("The `fqn_for_openapi_name` flag is deprecated. Please use `openapi_naming_strategy=fqn` instead.")
+ namingStrategy = "fqn"
+ } else if namingStrategy == "" {
+ namingStrategy = "legacy"
+ }
+ if strategyFn := genopenapi.LookupNamingStrategy(namingStrategy); strategyFn == nil {
+ emitError(fmt.Errorf("invalid naming strategy %q", namingStrategy))
+ return
+ }
+ reg.SetOpenAPINamingStrategy(namingStrategy)
+ reg.SetUseGoTemplate(*useGoTemplate)
+ reg.SetEnumsAsInts(*enumsAsInts)
+ reg.SetDisableDefaultErrors(*disableDefaultErrors)
+ reg.SetSimpleOperationIDs(*simpleOperationIDs)
+ reg.SetProto3OptionalNullable(*proto3OptionalNullable)
+ reg.SetGenerateUnboundMethods(*generateUnboundMethods)
+ reg.SetRecursiveDepth(*recursiveDepth)
+ reg.SetOmitEnumDefaultValue(*omitEnumDefaultValue)
+ reg.SetVisibilityRestrictionSelectors(*visibilityRestrictionSelectors)
+ if err := reg.SetRepeatedPathParamSeparator(*repeatedPathParamSeparator); err != nil {
+ emitError(err)
+ return
+ }
+ for k, v := range pkgMap {
+ reg.AddPkgMap(k, v)
+ }
+
+ if *grpcAPIConfiguration != "" {
+ if err := reg.LoadGrpcAPIServiceFromYAML(*grpcAPIConfiguration); err != nil {
+ emitError(err)
+ return
+ }
+ }
+
+ format := genopenapi.Format(*outputFormat)
+ if err := format.Validate(); err != nil {
+ emitError(err)
+ return
+ }
+
+ g := genopenapi.New(reg, format)
+
+ if err := genopenapi.AddErrorDefs(reg); err != nil {
+ emitError(err)
+ return
+ }
+
+ if err := reg.Load(req); err != nil {
+ emitError(err)
+ return
+ }
+
+ if *openAPIConfiguration != "" {
+ if err := reg.LoadOpenAPIConfigFromYAML(*openAPIConfiguration); err != nil {
+ emitError(err)
+ return
+ }
+ }
+
+ var targets []*descriptor.File
+ for _, target := range req.FileToGenerate {
+ f, err := reg.LookupFile(target)
+ if err != nil {
+ glog.Fatal(err)
+ }
+ targets = append(targets, f)
+ }
+
+ out, err := g.Generate(targets)
+ glog.V(1).Info("Processed code generator request")
+ if err != nil {
+ emitError(err)
+ return
+ }
+ emitFiles(out)
+}
+
+func emitFiles(out []*descriptor.ResponseFile) {
+ files := make([]*pluginpb.CodeGeneratorResponse_File, len(out))
+ for idx, item := range out {
+ files[idx] = item.CodeGeneratorResponse_File
+ }
+ resp := &pluginpb.CodeGeneratorResponse{File: files}
+ codegenerator.SetSupportedFeaturesOnCodeGeneratorResponse(resp)
+ emitResp(resp)
+}
+
+func emitError(err error) {
+ emitResp(&pluginpb.CodeGeneratorResponse{Error: proto.String(err.Error())})
+}
+
+func emitResp(resp *pluginpb.CodeGeneratorResponse) {
+ buf, err := proto.Marshal(resp)
+ if err != nil {
+ glog.Fatal(err)
+ }
+ if _, err := os.Stdout.Write(buf); err != nil {
+ glog.Fatal(err)
+ }
+}
+
+// parseReqParam parses a CodeGeneratorRequest parameter and adds the
+// extracted values to the given FlagSet and pkgMap. Returns a non-nil
+// error if setting a flag failed.
+func parseReqParam(param string, f *flag.FlagSet, pkgMap map[string]string) error {
+ if param == "" {
+ return nil
+ }
+ for _, p := range strings.Split(param, ",") {
+ spec := strings.SplitN(p, "=", 2)
+ if len(spec) == 1 {
+ if spec[0] == "allow_delete_body" {
+ err := f.Set(spec[0], "true")
+ if err != nil {
+ return fmt.Errorf("cannot set flag %s: %v", p, err)
+ }
+ continue
+ }
+ if spec[0] == "allow_merge" {
+ err := f.Set(spec[0], "true")
+ if err != nil {
+ return fmt.Errorf("cannot set flag %s: %v", p, err)
+ }
+ continue
+ }
+ if spec[0] == "allow_repeated_fields_in_body" {
+ err := f.Set(spec[0], "true")
+ if err != nil {
+ return fmt.Errorf("cannot set flag %s: %v", p, err)
+ }
+ continue
+ }
+ if spec[0] == "include_package_in_tags" {
+ err := f.Set(spec[0], "true")
+ if err != nil {
+ return fmt.Errorf("cannot set flag %s: %v", p, err)
+ }
+ continue
+ }
+ err := f.Set(spec[0], "")
+ if err != nil {
+ return fmt.Errorf("cannot set flag %s: %v", p, err)
+ }
+ continue
+ }
+ name, value := spec[0], spec[1]
+ if strings.HasPrefix(name, "M") {
+ pkgMap[name[1:]] = value
+ continue
+ }
+ if err := f.Set(name, value); err != nil {
+ return fmt.Errorf("cannot set flag %s: %v", p, err)
+ }
+ }
+ return nil
+}
diff --git a/gateway/protoc-gen-openapiv2/main_test.go b/gateway/protoc-gen-openapiv2/main_test.go
new file mode 100644
index 0000000..e1b9a1f
--- /dev/null
+++ b/gateway/protoc-gen-openapiv2/main_test.go
@@ -0,0 +1,279 @@
+package main
+
+import (
+ "errors"
+ "flag"
+ "reflect"
+ "testing"
+)
+
+func TestParseReqParam(t *testing.T) {
+
+ testcases := []struct {
+ name string
+ expected map[string]string
+ request string
+ expectedError error
+ allowDeleteBodyV bool
+ allowMergeV bool
+ allowRepeatedFieldsInBodyV bool
+ includePackageInTagsV bool
+ fileV string
+ importPathV string
+ mergeFileNameV string
+ useFQNForOpenAPINameV bool
+ openAPINamingStrategyV string
+ }{
+ {
+ // this one must be first - with no leading clearFlags call it
+ // verifies our expectation of default values as we reset by
+ // clearFlags
+ name: "Test 0",
+ expected: map[string]string{},
+ request: "",
+ allowDeleteBodyV: false,
+ allowMergeV: false,
+ allowRepeatedFieldsInBodyV: false,
+ includePackageInTagsV: false,
+ fileV: "-",
+ importPathV: "",
+ mergeFileNameV: "apidocs",
+ },
+ {
+ name: "Test 1",
+ expected: map[string]string{"google/api/annotations.proto": "github.com/googleapis/googleapis/google/api"},
+ request: "allow_delete_body,allow_merge,allow_repeated_fields_in_body,include_package_in_tags,file=./foo.pb,import_prefix=/bar/baz,Mgoogle/api/annotations.proto=github.com/googleapis/googleapis/google/api",
+ allowDeleteBodyV: true,
+ allowMergeV: true,
+ allowRepeatedFieldsInBodyV: true,
+ includePackageInTagsV: true,
+ fileV: "./foo.pb",
+ importPathV: "/bar/baz",
+ mergeFileNameV: "apidocs",
+ },
+ {
+ name: "Test 2",
+ expected: map[string]string{"google/api/annotations.proto": "github.com/googleapis/googleapis/google/api"},
+ request: "allow_delete_body=true,allow_merge=true,allow_repeated_fields_in_body=true,include_package_in_tags=true,merge_file_name=test_name,file=./foo.pb,import_prefix=/bar/baz,Mgoogle/api/annotations.proto=github.com/googleapis/googleapis/google/api",
+ allowDeleteBodyV: true,
+ allowMergeV: true,
+ allowRepeatedFieldsInBodyV: true,
+ includePackageInTagsV: true,
+ fileV: "./foo.pb",
+ importPathV: "/bar/baz",
+ mergeFileNameV: "test_name",
+ },
+ {
+ name: "Test 3",
+ expected: map[string]string{"a/b/c.proto": "github.com/x/y/z", "f/g/h.proto": "github.com/1/2/3/"},
+ request: "allow_delete_body=false,allow_merge=false,Ma/b/c.proto=github.com/x/y/z,Mf/g/h.proto=github.com/1/2/3/",
+ allowDeleteBodyV: false,
+ allowMergeV: false,
+ allowRepeatedFieldsInBodyV: false,
+ includePackageInTagsV: false,
+ fileV: "stdin",
+ importPathV: "",
+ mergeFileNameV: "apidocs",
+ },
+ {
+ name: "Test 4",
+ expected: map[string]string{},
+ request: "",
+ allowDeleteBodyV: false,
+ allowMergeV: false,
+ allowRepeatedFieldsInBodyV: false,
+ includePackageInTagsV: false,
+ fileV: "stdin",
+ importPathV: "",
+ mergeFileNameV: "apidocs",
+ },
+ {
+ name: "Test 5",
+ expected: map[string]string{},
+ request: "unknown_param=17",
+ expectedError: errors.New("cannot set flag unknown_param=17: no such flag -unknown_param"),
+ allowDeleteBodyV: false,
+ allowMergeV: false,
+ allowRepeatedFieldsInBodyV: false,
+ includePackageInTagsV: false,
+ fileV: "stdin",
+ importPathV: "",
+ mergeFileNameV: "apidocs",
+ },
+ {
+ name: "Test 6",
+ expected: map[string]string{},
+ request: "Mfoo",
+ expectedError: errors.New("cannot set flag Mfoo: no such flag -Mfoo"),
+ allowDeleteBodyV: false,
+ allowMergeV: false,
+ allowRepeatedFieldsInBodyV: false,
+ includePackageInTagsV: false,
+ fileV: "stdin",
+ importPathV: "",
+ mergeFileNameV: "apidocs",
+ },
+ {
+ name: "Test 7",
+ expected: map[string]string{},
+ request: "allow_delete_body,file,import_prefix,allow_merge,allow_repeated_fields_in_body,include_package_in_tags,merge_file_name",
+ allowDeleteBodyV: true,
+ allowMergeV: true,
+ allowRepeatedFieldsInBodyV: true,
+ includePackageInTagsV: true,
+ fileV: "",
+ importPathV: "",
+ mergeFileNameV: "",
+ },
+ {
+ name: "Test 8",
+ expected: map[string]string{},
+ request: "allow_delete_body,file,import_prefix,allow_merge,allow_repeated_fields_in_body=3,merge_file_name",
+ expectedError: errors.New(`cannot set flag allow_repeated_fields_in_body=3: parse error`),
+ allowDeleteBodyV: true,
+ allowMergeV: true,
+ allowRepeatedFieldsInBodyV: false,
+ includePackageInTagsV: false,
+ fileV: "",
+ importPathV: "",
+ mergeFileNameV: "apidocs",
+ },
+ {
+ name: "Test 9",
+ expected: map[string]string{},
+ request: "include_package_in_tags=3",
+ expectedError: errors.New(`cannot set flag include_package_in_tags=3: parse error`),
+ allowDeleteBodyV: false,
+ allowMergeV: false,
+ allowRepeatedFieldsInBodyV: false,
+ includePackageInTagsV: false,
+ fileV: "stdin",
+ importPathV: "",
+ mergeFileNameV: "apidocs",
+ },
+ {
+ name: "Test 10",
+ expected: map[string]string{},
+ request: "fqn_for_openapi_name=3",
+ expectedError: errors.New(`cannot set flag fqn_for_openapi_name=3: parse error`),
+ allowDeleteBodyV: false,
+ allowMergeV: false,
+ allowRepeatedFieldsInBodyV: false,
+ includePackageInTagsV: false,
+ useFQNForOpenAPINameV: false,
+ fileV: "stdin",
+ importPathV: "",
+ mergeFileNameV: "apidocs",
+ },
+ {
+ name: "Test 11",
+ expected: map[string]string{},
+ request: "fqn_for_openapi_name=true",
+ allowDeleteBodyV: false,
+ allowMergeV: false,
+ allowRepeatedFieldsInBodyV: false,
+ includePackageInTagsV: false,
+ useFQNForOpenAPINameV: true,
+ fileV: "stdin",
+ importPathV: "",
+ mergeFileNameV: "apidocs",
+ },
+ {
+ name: "Test 12",
+ expected: map[string]string{},
+ request: "openapi_naming_strategy=simple",
+ allowDeleteBodyV: false,
+ allowMergeV: false,
+ allowRepeatedFieldsInBodyV: false,
+ includePackageInTagsV: false,
+ useFQNForOpenAPINameV: false,
+ openAPINamingStrategyV: "simple",
+ fileV: "stdin",
+ importPathV: "",
+ mergeFileNameV: "apidocs",
+ },
+ }
+
+ for i, tc := range testcases {
+ t.Run(tc.name, func(tt *testing.T) {
+ f := flag.CommandLine
+ pkgMap := make(map[string]string)
+ err := parseReqParam(tc.request, f, pkgMap)
+ if tc.expectedError == nil {
+ if err != nil {
+ tt.Errorf("unexpected parse error '%v'", err)
+ }
+ if !reflect.DeepEqual(pkgMap, tc.expected) {
+ tt.Errorf("pkgMap parse error, expected '%v', got '%v'", tc.expected, pkgMap)
+ }
+ } else {
+ if err == nil {
+ tt.Error("expected parse error not returned")
+ }
+ if !reflect.DeepEqual(pkgMap, tc.expected) {
+ tt.Errorf("pkgMap parse error, expected '%v', got '%v'", tc.expected, pkgMap)
+ }
+ if err.Error() != tc.expectedError.Error() {
+ tt.Errorf("expected error malformed, expected %q, got %q", tc.expectedError.Error(), err.Error())
+ }
+ }
+ checkFlags(tc.allowDeleteBodyV, tc.allowMergeV, tc.allowRepeatedFieldsInBodyV, tc.includePackageInTagsV, tc.useFQNForOpenAPINameV, tc.openAPINamingStrategyV, tc.fileV, tc.importPathV, tc.mergeFileNameV, tt, i)
+
+ clearFlags()
+ })
+ }
+}
+
+func checkFlags(
+ allowDeleteV,
+ allowMergeV,
+ allowRepeatedFieldsInBodyV,
+ includePackageInTagsV bool,
+ useFQNForOpenAPINameV bool,
+ openAPINamingStrategyV,
+ fileV,
+ importPathV,
+ mergeFileNameV string,
+ t *testing.T,
+ tid int,
+) {
+ if *importPrefix != importPathV {
+ t.Errorf("Test %v: import_prefix misparsed, expected '%v', got '%v'", tid, importPathV, *importPrefix)
+ }
+ if *file != fileV {
+ t.Errorf("Test %v: file misparsed, expected '%v', got '%v'", tid, fileV, *file)
+ }
+ if *allowDeleteBody != allowDeleteV {
+ t.Errorf("Test %v: allow_delete_body misparsed, expected '%v', got '%v'", tid, allowDeleteV, *allowDeleteBody)
+ }
+ if *allowMerge != allowMergeV {
+ t.Errorf("Test %v: allow_merge misparsed, expected '%v', got '%v'", tid, allowMergeV, *allowMerge)
+ }
+ if *mergeFileName != mergeFileNameV {
+ t.Errorf("Test %v: merge_file_name misparsed, expected '%v', got '%v'", tid, mergeFileNameV, *mergeFileName)
+ }
+ if *allowRepeatedFieldsInBody != allowRepeatedFieldsInBodyV {
+ t.Errorf("Test %v: allow_repeated_fields_in_body misparsed, expected '%v', got '%v'", tid, allowRepeatedFieldsInBodyV, *allowRepeatedFieldsInBody)
+ }
+ if *includePackageInTags != includePackageInTagsV {
+ t.Errorf("Test %v: include_package_in_tags misparsed, expected '%v', got '%v'", tid, includePackageInTagsV, *includePackageInTags)
+ }
+ if *useFQNForOpenAPIName != useFQNForOpenAPINameV {
+ t.Errorf("Test %v: fqn_for_openapi_name misparsed, expected '%v', got '%v'", tid, useFQNForOpenAPINameV, *useFQNForOpenAPIName)
+ }
+ if *openAPINamingStrategy != openAPINamingStrategyV {
+ t.Errorf("Test %v: openapi_naming_strategy misparsed, expected '%v', got '%v'", tid, openAPINamingStrategyV, *openAPINamingStrategy)
+ }
+}
+
+func clearFlags() {
+ *importPrefix = ""
+ *file = "stdin"
+ *allowDeleteBody = false
+ *allowMerge = false
+ *allowRepeatedFieldsInBody = false
+ *includePackageInTags = false
+ *mergeFileName = "apidocs"
+ *useFQNForOpenAPIName = false
+ *openAPINamingStrategy = ""
+}
diff --git a/gateway/protoc-gen-swagger/options/BUILD.bazel b/gateway/protoc-gen-openapiv2/options/BUILD.bazel
similarity index 65%
rename from gateway/protoc-gen-swagger/options/BUILD.bazel
rename to gateway/protoc-gen-openapiv2/options/BUILD.bazel
index 7c39c66..5cab09c 100644
--- a/gateway/protoc-gen-swagger/options/BUILD.bazel
+++ b/gateway/protoc-gen-openapiv2/options/BUILD.bazel
@@ -1,3 +1,4 @@
+load("@rules_proto//proto:defs.bzl", "proto_library")
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
@@ -12,9 +13,9 @@ filegroup(
)
go_library(
- name = "go_default_library",
+ name = "options",
embed = [":options_go_proto"],
- importpath = "github.com/binchencoder/ease-gateway/gateway/protoc-gen-swagger/options",
+ importpath = "github.com/binchencoder/janus-gateway/gateway/protoc-gen-openapiv2/options",
)
proto_library(
@@ -24,7 +25,6 @@ proto_library(
"openapiv2.proto",
],
deps = [
- "@com_google_protobuf//:any_proto",
"@com_google_protobuf//:descriptor_proto",
"@com_google_protobuf//:struct_proto",
],
@@ -32,7 +32,13 @@ proto_library(
go_proto_library(
name = "options_go_proto",
- compilers = ["@io_bazel_rules_go//proto:go_grpc"],
- importpath = "github.com/binchencoder/ease-gateway/gateway/protoc-gen-swagger/options",
+ compilers = ["//:go_apiv2"],
+ importpath = "github.com/binchencoder/janus-gateway/gateway/protoc-gen-openapiv2/options",
proto = ":options_proto",
)
+
+alias(
+ name = "go_default_library",
+ actual = ":options",
+ visibility = ["//visibility:public"],
+)
diff --git a/gateway/protoc-gen-openapiv2/options/annotations.pb.go b/gateway/protoc-gen-openapiv2/options/annotations.pb.go
new file mode 100755
index 0000000..7a0c232
--- /dev/null
+++ b/gateway/protoc-gen-openapiv2/options/annotations.pb.go
@@ -0,0 +1,212 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.27.1
+// protoc v3.19.4
+// source: gateway/protoc-gen-openapiv2/options/annotations.proto
+
+package options
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ descriptorpb "google.golang.org/protobuf/types/descriptorpb"
+ reflect "reflect"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+var file_gateway_protoc_gen_openapiv2_options_annotations_proto_extTypes = []protoimpl.ExtensionInfo{
+ {
+ ExtendedType: (*descriptorpb.FileOptions)(nil),
+ ExtensionType: (*Swagger)(nil),
+ Field: 1042,
+ Name: "grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger",
+ Tag: "bytes,1042,opt,name=openapiv2_swagger",
+ Filename: "gateway/protoc-gen-openapiv2/options/annotations.proto",
+ },
+ {
+ ExtendedType: (*descriptorpb.MethodOptions)(nil),
+ ExtensionType: (*Operation)(nil),
+ Field: 1042,
+ Name: "grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation",
+ Tag: "bytes,1042,opt,name=openapiv2_operation",
+ Filename: "gateway/protoc-gen-openapiv2/options/annotations.proto",
+ },
+ {
+ ExtendedType: (*descriptorpb.MessageOptions)(nil),
+ ExtensionType: (*Schema)(nil),
+ Field: 1042,
+ Name: "grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema",
+ Tag: "bytes,1042,opt,name=openapiv2_schema",
+ Filename: "gateway/protoc-gen-openapiv2/options/annotations.proto",
+ },
+ {
+ ExtendedType: (*descriptorpb.ServiceOptions)(nil),
+ ExtensionType: (*Tag)(nil),
+ Field: 1042,
+ Name: "grpc.gateway.protoc_gen_openapiv2.options.openapiv2_tag",
+ Tag: "bytes,1042,opt,name=openapiv2_tag",
+ Filename: "gateway/protoc-gen-openapiv2/options/annotations.proto",
+ },
+ {
+ ExtendedType: (*descriptorpb.FieldOptions)(nil),
+ ExtensionType: (*JSONSchema)(nil),
+ Field: 1042,
+ Name: "grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field",
+ Tag: "bytes,1042,opt,name=openapiv2_field",
+ Filename: "gateway/protoc-gen-openapiv2/options/annotations.proto",
+ },
+}
+
+// Extension fields to descriptorpb.FileOptions.
+var (
+ // optional grpc.gateway.protoc_gen_openapiv2.options.Swagger openapiv2_swagger = 1042;
+ E_Openapiv2Swagger = &file_gateway_protoc_gen_openapiv2_options_annotations_proto_extTypes[0]
+)
+
+// Extension fields to descriptorpb.MethodOptions.
+var (
+ // optional grpc.gateway.protoc_gen_openapiv2.options.Operation openapiv2_operation = 1042;
+ E_Openapiv2Operation = &file_gateway_protoc_gen_openapiv2_options_annotations_proto_extTypes[1]
+)
+
+// Extension fields to descriptorpb.MessageOptions.
+var (
+ // optional grpc.gateway.protoc_gen_openapiv2.options.Schema openapiv2_schema = 1042;
+ E_Openapiv2Schema = &file_gateway_protoc_gen_openapiv2_options_annotations_proto_extTypes[2]
+)
+
+// Extension fields to descriptorpb.ServiceOptions.
+var (
+ // optional grpc.gateway.protoc_gen_openapiv2.options.Tag openapiv2_tag = 1042;
+ E_Openapiv2Tag = &file_gateway_protoc_gen_openapiv2_options_annotations_proto_extTypes[3]
+)
+
+// Extension fields to descriptorpb.FieldOptions.
+var (
+ // optional grpc.gateway.protoc_gen_openapiv2.options.JSONSchema openapiv2_field = 1042;
+ E_Openapiv2Field = &file_gateway_protoc_gen_openapiv2_options_annotations_proto_extTypes[4]
+)
+
+var File_gateway_protoc_gen_openapiv2_options_annotations_proto protoreflect.FileDescriptor
+
+var file_gateway_protoc_gen_openapiv2_options_annotations_proto_rawDesc = []byte{
+ 0x0a, 0x36, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63,
+ 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2f, 0x6f,
+ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x29, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67,
+ 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65,
+ 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69,
+ 0x6f, 0x6e, 0x73, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x34, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2f, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,
+ 0x69, 0x76, 0x32, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x6f, 0x70, 0x65, 0x6e,
+ 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3a, 0x7e, 0x0a, 0x11, 0x6f,
+ 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x5f, 0x73, 0x77, 0x61, 0x67, 0x67, 0x65, 0x72,
+ 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
+ 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x92,
+ 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74,
+ 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f,
+ 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+ 0x73, 0x2e, 0x53, 0x77, 0x61, 0x67, 0x67, 0x65, 0x72, 0x52, 0x10, 0x6f, 0x70, 0x65, 0x6e, 0x61,
+ 0x70, 0x69, 0x76, 0x32, 0x53, 0x77, 0x61, 0x67, 0x67, 0x65, 0x72, 0x3a, 0x86, 0x01, 0x0a, 0x13,
+ 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69,
+ 0x6f, 0x6e, 0x73, 0x18, 0x92, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x67, 0x72, 0x70,
+ 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63,
+ 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f,
+ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x52, 0x12, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x4f, 0x70, 0x65, 0x72, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x7e, 0x0a, 0x10, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76,
+ 0x32, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+ 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61,
+ 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x92, 0x08, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x31, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61,
+ 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x63, 0x68,
+ 0x65, 0x6d, 0x61, 0x52, 0x0f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x53, 0x63,
+ 0x68, 0x65, 0x6d, 0x61, 0x3a, 0x75, 0x0a, 0x0d, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76,
+ 0x32, 0x5f, 0x74, 0x61, 0x67, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4f,
+ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x92, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e,
+ 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76,
+ 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x54, 0x61, 0x67, 0x52, 0x0c, 0x6f,
+ 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x54, 0x61, 0x67, 0x3a, 0x7e, 0x0a, 0x0f, 0x6f,
+ 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x1d,
+ 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+ 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x92, 0x08,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65,
+ 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f,
+ 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+ 0x2e, 0x4a, 0x53, 0x4f, 0x4e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x0e, 0x6f, 0x70, 0x65,
+ 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x4b, 0x5a, 0x49, 0x67,
+ 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x69, 0x6e, 0x63, 0x68, 0x65,
+ 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x65, 0x61, 0x73, 0x65, 0x2d, 0x67, 0x61, 0x74, 0x65,
+ 0x77, 0x61, 0x79, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2f, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32,
+ 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var file_gateway_protoc_gen_openapiv2_options_annotations_proto_goTypes = []interface{}{
+ (*descriptorpb.FileOptions)(nil), // 0: google.protobuf.FileOptions
+ (*descriptorpb.MethodOptions)(nil), // 1: google.protobuf.MethodOptions
+ (*descriptorpb.MessageOptions)(nil), // 2: google.protobuf.MessageOptions
+ (*descriptorpb.ServiceOptions)(nil), // 3: google.protobuf.ServiceOptions
+ (*descriptorpb.FieldOptions)(nil), // 4: google.protobuf.FieldOptions
+ (*Swagger)(nil), // 5: grpc.gateway.protoc_gen_openapiv2.options.Swagger
+ (*Operation)(nil), // 6: grpc.gateway.protoc_gen_openapiv2.options.Operation
+ (*Schema)(nil), // 7: grpc.gateway.protoc_gen_openapiv2.options.Schema
+ (*Tag)(nil), // 8: grpc.gateway.protoc_gen_openapiv2.options.Tag
+ (*JSONSchema)(nil), // 9: grpc.gateway.protoc_gen_openapiv2.options.JSONSchema
+}
+var file_gateway_protoc_gen_openapiv2_options_annotations_proto_depIdxs = []int32{
+ 0, // 0: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger:extendee -> google.protobuf.FileOptions
+ 1, // 1: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation:extendee -> google.protobuf.MethodOptions
+ 2, // 2: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema:extendee -> google.protobuf.MessageOptions
+ 3, // 3: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_tag:extendee -> google.protobuf.ServiceOptions
+ 4, // 4: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field:extendee -> google.protobuf.FieldOptions
+ 5, // 5: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Swagger
+ 6, // 6: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Operation
+ 7, // 7: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Schema
+ 8, // 8: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_tag:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Tag
+ 9, // 9: grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field:type_name -> grpc.gateway.protoc_gen_openapiv2.options.JSONSchema
+ 10, // [10:10] is the sub-list for method output_type
+ 10, // [10:10] is the sub-list for method input_type
+ 5, // [5:10] is the sub-list for extension type_name
+ 0, // [0:5] is the sub-list for extension extendee
+ 0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_gateway_protoc_gen_openapiv2_options_annotations_proto_init() }
+func file_gateway_protoc_gen_openapiv2_options_annotations_proto_init() {
+ if File_gateway_protoc_gen_openapiv2_options_annotations_proto != nil {
+ return
+ }
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_init()
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_gateway_protoc_gen_openapiv2_options_annotations_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 0,
+ NumExtensions: 5,
+ NumServices: 0,
+ },
+ GoTypes: file_gateway_protoc_gen_openapiv2_options_annotations_proto_goTypes,
+ DependencyIndexes: file_gateway_protoc_gen_openapiv2_options_annotations_proto_depIdxs,
+ ExtensionInfos: file_gateway_protoc_gen_openapiv2_options_annotations_proto_extTypes,
+ }.Build()
+ File_gateway_protoc_gen_openapiv2_options_annotations_proto = out.File
+ file_gateway_protoc_gen_openapiv2_options_annotations_proto_rawDesc = nil
+ file_gateway_protoc_gen_openapiv2_options_annotations_proto_goTypes = nil
+ file_gateway_protoc_gen_openapiv2_options_annotations_proto_depIdxs = nil
+}
diff --git a/gateway/protoc-gen-swagger/options/annotations.proto b/gateway/protoc-gen-openapiv2/options/annotations.proto
similarity index 80%
rename from gateway/protoc-gen-swagger/options/annotations.proto
rename to gateway/protoc-gen-openapiv2/options/annotations.proto
index 09a56b1..98b03fb 100644
--- a/gateway/protoc-gen-swagger/options/annotations.proto
+++ b/gateway/protoc-gen-openapiv2/options/annotations.proto
@@ -1,42 +1,42 @@
syntax = "proto3";
-package grpc.gateway.protoc_gen_swagger.options;
+package grpc.gateway.protoc_gen_openapiv2.options;
-option go_package = "github.com/binchencoder/ease-gateway/gateway/protoc-gen-swagger/options";
+option go_package = "github.com/binchencoder/janus-gateway/gateway/protoc-gen-openapiv2/options";
import "google/protobuf/descriptor.proto";
-import "gateway/protoc-gen-swagger/options/openapiv2.proto";
+import "gateway/protoc-gen-openapiv2/options/openapiv2.proto";
extend google.protobuf.FileOptions {
- // ID assigned by protobuf-global-extension-registry@google.com for grpc-gateway project.
+ // ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project.
//
// All IDs are the same, as assigned. It is okay that they are the same, as they extend
// different descriptor messages.
Swagger openapiv2_swagger = 1042;
}
extend google.protobuf.MethodOptions {
- // ID assigned by protobuf-global-extension-registry@google.com for grpc-gateway project.
+ // ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project.
//
// All IDs are the same, as assigned. It is okay that they are the same, as they extend
// different descriptor messages.
Operation openapiv2_operation = 1042;
}
extend google.protobuf.MessageOptions {
- // ID assigned by protobuf-global-extension-registry@google.com for grpc-gateway project.
+ // ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project.
//
// All IDs are the same, as assigned. It is okay that they are the same, as they extend
// different descriptor messages.
Schema openapiv2_schema = 1042;
}
extend google.protobuf.ServiceOptions {
- // ID assigned by protobuf-global-extension-registry@google.com for grpc-gateway project.
+ // ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project.
//
// All IDs are the same, as assigned. It is okay that they are the same, as they extend
// different descriptor messages.
Tag openapiv2_tag = 1042;
}
extend google.protobuf.FieldOptions {
- // ID assigned by protobuf-global-extension-registry@google.com for grpc-gateway project.
+ // ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project.
//
// All IDs are the same, as assigned. It is okay that they are the same, as they extend
// different descriptor messages.
diff --git a/gateway/protoc-gen-openapiv2/options/openapiv2.pb.go b/gateway/protoc-gen-openapiv2/options/openapiv2.pb.go
new file mode 100755
index 0000000..fceae2e
--- /dev/null
+++ b/gateway/protoc-gen-openapiv2/options/openapiv2.pb.go
@@ -0,0 +1,2411 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.27.1
+// protoc v3.19.4
+// source: gateway/protoc-gen-openapiv2/options/openapiv2.proto
+
+package options
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ structpb "google.golang.org/protobuf/types/known/structpb"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type Scheme int32
+
+const (
+ Scheme_UNKNOWN Scheme = 0
+ Scheme_HTTP Scheme = 1
+ Scheme_HTTPS Scheme = 2
+ Scheme_WS Scheme = 3
+ Scheme_WSS Scheme = 4
+)
+
+// Enum value maps for Scheme.
+var (
+ Scheme_name = map[int32]string{
+ 0: "UNKNOWN",
+ 1: "HTTP",
+ 2: "HTTPS",
+ 3: "WS",
+ 4: "WSS",
+ }
+ Scheme_value = map[string]int32{
+ "UNKNOWN": 0,
+ "HTTP": 1,
+ "HTTPS": 2,
+ "WS": 3,
+ "WSS": 4,
+ }
+)
+
+func (x Scheme) Enum() *Scheme {
+ p := new(Scheme)
+ *p = x
+ return p
+}
+
+func (x Scheme) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (Scheme) Descriptor() protoreflect.EnumDescriptor {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_enumTypes[0].Descriptor()
+}
+
+func (Scheme) Type() protoreflect.EnumType {
+ return &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_enumTypes[0]
+}
+
+func (x Scheme) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use Scheme.Descriptor instead.
+func (Scheme) EnumDescriptor() ([]byte, []int) {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescGZIP(), []int{0}
+}
+
+type JSONSchema_JSONSchemaSimpleTypes int32
+
+const (
+ JSONSchema_UNKNOWN JSONSchema_JSONSchemaSimpleTypes = 0
+ JSONSchema_ARRAY JSONSchema_JSONSchemaSimpleTypes = 1
+ JSONSchema_BOOLEAN JSONSchema_JSONSchemaSimpleTypes = 2
+ JSONSchema_INTEGER JSONSchema_JSONSchemaSimpleTypes = 3
+ JSONSchema_NULL JSONSchema_JSONSchemaSimpleTypes = 4
+ JSONSchema_NUMBER JSONSchema_JSONSchemaSimpleTypes = 5
+ JSONSchema_OBJECT JSONSchema_JSONSchemaSimpleTypes = 6
+ JSONSchema_STRING JSONSchema_JSONSchemaSimpleTypes = 7
+)
+
+// Enum value maps for JSONSchema_JSONSchemaSimpleTypes.
+var (
+ JSONSchema_JSONSchemaSimpleTypes_name = map[int32]string{
+ 0: "UNKNOWN",
+ 1: "ARRAY",
+ 2: "BOOLEAN",
+ 3: "INTEGER",
+ 4: "NULL",
+ 5: "NUMBER",
+ 6: "OBJECT",
+ 7: "STRING",
+ }
+ JSONSchema_JSONSchemaSimpleTypes_value = map[string]int32{
+ "UNKNOWN": 0,
+ "ARRAY": 1,
+ "BOOLEAN": 2,
+ "INTEGER": 3,
+ "NULL": 4,
+ "NUMBER": 5,
+ "OBJECT": 6,
+ "STRING": 7,
+ }
+)
+
+func (x JSONSchema_JSONSchemaSimpleTypes) Enum() *JSONSchema_JSONSchemaSimpleTypes {
+ p := new(JSONSchema_JSONSchemaSimpleTypes)
+ *p = x
+ return p
+}
+
+func (x JSONSchema_JSONSchemaSimpleTypes) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (JSONSchema_JSONSchemaSimpleTypes) Descriptor() protoreflect.EnumDescriptor {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_enumTypes[1].Descriptor()
+}
+
+func (JSONSchema_JSONSchemaSimpleTypes) Type() protoreflect.EnumType {
+ return &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_enumTypes[1]
+}
+
+func (x JSONSchema_JSONSchemaSimpleTypes) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use JSONSchema_JSONSchemaSimpleTypes.Descriptor instead.
+func (JSONSchema_JSONSchemaSimpleTypes) EnumDescriptor() ([]byte, []int) {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescGZIP(), []int{9, 0}
+}
+
+type SecurityScheme_Type int32
+
+const (
+ SecurityScheme_TYPE_INVALID SecurityScheme_Type = 0
+ SecurityScheme_TYPE_BASIC SecurityScheme_Type = 1
+ SecurityScheme_TYPE_API_KEY SecurityScheme_Type = 2
+ SecurityScheme_TYPE_OAUTH2 SecurityScheme_Type = 3
+)
+
+// Enum value maps for SecurityScheme_Type.
+var (
+ SecurityScheme_Type_name = map[int32]string{
+ 0: "TYPE_INVALID",
+ 1: "TYPE_BASIC",
+ 2: "TYPE_API_KEY",
+ 3: "TYPE_OAUTH2",
+ }
+ SecurityScheme_Type_value = map[string]int32{
+ "TYPE_INVALID": 0,
+ "TYPE_BASIC": 1,
+ "TYPE_API_KEY": 2,
+ "TYPE_OAUTH2": 3,
+ }
+)
+
+func (x SecurityScheme_Type) Enum() *SecurityScheme_Type {
+ p := new(SecurityScheme_Type)
+ *p = x
+ return p
+}
+
+func (x SecurityScheme_Type) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (SecurityScheme_Type) Descriptor() protoreflect.EnumDescriptor {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_enumTypes[2].Descriptor()
+}
+
+func (SecurityScheme_Type) Type() protoreflect.EnumType {
+ return &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_enumTypes[2]
+}
+
+func (x SecurityScheme_Type) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use SecurityScheme_Type.Descriptor instead.
+func (SecurityScheme_Type) EnumDescriptor() ([]byte, []int) {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescGZIP(), []int{12, 0}
+}
+
+type SecurityScheme_In int32
+
+const (
+ SecurityScheme_IN_INVALID SecurityScheme_In = 0
+ SecurityScheme_IN_QUERY SecurityScheme_In = 1
+ SecurityScheme_IN_HEADER SecurityScheme_In = 2
+)
+
+// Enum value maps for SecurityScheme_In.
+var (
+ SecurityScheme_In_name = map[int32]string{
+ 0: "IN_INVALID",
+ 1: "IN_QUERY",
+ 2: "IN_HEADER",
+ }
+ SecurityScheme_In_value = map[string]int32{
+ "IN_INVALID": 0,
+ "IN_QUERY": 1,
+ "IN_HEADER": 2,
+ }
+)
+
+func (x SecurityScheme_In) Enum() *SecurityScheme_In {
+ p := new(SecurityScheme_In)
+ *p = x
+ return p
+}
+
+func (x SecurityScheme_In) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (SecurityScheme_In) Descriptor() protoreflect.EnumDescriptor {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_enumTypes[3].Descriptor()
+}
+
+func (SecurityScheme_In) Type() protoreflect.EnumType {
+ return &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_enumTypes[3]
+}
+
+func (x SecurityScheme_In) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use SecurityScheme_In.Descriptor instead.
+func (SecurityScheme_In) EnumDescriptor() ([]byte, []int) {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescGZIP(), []int{12, 1}
+}
+
+type SecurityScheme_Flow int32
+
+const (
+ SecurityScheme_FLOW_INVALID SecurityScheme_Flow = 0
+ SecurityScheme_FLOW_IMPLICIT SecurityScheme_Flow = 1
+ SecurityScheme_FLOW_PASSWORD SecurityScheme_Flow = 2
+ SecurityScheme_FLOW_APPLICATION SecurityScheme_Flow = 3
+ SecurityScheme_FLOW_ACCESS_CODE SecurityScheme_Flow = 4
+)
+
+// Enum value maps for SecurityScheme_Flow.
+var (
+ SecurityScheme_Flow_name = map[int32]string{
+ 0: "FLOW_INVALID",
+ 1: "FLOW_IMPLICIT",
+ 2: "FLOW_PASSWORD",
+ 3: "FLOW_APPLICATION",
+ 4: "FLOW_ACCESS_CODE",
+ }
+ SecurityScheme_Flow_value = map[string]int32{
+ "FLOW_INVALID": 0,
+ "FLOW_IMPLICIT": 1,
+ "FLOW_PASSWORD": 2,
+ "FLOW_APPLICATION": 3,
+ "FLOW_ACCESS_CODE": 4,
+ }
+)
+
+func (x SecurityScheme_Flow) Enum() *SecurityScheme_Flow {
+ p := new(SecurityScheme_Flow)
+ *p = x
+ return p
+}
+
+func (x SecurityScheme_Flow) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (SecurityScheme_Flow) Descriptor() protoreflect.EnumDescriptor {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_enumTypes[4].Descriptor()
+}
+
+func (SecurityScheme_Flow) Type() protoreflect.EnumType {
+ return &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_enumTypes[4]
+}
+
+func (x SecurityScheme_Flow) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use SecurityScheme_Flow.Descriptor instead.
+func (SecurityScheme_Flow) EnumDescriptor() ([]byte, []int) {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescGZIP(), []int{12, 2}
+}
+
+type Swagger struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Swagger string `protobuf:"bytes,1,opt,name=swagger,proto3" json:"swagger,omitempty"`
+ Info *Info `protobuf:"bytes,2,opt,name=info,proto3" json:"info,omitempty"`
+ Host string `protobuf:"bytes,3,opt,name=host,proto3" json:"host,omitempty"`
+ BasePath string `protobuf:"bytes,4,opt,name=base_path,json=basePath,proto3" json:"base_path,omitempty"`
+ Schemes []Scheme `protobuf:"varint,5,rep,packed,name=schemes,proto3,enum=grpc.gateway.protoc_gen_openapiv2.options.Scheme" json:"schemes,omitempty"`
+ Consumes []string `protobuf:"bytes,6,rep,name=consumes,proto3" json:"consumes,omitempty"`
+ Produces []string `protobuf:"bytes,7,rep,name=produces,proto3" json:"produces,omitempty"`
+ Responses map[string]*Response `protobuf:"bytes,10,rep,name=responses,proto3" json:"responses,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ SecurityDefinitions *SecurityDefinitions `protobuf:"bytes,11,opt,name=security_definitions,json=securityDefinitions,proto3" json:"security_definitions,omitempty"`
+ Security []*SecurityRequirement `protobuf:"bytes,12,rep,name=security,proto3" json:"security,omitempty"`
+ ExternalDocs *ExternalDocumentation `protobuf:"bytes,14,opt,name=external_docs,json=externalDocs,proto3" json:"external_docs,omitempty"`
+ Extensions map[string]*structpb.Value `protobuf:"bytes,15,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+}
+
+func (x *Swagger) Reset() {
+ *x = Swagger{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Swagger) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Swagger) ProtoMessage() {}
+
+func (x *Swagger) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Swagger.ProtoReflect.Descriptor instead.
+func (*Swagger) Descriptor() ([]byte, []int) {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Swagger) GetSwagger() string {
+ if x != nil {
+ return x.Swagger
+ }
+ return ""
+}
+
+func (x *Swagger) GetInfo() *Info {
+ if x != nil {
+ return x.Info
+ }
+ return nil
+}
+
+func (x *Swagger) GetHost() string {
+ if x != nil {
+ return x.Host
+ }
+ return ""
+}
+
+func (x *Swagger) GetBasePath() string {
+ if x != nil {
+ return x.BasePath
+ }
+ return ""
+}
+
+func (x *Swagger) GetSchemes() []Scheme {
+ if x != nil {
+ return x.Schemes
+ }
+ return nil
+}
+
+func (x *Swagger) GetConsumes() []string {
+ if x != nil {
+ return x.Consumes
+ }
+ return nil
+}
+
+func (x *Swagger) GetProduces() []string {
+ if x != nil {
+ return x.Produces
+ }
+ return nil
+}
+
+func (x *Swagger) GetResponses() map[string]*Response {
+ if x != nil {
+ return x.Responses
+ }
+ return nil
+}
+
+func (x *Swagger) GetSecurityDefinitions() *SecurityDefinitions {
+ if x != nil {
+ return x.SecurityDefinitions
+ }
+ return nil
+}
+
+func (x *Swagger) GetSecurity() []*SecurityRequirement {
+ if x != nil {
+ return x.Security
+ }
+ return nil
+}
+
+func (x *Swagger) GetExternalDocs() *ExternalDocumentation {
+ if x != nil {
+ return x.ExternalDocs
+ }
+ return nil
+}
+
+func (x *Swagger) GetExtensions() map[string]*structpb.Value {
+ if x != nil {
+ return x.Extensions
+ }
+ return nil
+}
+
+type Operation struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Tags []string `protobuf:"bytes,1,rep,name=tags,proto3" json:"tags,omitempty"`
+ Summary string `protobuf:"bytes,2,opt,name=summary,proto3" json:"summary,omitempty"`
+ Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
+ ExternalDocs *ExternalDocumentation `protobuf:"bytes,4,opt,name=external_docs,json=externalDocs,proto3" json:"external_docs,omitempty"`
+ OperationId string `protobuf:"bytes,5,opt,name=operation_id,json=operationId,proto3" json:"operation_id,omitempty"`
+ Consumes []string `protobuf:"bytes,6,rep,name=consumes,proto3" json:"consumes,omitempty"`
+ Produces []string `protobuf:"bytes,7,rep,name=produces,proto3" json:"produces,omitempty"`
+ Responses map[string]*Response `protobuf:"bytes,9,rep,name=responses,proto3" json:"responses,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ Schemes []Scheme `protobuf:"varint,10,rep,packed,name=schemes,proto3,enum=grpc.gateway.protoc_gen_openapiv2.options.Scheme" json:"schemes,omitempty"`
+ Deprecated bool `protobuf:"varint,11,opt,name=deprecated,proto3" json:"deprecated,omitempty"`
+ Security []*SecurityRequirement `protobuf:"bytes,12,rep,name=security,proto3" json:"security,omitempty"`
+ Extensions map[string]*structpb.Value `protobuf:"bytes,13,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+}
+
+func (x *Operation) Reset() {
+ *x = Operation{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Operation) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Operation) ProtoMessage() {}
+
+func (x *Operation) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Operation.ProtoReflect.Descriptor instead.
+func (*Operation) Descriptor() ([]byte, []int) {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *Operation) GetTags() []string {
+ if x != nil {
+ return x.Tags
+ }
+ return nil
+}
+
+func (x *Operation) GetSummary() string {
+ if x != nil {
+ return x.Summary
+ }
+ return ""
+}
+
+func (x *Operation) GetDescription() string {
+ if x != nil {
+ return x.Description
+ }
+ return ""
+}
+
+func (x *Operation) GetExternalDocs() *ExternalDocumentation {
+ if x != nil {
+ return x.ExternalDocs
+ }
+ return nil
+}
+
+func (x *Operation) GetOperationId() string {
+ if x != nil {
+ return x.OperationId
+ }
+ return ""
+}
+
+func (x *Operation) GetConsumes() []string {
+ if x != nil {
+ return x.Consumes
+ }
+ return nil
+}
+
+func (x *Operation) GetProduces() []string {
+ if x != nil {
+ return x.Produces
+ }
+ return nil
+}
+
+func (x *Operation) GetResponses() map[string]*Response {
+ if x != nil {
+ return x.Responses
+ }
+ return nil
+}
+
+func (x *Operation) GetSchemes() []Scheme {
+ if x != nil {
+ return x.Schemes
+ }
+ return nil
+}
+
+func (x *Operation) GetDeprecated() bool {
+ if x != nil {
+ return x.Deprecated
+ }
+ return false
+}
+
+func (x *Operation) GetSecurity() []*SecurityRequirement {
+ if x != nil {
+ return x.Security
+ }
+ return nil
+}
+
+func (x *Operation) GetExtensions() map[string]*structpb.Value {
+ if x != nil {
+ return x.Extensions
+ }
+ return nil
+}
+
+type Header struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"`
+ Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
+ Format string `protobuf:"bytes,3,opt,name=format,proto3" json:"format,omitempty"`
+ Default string `protobuf:"bytes,6,opt,name=default,proto3" json:"default,omitempty"`
+ Pattern string `protobuf:"bytes,13,opt,name=pattern,proto3" json:"pattern,omitempty"`
+}
+
+func (x *Header) Reset() {
+ *x = Header{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Header) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Header) ProtoMessage() {}
+
+func (x *Header) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Header.ProtoReflect.Descriptor instead.
+func (*Header) Descriptor() ([]byte, []int) {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *Header) GetDescription() string {
+ if x != nil {
+ return x.Description
+ }
+ return ""
+}
+
+func (x *Header) GetType() string {
+ if x != nil {
+ return x.Type
+ }
+ return ""
+}
+
+func (x *Header) GetFormat() string {
+ if x != nil {
+ return x.Format
+ }
+ return ""
+}
+
+func (x *Header) GetDefault() string {
+ if x != nil {
+ return x.Default
+ }
+ return ""
+}
+
+func (x *Header) GetPattern() string {
+ if x != nil {
+ return x.Pattern
+ }
+ return ""
+}
+
+type Response struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"`
+ Schema *Schema `protobuf:"bytes,2,opt,name=schema,proto3" json:"schema,omitempty"`
+ Headers map[string]*Header `protobuf:"bytes,3,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ Examples map[string]string `protobuf:"bytes,4,rep,name=examples,proto3" json:"examples,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ Extensions map[string]*structpb.Value `protobuf:"bytes,5,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+}
+
+func (x *Response) Reset() {
+ *x = Response{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Response) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Response) ProtoMessage() {}
+
+func (x *Response) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Response.ProtoReflect.Descriptor instead.
+func (*Response) Descriptor() ([]byte, []int) {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *Response) GetDescription() string {
+ if x != nil {
+ return x.Description
+ }
+ return ""
+}
+
+func (x *Response) GetSchema() *Schema {
+ if x != nil {
+ return x.Schema
+ }
+ return nil
+}
+
+func (x *Response) GetHeaders() map[string]*Header {
+ if x != nil {
+ return x.Headers
+ }
+ return nil
+}
+
+func (x *Response) GetExamples() map[string]string {
+ if x != nil {
+ return x.Examples
+ }
+ return nil
+}
+
+func (x *Response) GetExtensions() map[string]*structpb.Value {
+ if x != nil {
+ return x.Extensions
+ }
+ return nil
+}
+
+type Info struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"`
+ Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
+ TermsOfService string `protobuf:"bytes,3,opt,name=terms_of_service,json=termsOfService,proto3" json:"terms_of_service,omitempty"`
+ Contact *Contact `protobuf:"bytes,4,opt,name=contact,proto3" json:"contact,omitempty"`
+ License *License `protobuf:"bytes,5,opt,name=license,proto3" json:"license,omitempty"`
+ Version string `protobuf:"bytes,6,opt,name=version,proto3" json:"version,omitempty"`
+ Extensions map[string]*structpb.Value `protobuf:"bytes,7,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+}
+
+func (x *Info) Reset() {
+ *x = Info{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Info) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Info) ProtoMessage() {}
+
+func (x *Info) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[4]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Info.ProtoReflect.Descriptor instead.
+func (*Info) Descriptor() ([]byte, []int) {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *Info) GetTitle() string {
+ if x != nil {
+ return x.Title
+ }
+ return ""
+}
+
+func (x *Info) GetDescription() string {
+ if x != nil {
+ return x.Description
+ }
+ return ""
+}
+
+func (x *Info) GetTermsOfService() string {
+ if x != nil {
+ return x.TermsOfService
+ }
+ return ""
+}
+
+func (x *Info) GetContact() *Contact {
+ if x != nil {
+ return x.Contact
+ }
+ return nil
+}
+
+func (x *Info) GetLicense() *License {
+ if x != nil {
+ return x.License
+ }
+ return nil
+}
+
+func (x *Info) GetVersion() string {
+ if x != nil {
+ return x.Version
+ }
+ return ""
+}
+
+func (x *Info) GetExtensions() map[string]*structpb.Value {
+ if x != nil {
+ return x.Extensions
+ }
+ return nil
+}
+
+type Contact struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+ Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"`
+ Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"`
+}
+
+func (x *Contact) Reset() {
+ *x = Contact{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Contact) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Contact) ProtoMessage() {}
+
+func (x *Contact) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[5]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Contact.ProtoReflect.Descriptor instead.
+func (*Contact) Descriptor() ([]byte, []int) {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *Contact) GetName() string {
+ if x != nil {
+ return x.Name
+ }
+ return ""
+}
+
+func (x *Contact) GetUrl() string {
+ if x != nil {
+ return x.Url
+ }
+ return ""
+}
+
+func (x *Contact) GetEmail() string {
+ if x != nil {
+ return x.Email
+ }
+ return ""
+}
+
+type License struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+ Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"`
+}
+
+func (x *License) Reset() {
+ *x = License{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[6]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *License) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*License) ProtoMessage() {}
+
+func (x *License) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[6]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use License.ProtoReflect.Descriptor instead.
+func (*License) Descriptor() ([]byte, []int) {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *License) GetName() string {
+ if x != nil {
+ return x.Name
+ }
+ return ""
+}
+
+func (x *License) GetUrl() string {
+ if x != nil {
+ return x.Url
+ }
+ return ""
+}
+
+type ExternalDocumentation struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"`
+ Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"`
+}
+
+func (x *ExternalDocumentation) Reset() {
+ *x = ExternalDocumentation{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[7]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ExternalDocumentation) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ExternalDocumentation) ProtoMessage() {}
+
+func (x *ExternalDocumentation) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[7]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ExternalDocumentation.ProtoReflect.Descriptor instead.
+func (*ExternalDocumentation) Descriptor() ([]byte, []int) {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *ExternalDocumentation) GetDescription() string {
+ if x != nil {
+ return x.Description
+ }
+ return ""
+}
+
+func (x *ExternalDocumentation) GetUrl() string {
+ if x != nil {
+ return x.Url
+ }
+ return ""
+}
+
+type Schema struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ JsonSchema *JSONSchema `protobuf:"bytes,1,opt,name=json_schema,json=jsonSchema,proto3" json:"json_schema,omitempty"`
+ Discriminator string `protobuf:"bytes,2,opt,name=discriminator,proto3" json:"discriminator,omitempty"`
+ ReadOnly bool `protobuf:"varint,3,opt,name=read_only,json=readOnly,proto3" json:"read_only,omitempty"`
+ ExternalDocs *ExternalDocumentation `protobuf:"bytes,5,opt,name=external_docs,json=externalDocs,proto3" json:"external_docs,omitempty"`
+ Example string `protobuf:"bytes,6,opt,name=example,proto3" json:"example,omitempty"`
+}
+
+func (x *Schema) Reset() {
+ *x = Schema{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[8]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Schema) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Schema) ProtoMessage() {}
+
+func (x *Schema) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[8]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Schema.ProtoReflect.Descriptor instead.
+func (*Schema) Descriptor() ([]byte, []int) {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescGZIP(), []int{8}
+}
+
+func (x *Schema) GetJsonSchema() *JSONSchema {
+ if x != nil {
+ return x.JsonSchema
+ }
+ return nil
+}
+
+func (x *Schema) GetDiscriminator() string {
+ if x != nil {
+ return x.Discriminator
+ }
+ return ""
+}
+
+func (x *Schema) GetReadOnly() bool {
+ if x != nil {
+ return x.ReadOnly
+ }
+ return false
+}
+
+func (x *Schema) GetExternalDocs() *ExternalDocumentation {
+ if x != nil {
+ return x.ExternalDocs
+ }
+ return nil
+}
+
+func (x *Schema) GetExample() string {
+ if x != nil {
+ return x.Example
+ }
+ return ""
+}
+
+type JSONSchema struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Ref string `protobuf:"bytes,3,opt,name=ref,proto3" json:"ref,omitempty"`
+ Title string `protobuf:"bytes,5,opt,name=title,proto3" json:"title,omitempty"`
+ Description string `protobuf:"bytes,6,opt,name=description,proto3" json:"description,omitempty"`
+ Default string `protobuf:"bytes,7,opt,name=default,proto3" json:"default,omitempty"`
+ ReadOnly bool `protobuf:"varint,8,opt,name=read_only,json=readOnly,proto3" json:"read_only,omitempty"`
+ Example string `protobuf:"bytes,9,opt,name=example,proto3" json:"example,omitempty"`
+ MultipleOf float64 `protobuf:"fixed64,10,opt,name=multiple_of,json=multipleOf,proto3" json:"multiple_of,omitempty"`
+ Maximum float64 `protobuf:"fixed64,11,opt,name=maximum,proto3" json:"maximum,omitempty"`
+ ExclusiveMaximum bool `protobuf:"varint,12,opt,name=exclusive_maximum,json=exclusiveMaximum,proto3" json:"exclusive_maximum,omitempty"`
+ Minimum float64 `protobuf:"fixed64,13,opt,name=minimum,proto3" json:"minimum,omitempty"`
+ ExclusiveMinimum bool `protobuf:"varint,14,opt,name=exclusive_minimum,json=exclusiveMinimum,proto3" json:"exclusive_minimum,omitempty"`
+ MaxLength uint64 `protobuf:"varint,15,opt,name=max_length,json=maxLength,proto3" json:"max_length,omitempty"`
+ MinLength uint64 `protobuf:"varint,16,opt,name=min_length,json=minLength,proto3" json:"min_length,omitempty"`
+ Pattern string `protobuf:"bytes,17,opt,name=pattern,proto3" json:"pattern,omitempty"`
+ MaxItems uint64 `protobuf:"varint,20,opt,name=max_items,json=maxItems,proto3" json:"max_items,omitempty"`
+ MinItems uint64 `protobuf:"varint,21,opt,name=min_items,json=minItems,proto3" json:"min_items,omitempty"`
+ UniqueItems bool `protobuf:"varint,22,opt,name=unique_items,json=uniqueItems,proto3" json:"unique_items,omitempty"`
+ MaxProperties uint64 `protobuf:"varint,24,opt,name=max_properties,json=maxProperties,proto3" json:"max_properties,omitempty"`
+ MinProperties uint64 `protobuf:"varint,25,opt,name=min_properties,json=minProperties,proto3" json:"min_properties,omitempty"`
+ Required []string `protobuf:"bytes,26,rep,name=required,proto3" json:"required,omitempty"`
+ Array []string `protobuf:"bytes,34,rep,name=array,proto3" json:"array,omitempty"`
+ Type []JSONSchema_JSONSchemaSimpleTypes `protobuf:"varint,35,rep,packed,name=type,proto3,enum=grpc.gateway.protoc_gen_openapiv2.options.JSONSchema_JSONSchemaSimpleTypes" json:"type,omitempty"`
+ Format string `protobuf:"bytes,36,opt,name=format,proto3" json:"format,omitempty"`
+ Enum []string `protobuf:"bytes,46,rep,name=enum,proto3" json:"enum,omitempty"`
+}
+
+func (x *JSONSchema) Reset() {
+ *x = JSONSchema{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[9]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *JSONSchema) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*JSONSchema) ProtoMessage() {}
+
+func (x *JSONSchema) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[9]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use JSONSchema.ProtoReflect.Descriptor instead.
+func (*JSONSchema) Descriptor() ([]byte, []int) {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescGZIP(), []int{9}
+}
+
+func (x *JSONSchema) GetRef() string {
+ if x != nil {
+ return x.Ref
+ }
+ return ""
+}
+
+func (x *JSONSchema) GetTitle() string {
+ if x != nil {
+ return x.Title
+ }
+ return ""
+}
+
+func (x *JSONSchema) GetDescription() string {
+ if x != nil {
+ return x.Description
+ }
+ return ""
+}
+
+func (x *JSONSchema) GetDefault() string {
+ if x != nil {
+ return x.Default
+ }
+ return ""
+}
+
+func (x *JSONSchema) GetReadOnly() bool {
+ if x != nil {
+ return x.ReadOnly
+ }
+ return false
+}
+
+func (x *JSONSchema) GetExample() string {
+ if x != nil {
+ return x.Example
+ }
+ return ""
+}
+
+func (x *JSONSchema) GetMultipleOf() float64 {
+ if x != nil {
+ return x.MultipleOf
+ }
+ return 0
+}
+
+func (x *JSONSchema) GetMaximum() float64 {
+ if x != nil {
+ return x.Maximum
+ }
+ return 0
+}
+
+func (x *JSONSchema) GetExclusiveMaximum() bool {
+ if x != nil {
+ return x.ExclusiveMaximum
+ }
+ return false
+}
+
+func (x *JSONSchema) GetMinimum() float64 {
+ if x != nil {
+ return x.Minimum
+ }
+ return 0
+}
+
+func (x *JSONSchema) GetExclusiveMinimum() bool {
+ if x != nil {
+ return x.ExclusiveMinimum
+ }
+ return false
+}
+
+func (x *JSONSchema) GetMaxLength() uint64 {
+ if x != nil {
+ return x.MaxLength
+ }
+ return 0
+}
+
+func (x *JSONSchema) GetMinLength() uint64 {
+ if x != nil {
+ return x.MinLength
+ }
+ return 0
+}
+
+func (x *JSONSchema) GetPattern() string {
+ if x != nil {
+ return x.Pattern
+ }
+ return ""
+}
+
+func (x *JSONSchema) GetMaxItems() uint64 {
+ if x != nil {
+ return x.MaxItems
+ }
+ return 0
+}
+
+func (x *JSONSchema) GetMinItems() uint64 {
+ if x != nil {
+ return x.MinItems
+ }
+ return 0
+}
+
+func (x *JSONSchema) GetUniqueItems() bool {
+ if x != nil {
+ return x.UniqueItems
+ }
+ return false
+}
+
+func (x *JSONSchema) GetMaxProperties() uint64 {
+ if x != nil {
+ return x.MaxProperties
+ }
+ return 0
+}
+
+func (x *JSONSchema) GetMinProperties() uint64 {
+ if x != nil {
+ return x.MinProperties
+ }
+ return 0
+}
+
+func (x *JSONSchema) GetRequired() []string {
+ if x != nil {
+ return x.Required
+ }
+ return nil
+}
+
+func (x *JSONSchema) GetArray() []string {
+ if x != nil {
+ return x.Array
+ }
+ return nil
+}
+
+func (x *JSONSchema) GetType() []JSONSchema_JSONSchemaSimpleTypes {
+ if x != nil {
+ return x.Type
+ }
+ return nil
+}
+
+func (x *JSONSchema) GetFormat() string {
+ if x != nil {
+ return x.Format
+ }
+ return ""
+}
+
+func (x *JSONSchema) GetEnum() []string {
+ if x != nil {
+ return x.Enum
+ }
+ return nil
+}
+
+type Tag struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
+ ExternalDocs *ExternalDocumentation `protobuf:"bytes,3,opt,name=external_docs,json=externalDocs,proto3" json:"external_docs,omitempty"`
+}
+
+func (x *Tag) Reset() {
+ *x = Tag{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[10]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Tag) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Tag) ProtoMessage() {}
+
+func (x *Tag) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[10]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Tag.ProtoReflect.Descriptor instead.
+func (*Tag) Descriptor() ([]byte, []int) {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescGZIP(), []int{10}
+}
+
+func (x *Tag) GetDescription() string {
+ if x != nil {
+ return x.Description
+ }
+ return ""
+}
+
+func (x *Tag) GetExternalDocs() *ExternalDocumentation {
+ if x != nil {
+ return x.ExternalDocs
+ }
+ return nil
+}
+
+type SecurityDefinitions struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Security map[string]*SecurityScheme `protobuf:"bytes,1,rep,name=security,proto3" json:"security,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+}
+
+func (x *SecurityDefinitions) Reset() {
+ *x = SecurityDefinitions{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[11]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SecurityDefinitions) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SecurityDefinitions) ProtoMessage() {}
+
+func (x *SecurityDefinitions) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[11]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use SecurityDefinitions.ProtoReflect.Descriptor instead.
+func (*SecurityDefinitions) Descriptor() ([]byte, []int) {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescGZIP(), []int{11}
+}
+
+func (x *SecurityDefinitions) GetSecurity() map[string]*SecurityScheme {
+ if x != nil {
+ return x.Security
+ }
+ return nil
+}
+
+type SecurityScheme struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Type SecurityScheme_Type `protobuf:"varint,1,opt,name=type,proto3,enum=grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme_Type" json:"type,omitempty"`
+ Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
+ Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
+ In SecurityScheme_In `protobuf:"varint,4,opt,name=in,proto3,enum=grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme_In" json:"in,omitempty"`
+ Flow SecurityScheme_Flow `protobuf:"varint,5,opt,name=flow,proto3,enum=grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme_Flow" json:"flow,omitempty"`
+ AuthorizationUrl string `protobuf:"bytes,6,opt,name=authorization_url,json=authorizationUrl,proto3" json:"authorization_url,omitempty"`
+ TokenUrl string `protobuf:"bytes,7,opt,name=token_url,json=tokenUrl,proto3" json:"token_url,omitempty"`
+ Scopes *Scopes `protobuf:"bytes,8,opt,name=scopes,proto3" json:"scopes,omitempty"`
+ Extensions map[string]*structpb.Value `protobuf:"bytes,9,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+}
+
+func (x *SecurityScheme) Reset() {
+ *x = SecurityScheme{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[12]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SecurityScheme) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SecurityScheme) ProtoMessage() {}
+
+func (x *SecurityScheme) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[12]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use SecurityScheme.ProtoReflect.Descriptor instead.
+func (*SecurityScheme) Descriptor() ([]byte, []int) {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescGZIP(), []int{12}
+}
+
+func (x *SecurityScheme) GetType() SecurityScheme_Type {
+ if x != nil {
+ return x.Type
+ }
+ return SecurityScheme_TYPE_INVALID
+}
+
+func (x *SecurityScheme) GetDescription() string {
+ if x != nil {
+ return x.Description
+ }
+ return ""
+}
+
+func (x *SecurityScheme) GetName() string {
+ if x != nil {
+ return x.Name
+ }
+ return ""
+}
+
+func (x *SecurityScheme) GetIn() SecurityScheme_In {
+ if x != nil {
+ return x.In
+ }
+ return SecurityScheme_IN_INVALID
+}
+
+func (x *SecurityScheme) GetFlow() SecurityScheme_Flow {
+ if x != nil {
+ return x.Flow
+ }
+ return SecurityScheme_FLOW_INVALID
+}
+
+func (x *SecurityScheme) GetAuthorizationUrl() string {
+ if x != nil {
+ return x.AuthorizationUrl
+ }
+ return ""
+}
+
+func (x *SecurityScheme) GetTokenUrl() string {
+ if x != nil {
+ return x.TokenUrl
+ }
+ return ""
+}
+
+func (x *SecurityScheme) GetScopes() *Scopes {
+ if x != nil {
+ return x.Scopes
+ }
+ return nil
+}
+
+func (x *SecurityScheme) GetExtensions() map[string]*structpb.Value {
+ if x != nil {
+ return x.Extensions
+ }
+ return nil
+}
+
+type SecurityRequirement struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ SecurityRequirement map[string]*SecurityRequirement_SecurityRequirementValue `protobuf:"bytes,1,rep,name=security_requirement,json=securityRequirement,proto3" json:"security_requirement,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+}
+
+func (x *SecurityRequirement) Reset() {
+ *x = SecurityRequirement{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[13]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SecurityRequirement) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SecurityRequirement) ProtoMessage() {}
+
+func (x *SecurityRequirement) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[13]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use SecurityRequirement.ProtoReflect.Descriptor instead.
+func (*SecurityRequirement) Descriptor() ([]byte, []int) {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescGZIP(), []int{13}
+}
+
+func (x *SecurityRequirement) GetSecurityRequirement() map[string]*SecurityRequirement_SecurityRequirementValue {
+ if x != nil {
+ return x.SecurityRequirement
+ }
+ return nil
+}
+
+type Scopes struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Scope map[string]string `protobuf:"bytes,1,rep,name=scope,proto3" json:"scope,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+}
+
+func (x *Scopes) Reset() {
+ *x = Scopes{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[14]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Scopes) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Scopes) ProtoMessage() {}
+
+func (x *Scopes) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[14]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Scopes.ProtoReflect.Descriptor instead.
+func (*Scopes) Descriptor() ([]byte, []int) {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescGZIP(), []int{14}
+}
+
+func (x *Scopes) GetScope() map[string]string {
+ if x != nil {
+ return x.Scope
+ }
+ return nil
+}
+
+type SecurityRequirement_SecurityRequirementValue struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Scope []string `protobuf:"bytes,1,rep,name=scope,proto3" json:"scope,omitempty"`
+}
+
+func (x *SecurityRequirement_SecurityRequirementValue) Reset() {
+ *x = SecurityRequirement_SecurityRequirementValue{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[25]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SecurityRequirement_SecurityRequirementValue) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SecurityRequirement_SecurityRequirementValue) ProtoMessage() {}
+
+func (x *SecurityRequirement_SecurityRequirementValue) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[25]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use SecurityRequirement_SecurityRequirementValue.ProtoReflect.Descriptor instead.
+func (*SecurityRequirement_SecurityRequirementValue) Descriptor() ([]byte, []int) {
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescGZIP(), []int{13, 0}
+}
+
+func (x *SecurityRequirement_SecurityRequirementValue) GetScope() []string {
+ if x != nil {
+ return x.Scope
+ }
+ return nil
+}
+
+var File_gateway_protoc_gen_openapiv2_options_openapiv2_proto protoreflect.FileDescriptor
+
+var file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDesc = []byte{
+ 0x0a, 0x34, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63,
+ 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2f, 0x6f,
+ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x29, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74,
+ 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f,
+ 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+ 0x73, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
+ 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
+ 0xf5, 0x07, 0x0a, 0x07, 0x53, 0x77, 0x61, 0x67, 0x67, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x73,
+ 0x77, 0x61, 0x67, 0x67, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x77,
+ 0x61, 0x67, 0x67, 0x65, 0x72, 0x12, 0x43, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77,
+ 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70,
+ 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e,
+ 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f,
+ 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x1b,
+ 0x0a, 0x09, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x08, 0x62, 0x61, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x4b, 0x0a, 0x07, 0x73,
+ 0x63, 0x68, 0x65, 0x6d, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x67,
+ 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32,
+ 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x52,
+ 0x07, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x73,
+ 0x75, 0x6d, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x73,
+ 0x75, 0x6d, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x73,
+ 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x73,
+ 0x12, 0x5f, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x0a, 0x20,
+ 0x03, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77,
+ 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70,
+ 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e,
+ 0x53, 0x77, 0x61, 0x67, 0x67, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+ 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+ 0x73, 0x12, 0x71, 0x0a, 0x14, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x64, 0x65,
+ 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x3e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,
+ 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x65, 0x63, 0x75,
+ 0x72, 0x69, 0x74, 0x79, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52,
+ 0x13, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74,
+ 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x5a, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,
+ 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61,
+ 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e,
+ 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f,
+ 0x6e, 0x73, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x69,
+ 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,
+ 0x12, 0x65, 0x0a, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x64, 0x6f, 0x63,
+ 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67,
+ 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65,
+ 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69,
+ 0x6f, 0x6e, 0x73, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6f, 0x63, 0x75,
+ 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72,
+ 0x6e, 0x61, 0x6c, 0x44, 0x6f, 0x63, 0x73, 0x12, 0x62, 0x0a, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e,
+ 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x67, 0x72,
+ 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e,
+ 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x77, 0x61, 0x67, 0x67, 0x65, 0x72, 0x2e,
+ 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
+ 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x71, 0x0a, 0x0e, 0x52,
+ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
+ 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
+ 0x49, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33,
+ 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,
+ 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f,
+ 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x55,
+ 0x0a, 0x0f, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72,
+ 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
+ 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
+ 0x65, 0x3a, 0x02, 0x38, 0x01, 0x4a, 0x04, 0x08, 0x08, 0x10, 0x09, 0x4a, 0x04, 0x08, 0x09, 0x10,
+ 0x0a, 0x4a, 0x04, 0x08, 0x0d, 0x10, 0x0e, 0x22, 0xff, 0x06, 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x01, 0x20,
+ 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d,
+ 0x6d, 0x61, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d,
+ 0x61, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
+ 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
+ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x65, 0x0a, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61,
+ 0x6c, 0x5f, 0x64, 0x6f, 0x63, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x67,
+ 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32,
+ 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61,
+ 0x6c, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c,
+ 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6f, 0x63, 0x73, 0x12, 0x21, 0x0a, 0x0c,
+ 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12,
+ 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28,
+ 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70,
+ 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70,
+ 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x73, 0x12, 0x61, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f,
+ 0x6e, 0x73, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x67, 0x72, 0x70,
+ 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63,
+ 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f,
+ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
+ 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x12, 0x4b, 0x0a, 0x07, 0x73, 0x63,
+ 0x68, 0x65, 0x6d, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x67, 0x72,
+ 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e,
+ 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x52, 0x07,
+ 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65,
+ 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65, 0x70,
+ 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x5a, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72,
+ 0x69, 0x74, 0x79, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x67, 0x72, 0x70, 0x63,
+ 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f,
+ 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70,
+ 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x65,
+ 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72,
+ 0x69, 0x74, 0x79, 0x12, 0x64, 0x0a, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
+ 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x44, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67,
+ 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65,
+ 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69,
+ 0x6f, 0x6e, 0x73, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x78,
+ 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x65,
+ 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x71, 0x0a, 0x0e, 0x52, 0x65, 0x73,
+ 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b,
+ 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x49, 0x0a,
+ 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67,
+ 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32,
+ 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+ 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x55, 0x0a, 0x0f,
+ 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
+ 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
+ 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
+ 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a,
+ 0x02, 0x38, 0x01, 0x4a, 0x04, 0x08, 0x08, 0x10, 0x09, 0x22, 0xd8, 0x01, 0x0a, 0x06, 0x48, 0x65,
+ 0x61, 0x64, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,
+ 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f,
+ 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d,
+ 0x61, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x06, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x18, 0x0a, 0x07,
+ 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70,
+ 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x05,
+ 0x10, 0x06, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x4a, 0x04, 0x08, 0x08, 0x10, 0x09, 0x4a, 0x04,
+ 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x0a, 0x10, 0x0b, 0x4a, 0x04, 0x08, 0x0b, 0x10, 0x0c,
+ 0x4a, 0x04, 0x08, 0x0c, 0x10, 0x0d, 0x4a, 0x04, 0x08, 0x0e, 0x10, 0x0f, 0x4a, 0x04, 0x08, 0x0f,
+ 0x10, 0x10, 0x4a, 0x04, 0x08, 0x10, 0x10, 0x11, 0x4a, 0x04, 0x08, 0x11, 0x10, 0x12, 0x4a, 0x04,
+ 0x08, 0x12, 0x10, 0x13, 0x22, 0x9a, 0x05, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+ 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x12, 0x49, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77,
+ 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70,
+ 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e,
+ 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x5a,
+ 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32,
+ 0x40, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,
+ 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x70,
+ 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72,
+ 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x5d, 0x0a, 0x08, 0x65, 0x78,
+ 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x67,
+ 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32,
+ 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+ 0x65, 0x2e, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
+ 0x08, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0x63, 0x0a, 0x0a, 0x65, 0x78, 0x74,
+ 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x43, 0x2e,
+ 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76,
+ 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+ 0x73, 0x65, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74,
+ 0x72, 0x79, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x6d,
+ 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10,
+ 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79,
+ 0x12, 0x47, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x31, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,
+ 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x64,
+ 0x65, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3b, 0x0a,
+ 0x0d, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10,
+ 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79,
+ 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x55, 0x0a, 0x0f, 0x45, 0x78,
+ 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
+ 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
+ 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16,
+ 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+ 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
+ 0x01, 0x22, 0xd6, 0x03, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69,
+ 0x74, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65,
+ 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
+ 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x5f, 0x6f, 0x66, 0x5f, 0x73,
+ 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x65,
+ 0x72, 0x6d, 0x73, 0x4f, 0x66, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4c, 0x0a, 0x07,
+ 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e,
+ 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76,
+ 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63,
+ 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, 0x4c, 0x0a, 0x07, 0x6c, 0x69,
+ 0x63, 0x65, 0x6e, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x67, 0x72,
+ 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e,
+ 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x52,
+ 0x07, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73,
+ 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69,
+ 0x6f, 0x6e, 0x12, 0x5f, 0x0a, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73,
+ 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61,
+ 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e,
+ 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f,
+ 0x6e, 0x73, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,
+ 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,
+ 0x6f, 0x6e, 0x73, 0x1a, 0x55, 0x0a, 0x0f, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
+ 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
+ 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52,
+ 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x45, 0x0a, 0x07, 0x43, 0x6f,
+ 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x65,
+ 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69,
+ 0x6c, 0x22, 0x2f, 0x0a, 0x07, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04,
+ 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
+ 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75,
+ 0x72, 0x6c, 0x22, 0x4b, 0x0a, 0x15, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6f,
+ 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64,
+ 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a,
+ 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22,
+ 0xaa, 0x02, 0x0a, 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x56, 0x0a, 0x0b, 0x6a, 0x73,
+ 0x6f, 0x6e, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x35, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,
+ 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4a, 0x53, 0x4f, 0x4e,
+ 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x0a, 0x6a, 0x73, 0x6f, 0x6e, 0x53, 0x63, 0x68, 0x65,
+ 0x6d, 0x61, 0x12, 0x24, 0x0a, 0x0d, 0x64, 0x69, 0x73, 0x63, 0x72, 0x69, 0x6d, 0x69, 0x6e, 0x61,
+ 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x69, 0x73, 0x63, 0x72,
+ 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x61, 0x64,
+ 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x61,
+ 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x65, 0x0a, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61,
+ 0x6c, 0x5f, 0x64, 0x6f, 0x63, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x67,
+ 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32,
+ 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61,
+ 0x6c, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c,
+ 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6f, 0x63, 0x73, 0x12, 0x18, 0x0a, 0x07,
+ 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65,
+ 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0xdf, 0x07, 0x0a,
+ 0x0a, 0x4a, 0x53, 0x4f, 0x4e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x72,
+ 0x65, 0x66, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x72, 0x65, 0x66, 0x12, 0x14, 0x0a,
+ 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69,
+ 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
+ 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
+ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74,
+ 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12,
+ 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x08, 0x20, 0x01,
+ 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x61, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07,
+ 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65,
+ 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70,
+ 0x6c, 0x65, 0x5f, 0x6f, 0x66, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0a, 0x6d, 0x75, 0x6c,
+ 0x74, 0x69, 0x70, 0x6c, 0x65, 0x4f, 0x66, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x69, 0x6d,
+ 0x75, 0x6d, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75,
+ 0x6d, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x6d,
+ 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x78,
+ 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x4d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x18,
+ 0x0a, 0x07, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x01, 0x52,
+ 0x07, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x63, 0x6c,
+ 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x0e, 0x20,
+ 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x4d, 0x69,
+ 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x65, 0x6e,
+ 0x67, 0x74, 0x68, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x6d, 0x61, 0x78, 0x4c, 0x65,
+ 0x6e, 0x67, 0x74, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x69, 0x6e, 0x5f, 0x6c, 0x65, 0x6e, 0x67,
+ 0x74, 0x68, 0x18, 0x10, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x6d, 0x69, 0x6e, 0x4c, 0x65, 0x6e,
+ 0x67, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 0x11,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x12, 0x1b, 0x0a,
+ 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x04,
+ 0x52, 0x08, 0x6d, 0x61, 0x78, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x69,
+ 0x6e, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x15, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6d,
+ 0x69, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x6e, 0x69, 0x71, 0x75,
+ 0x65, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x16, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x75,
+ 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x61,
+ 0x78, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x18, 0x20, 0x01,
+ 0x28, 0x04, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65,
+ 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x69, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74,
+ 0x69, 0x65, 0x73, 0x18, 0x19, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6d, 0x69, 0x6e, 0x50, 0x72,
+ 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75,
+ 0x69, 0x72, 0x65, 0x64, 0x18, 0x1a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75,
+ 0x69, 0x72, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x72, 0x72, 0x61, 0x79, 0x18, 0x22, 0x20,
+ 0x03, 0x28, 0x09, 0x52, 0x05, 0x61, 0x72, 0x72, 0x61, 0x79, 0x12, 0x5f, 0x0a, 0x04, 0x74, 0x79,
+ 0x70, 0x65, 0x18, 0x23, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x4b, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e,
+ 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67,
+ 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4a, 0x53, 0x4f, 0x4e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e,
+ 0x4a, 0x53, 0x4f, 0x4e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65,
+ 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x66,
+ 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x24, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x72,
+ 0x6d, 0x61, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x6e, 0x75, 0x6d, 0x18, 0x2e, 0x20, 0x03, 0x28,
+ 0x09, 0x52, 0x04, 0x65, 0x6e, 0x75, 0x6d, 0x22, 0x77, 0x0a, 0x15, 0x4a, 0x53, 0x4f, 0x4e, 0x53,
+ 0x63, 0x68, 0x65, 0x6d, 0x61, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73,
+ 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x09, 0x0a,
+ 0x05, 0x41, 0x52, 0x52, 0x41, 0x59, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x42, 0x4f, 0x4f, 0x4c,
+ 0x45, 0x41, 0x4e, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52,
+ 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x55, 0x4c, 0x4c, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06,
+ 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x10, 0x05, 0x12, 0x0a, 0x0a, 0x06, 0x4f, 0x42, 0x4a, 0x45,
+ 0x43, 0x54, 0x10, 0x06, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x07,
+ 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x04,
+ 0x10, 0x05, 0x4a, 0x04, 0x08, 0x12, 0x10, 0x13, 0x4a, 0x04, 0x08, 0x13, 0x10, 0x14, 0x4a, 0x04,
+ 0x08, 0x17, 0x10, 0x18, 0x4a, 0x04, 0x08, 0x1b, 0x10, 0x1c, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d,
+ 0x4a, 0x04, 0x08, 0x1d, 0x10, 0x1e, 0x4a, 0x04, 0x08, 0x1e, 0x10, 0x22, 0x4a, 0x04, 0x08, 0x25,
+ 0x10, 0x2a, 0x4a, 0x04, 0x08, 0x2a, 0x10, 0x2b, 0x4a, 0x04, 0x08, 0x2b, 0x10, 0x2e, 0x22, 0x94,
+ 0x01, 0x0a, 0x03, 0x54, 0x61, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
+ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73,
+ 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x65, 0x0a, 0x0d, 0x65, 0x78, 0x74, 0x65,
+ 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x64, 0x6f, 0x63, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x40, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,
+ 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x45, 0x78, 0x74, 0x65,
+ 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x52, 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6f, 0x63, 0x73, 0x4a,
+ 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0xf7, 0x01, 0x0a, 0x13, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69,
+ 0x74, 0x79, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x68, 0x0a,
+ 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
+ 0x4c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,
+ 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x65, 0x63, 0x75,
+ 0x72, 0x69, 0x74, 0x79, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e,
+ 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x73,
+ 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x1a, 0x76, 0x0a, 0x0d, 0x53, 0x65, 0x63, 0x75, 0x72,
+ 0x69, 0x74, 0x79, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x4f, 0x0a, 0x05, 0x76, 0x61,
+ 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x67, 0x72, 0x70, 0x63,
+ 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f,
+ 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70,
+ 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x53, 0x63,
+ 0x68, 0x65, 0x6d, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22,
+ 0xff, 0x06, 0x0a, 0x0e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x53, 0x63, 0x68, 0x65,
+ 0x6d, 0x65, 0x12, 0x52, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
+ 0x32, 0x3e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61,
+ 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x65, 0x63,
+ 0x75, 0x72, 0x69, 0x74, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65,
+ 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
+ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73,
+ 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x4c, 0x0a, 0x02,
+ 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e,
+ 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67,
+ 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x53, 0x63, 0x68,
+ 0x65, 0x6d, 0x65, 0x2e, 0x49, 0x6e, 0x52, 0x02, 0x69, 0x6e, 0x12, 0x52, 0x0a, 0x04, 0x66, 0x6c,
+ 0x6f, 0x77, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e,
+ 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67,
+ 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x53, 0x63, 0x68,
+ 0x65, 0x6d, 0x65, 0x2e, 0x46, 0x6c, 0x6f, 0x77, 0x52, 0x04, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x2b,
+ 0x0a, 0x11, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f,
+ 0x75, 0x72, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x61, 0x75, 0x74, 0x68, 0x6f,
+ 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x72, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x74,
+ 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
+ 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x55, 0x72, 0x6c, 0x12, 0x49, 0x0a, 0x06, 0x73, 0x63, 0x6f, 0x70,
+ 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e,
+ 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67,
+ 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x52, 0x06, 0x73, 0x63, 0x6f,
+ 0x70, 0x65, 0x73, 0x12, 0x69, 0x0a, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
+ 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x49, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67,
+ 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65,
+ 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69,
+ 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x53, 0x63, 0x68, 0x65,
+ 0x6d, 0x65, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74,
+ 0x72, 0x79, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x55,
+ 0x0a, 0x0f, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72,
+ 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
+ 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
+ 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4b, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a,
+ 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12,
+ 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x01, 0x12,
+ 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x10,
+ 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, 0x41, 0x55, 0x54, 0x48, 0x32,
+ 0x10, 0x03, 0x22, 0x31, 0x0a, 0x02, 0x49, 0x6e, 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x4e, 0x5f, 0x49,
+ 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x49, 0x4e, 0x5f, 0x51,
+ 0x55, 0x45, 0x52, 0x59, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x49, 0x4e, 0x5f, 0x48, 0x45, 0x41,
+ 0x44, 0x45, 0x52, 0x10, 0x02, 0x22, 0x6a, 0x0a, 0x04, 0x46, 0x6c, 0x6f, 0x77, 0x12, 0x10, 0x0a,
+ 0x0c, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12,
+ 0x11, 0x0a, 0x0d, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x49, 0x4d, 0x50, 0x4c, 0x49, 0x43, 0x49, 0x54,
+ 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x50, 0x41, 0x53, 0x53, 0x57,
+ 0x4f, 0x52, 0x44, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x41, 0x50,
+ 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x46,
+ 0x4c, 0x4f, 0x57, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x10,
+ 0x04, 0x22, 0xf6, 0x02, 0x0a, 0x13, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x65,
+ 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x8a, 0x01, 0x0a, 0x14, 0x73, 0x65,
+ 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65,
+ 0x6e, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x57, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e,
+ 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67,
+ 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71,
+ 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74,
+ 0x79, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x45, 0x6e, 0x74, 0x72,
+ 0x79, 0x52, 0x13, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x69,
+ 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x1a, 0x30, 0x0a, 0x18, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69,
+ 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x6c,
+ 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28,
+ 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x1a, 0x9f, 0x01, 0x0a, 0x18, 0x53, 0x65, 0x63,
+ 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74,
+ 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x6d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x57, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61,
+ 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e,
+ 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f,
+ 0x6e, 0x73, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x69,
+ 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52,
+ 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52,
+ 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x96, 0x01, 0x0a, 0x06, 0x53,
+ 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x52, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x01,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65,
+ 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f,
+ 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+ 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x45, 0x6e, 0x74,
+ 0x72, 0x79, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x1a, 0x38, 0x0a, 0x0a, 0x53, 0x63, 0x6f,
+ 0x70, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c,
+ 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a,
+ 0x02, 0x38, 0x01, 0x2a, 0x3b, 0x0a, 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x12, 0x0b, 0x0a,
+ 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x54,
+ 0x54, 0x50, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x48, 0x54, 0x54, 0x50, 0x53, 0x10, 0x02, 0x12,
+ 0x06, 0x0a, 0x02, 0x57, 0x53, 0x10, 0x03, 0x12, 0x07, 0x0a, 0x03, 0x57, 0x53, 0x53, 0x10, 0x04,
+ 0x42, 0x4b, 0x5a, 0x49, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62,
+ 0x69, 0x6e, 0x63, 0x68, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x65, 0x61, 0x73, 0x65,
+ 0x2d, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
+ 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e,
+ 0x61, 0x70, 0x69, 0x76, 0x32, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x62, 0x06, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescOnce sync.Once
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescData = file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDesc
+)
+
+func file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescGZIP() []byte {
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescOnce.Do(func() {
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescData = protoimpl.X.CompressGZIP(file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescData)
+ })
+ return file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDescData
+}
+
+var file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_enumTypes = make([]protoimpl.EnumInfo, 5)
+var file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes = make([]protoimpl.MessageInfo, 28)
+var file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_goTypes = []interface{}{
+ (Scheme)(0), // 0: grpc.gateway.protoc_gen_openapiv2.options.Scheme
+ (JSONSchema_JSONSchemaSimpleTypes)(0), // 1: grpc.gateway.protoc_gen_openapiv2.options.JSONSchema.JSONSchemaSimpleTypes
+ (SecurityScheme_Type)(0), // 2: grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.Type
+ (SecurityScheme_In)(0), // 3: grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.In
+ (SecurityScheme_Flow)(0), // 4: grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.Flow
+ (*Swagger)(nil), // 5: grpc.gateway.protoc_gen_openapiv2.options.Swagger
+ (*Operation)(nil), // 6: grpc.gateway.protoc_gen_openapiv2.options.Operation
+ (*Header)(nil), // 7: grpc.gateway.protoc_gen_openapiv2.options.Header
+ (*Response)(nil), // 8: grpc.gateway.protoc_gen_openapiv2.options.Response
+ (*Info)(nil), // 9: grpc.gateway.protoc_gen_openapiv2.options.Info
+ (*Contact)(nil), // 10: grpc.gateway.protoc_gen_openapiv2.options.Contact
+ (*License)(nil), // 11: grpc.gateway.protoc_gen_openapiv2.options.License
+ (*ExternalDocumentation)(nil), // 12: grpc.gateway.protoc_gen_openapiv2.options.ExternalDocumentation
+ (*Schema)(nil), // 13: grpc.gateway.protoc_gen_openapiv2.options.Schema
+ (*JSONSchema)(nil), // 14: grpc.gateway.protoc_gen_openapiv2.options.JSONSchema
+ (*Tag)(nil), // 15: grpc.gateway.protoc_gen_openapiv2.options.Tag
+ (*SecurityDefinitions)(nil), // 16: grpc.gateway.protoc_gen_openapiv2.options.SecurityDefinitions
+ (*SecurityScheme)(nil), // 17: grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme
+ (*SecurityRequirement)(nil), // 18: grpc.gateway.protoc_gen_openapiv2.options.SecurityRequirement
+ (*Scopes)(nil), // 19: grpc.gateway.protoc_gen_openapiv2.options.Scopes
+ nil, // 20: grpc.gateway.protoc_gen_openapiv2.options.Swagger.ResponsesEntry
+ nil, // 21: grpc.gateway.protoc_gen_openapiv2.options.Swagger.ExtensionsEntry
+ nil, // 22: grpc.gateway.protoc_gen_openapiv2.options.Operation.ResponsesEntry
+ nil, // 23: grpc.gateway.protoc_gen_openapiv2.options.Operation.ExtensionsEntry
+ nil, // 24: grpc.gateway.protoc_gen_openapiv2.options.Response.HeadersEntry
+ nil, // 25: grpc.gateway.protoc_gen_openapiv2.options.Response.ExamplesEntry
+ nil, // 26: grpc.gateway.protoc_gen_openapiv2.options.Response.ExtensionsEntry
+ nil, // 27: grpc.gateway.protoc_gen_openapiv2.options.Info.ExtensionsEntry
+ nil, // 28: grpc.gateway.protoc_gen_openapiv2.options.SecurityDefinitions.SecurityEntry
+ nil, // 29: grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.ExtensionsEntry
+ (*SecurityRequirement_SecurityRequirementValue)(nil), // 30: grpc.gateway.protoc_gen_openapiv2.options.SecurityRequirement.SecurityRequirementValue
+ nil, // 31: grpc.gateway.protoc_gen_openapiv2.options.SecurityRequirement.SecurityRequirementEntry
+ nil, // 32: grpc.gateway.protoc_gen_openapiv2.options.Scopes.ScopeEntry
+ (*structpb.Value)(nil), // 33: google.protobuf.Value
+}
+var file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_depIdxs = []int32{
+ 9, // 0: grpc.gateway.protoc_gen_openapiv2.options.Swagger.info:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Info
+ 0, // 1: grpc.gateway.protoc_gen_openapiv2.options.Swagger.schemes:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Scheme
+ 20, // 2: grpc.gateway.protoc_gen_openapiv2.options.Swagger.responses:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Swagger.ResponsesEntry
+ 16, // 3: grpc.gateway.protoc_gen_openapiv2.options.Swagger.security_definitions:type_name -> grpc.gateway.protoc_gen_openapiv2.options.SecurityDefinitions
+ 18, // 4: grpc.gateway.protoc_gen_openapiv2.options.Swagger.security:type_name -> grpc.gateway.protoc_gen_openapiv2.options.SecurityRequirement
+ 12, // 5: grpc.gateway.protoc_gen_openapiv2.options.Swagger.external_docs:type_name -> grpc.gateway.protoc_gen_openapiv2.options.ExternalDocumentation
+ 21, // 6: grpc.gateway.protoc_gen_openapiv2.options.Swagger.extensions:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Swagger.ExtensionsEntry
+ 12, // 7: grpc.gateway.protoc_gen_openapiv2.options.Operation.external_docs:type_name -> grpc.gateway.protoc_gen_openapiv2.options.ExternalDocumentation
+ 22, // 8: grpc.gateway.protoc_gen_openapiv2.options.Operation.responses:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Operation.ResponsesEntry
+ 0, // 9: grpc.gateway.protoc_gen_openapiv2.options.Operation.schemes:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Scheme
+ 18, // 10: grpc.gateway.protoc_gen_openapiv2.options.Operation.security:type_name -> grpc.gateway.protoc_gen_openapiv2.options.SecurityRequirement
+ 23, // 11: grpc.gateway.protoc_gen_openapiv2.options.Operation.extensions:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Operation.ExtensionsEntry
+ 13, // 12: grpc.gateway.protoc_gen_openapiv2.options.Response.schema:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Schema
+ 24, // 13: grpc.gateway.protoc_gen_openapiv2.options.Response.headers:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Response.HeadersEntry
+ 25, // 14: grpc.gateway.protoc_gen_openapiv2.options.Response.examples:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Response.ExamplesEntry
+ 26, // 15: grpc.gateway.protoc_gen_openapiv2.options.Response.extensions:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Response.ExtensionsEntry
+ 10, // 16: grpc.gateway.protoc_gen_openapiv2.options.Info.contact:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Contact
+ 11, // 17: grpc.gateway.protoc_gen_openapiv2.options.Info.license:type_name -> grpc.gateway.protoc_gen_openapiv2.options.License
+ 27, // 18: grpc.gateway.protoc_gen_openapiv2.options.Info.extensions:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Info.ExtensionsEntry
+ 14, // 19: grpc.gateway.protoc_gen_openapiv2.options.Schema.json_schema:type_name -> grpc.gateway.protoc_gen_openapiv2.options.JSONSchema
+ 12, // 20: grpc.gateway.protoc_gen_openapiv2.options.Schema.external_docs:type_name -> grpc.gateway.protoc_gen_openapiv2.options.ExternalDocumentation
+ 1, // 21: grpc.gateway.protoc_gen_openapiv2.options.JSONSchema.type:type_name -> grpc.gateway.protoc_gen_openapiv2.options.JSONSchema.JSONSchemaSimpleTypes
+ 12, // 22: grpc.gateway.protoc_gen_openapiv2.options.Tag.external_docs:type_name -> grpc.gateway.protoc_gen_openapiv2.options.ExternalDocumentation
+ 28, // 23: grpc.gateway.protoc_gen_openapiv2.options.SecurityDefinitions.security:type_name -> grpc.gateway.protoc_gen_openapiv2.options.SecurityDefinitions.SecurityEntry
+ 2, // 24: grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.type:type_name -> grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.Type
+ 3, // 25: grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.in:type_name -> grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.In
+ 4, // 26: grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.flow:type_name -> grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.Flow
+ 19, // 27: grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.scopes:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Scopes
+ 29, // 28: grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.extensions:type_name -> grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.ExtensionsEntry
+ 31, // 29: grpc.gateway.protoc_gen_openapiv2.options.SecurityRequirement.security_requirement:type_name -> grpc.gateway.protoc_gen_openapiv2.options.SecurityRequirement.SecurityRequirementEntry
+ 32, // 30: grpc.gateway.protoc_gen_openapiv2.options.Scopes.scope:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Scopes.ScopeEntry
+ 8, // 31: grpc.gateway.protoc_gen_openapiv2.options.Swagger.ResponsesEntry.value:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Response
+ 33, // 32: grpc.gateway.protoc_gen_openapiv2.options.Swagger.ExtensionsEntry.value:type_name -> google.protobuf.Value
+ 8, // 33: grpc.gateway.protoc_gen_openapiv2.options.Operation.ResponsesEntry.value:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Response
+ 33, // 34: grpc.gateway.protoc_gen_openapiv2.options.Operation.ExtensionsEntry.value:type_name -> google.protobuf.Value
+ 7, // 35: grpc.gateway.protoc_gen_openapiv2.options.Response.HeadersEntry.value:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Header
+ 33, // 36: grpc.gateway.protoc_gen_openapiv2.options.Response.ExtensionsEntry.value:type_name -> google.protobuf.Value
+ 33, // 37: grpc.gateway.protoc_gen_openapiv2.options.Info.ExtensionsEntry.value:type_name -> google.protobuf.Value
+ 17, // 38: grpc.gateway.protoc_gen_openapiv2.options.SecurityDefinitions.SecurityEntry.value:type_name -> grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme
+ 33, // 39: grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.ExtensionsEntry.value:type_name -> google.protobuf.Value
+ 30, // 40: grpc.gateway.protoc_gen_openapiv2.options.SecurityRequirement.SecurityRequirementEntry.value:type_name -> grpc.gateway.protoc_gen_openapiv2.options.SecurityRequirement.SecurityRequirementValue
+ 41, // [41:41] is the sub-list for method output_type
+ 41, // [41:41] is the sub-list for method input_type
+ 41, // [41:41] is the sub-list for extension type_name
+ 41, // [41:41] is the sub-list for extension extendee
+ 0, // [0:41] is the sub-list for field type_name
+}
+
+func init() { file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_init() }
+func file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_init() {
+ if File_gateway_protoc_gen_openapiv2_options_openapiv2_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Swagger); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Operation); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Header); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Response); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Info); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Contact); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*License); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ExternalDocumentation); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Schema); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*JSONSchema); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Tag); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SecurityDefinitions); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SecurityScheme); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SecurityRequirement); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Scopes); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SecurityRequirement_SecurityRequirementValue); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDesc,
+ NumEnums: 5,
+ NumMessages: 28,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_goTypes,
+ DependencyIndexes: file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_depIdxs,
+ EnumInfos: file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_enumTypes,
+ MessageInfos: file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_msgTypes,
+ }.Build()
+ File_gateway_protoc_gen_openapiv2_options_openapiv2_proto = out.File
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_rawDesc = nil
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_goTypes = nil
+ file_gateway_protoc_gen_openapiv2_options_openapiv2_proto_depIdxs = nil
+}
diff --git a/gateway/protoc-gen-openapiv2/options/openapiv2.proto b/gateway/protoc-gen-openapiv2/options/openapiv2.proto
new file mode 100644
index 0000000..a2bd206
--- /dev/null
+++ b/gateway/protoc-gen-openapiv2/options/openapiv2.proto
@@ -0,0 +1,645 @@
+syntax = "proto3";
+
+package grpc.gateway.protoc_gen_openapiv2.options;
+
+option go_package = "github.com/binchencoder/janus-gateway/gateway/protoc-gen-openapiv2/options";
+
+import "google/protobuf/struct.proto";
+
+// Scheme describes the schemes supported by the OpenAPI Swagger
+// and Operation objects.
+enum Scheme {
+ UNKNOWN = 0;
+ HTTP = 1;
+ HTTPS = 2;
+ WS = 3;
+ WSS = 4;
+}
+
+// `Swagger` is a representation of OpenAPI v2 specification's Swagger object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#swaggerObject
+//
+// Example:
+//
+// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
+// info: {
+// title: "Echo API";
+// version: "1.0";
+// description: ";
+// contact: {
+// name: "gRPC-Gateway project";
+// url: "https://github.com/grpc-ecosystem/grpc-gateway";
+// email: "none@example.com";
+// };
+// license: {
+// name: "BSD 3-Clause License";
+// url: "https://github.com/grpc-ecosystem/grpc-gateway/blob/master/LICENSE.txt";
+// };
+// };
+// schemes: HTTPS;
+// consumes: "application/json";
+// produces: "application/json";
+// };
+//
+message Swagger {
+ // Specifies the OpenAPI Specification version being used. It can be
+ // used by the OpenAPI UI and other clients to interpret the API listing. The
+ // value MUST be "2.0".
+ string swagger = 1;
+ // Provides metadata about the API. The metadata can be used by the
+ // clients if needed.
+ Info info = 2;
+ // The host (name or ip) serving the API. This MUST be the host only and does
+ // not include the scheme nor sub-paths. It MAY include a port. If the host is
+ // not included, the host serving the documentation is to be used (including
+ // the port). The host does not support path templating.
+ string host = 3;
+ // The base path on which the API is served, which is relative to the host. If
+ // it is not included, the API is served directly under the host. The value
+ // MUST start with a leading slash (/). The basePath does not support path
+ // templating.
+ // Note that using `base_path` does not change the endpoint paths that are
+ // generated in the resulting OpenAPI file. If you wish to use `base_path`
+ // with relatively generated OpenAPI paths, the `base_path` prefix must be
+ // manually removed from your `google.api.http` paths and your code changed to
+ // serve the API from the `base_path`.
+ string base_path = 4;
+ // The transfer protocol of the API. Values MUST be from the list: "http",
+ // "https", "ws", "wss". If the schemes is not included, the default scheme to
+ // be used is the one used to access the OpenAPI definition itself.
+ repeated Scheme schemes = 5;
+ // A list of MIME types the APIs can consume. This is global to all APIs but
+ // can be overridden on specific API calls. Value MUST be as described under
+ // Mime Types.
+ repeated string consumes = 6;
+ // A list of MIME types the APIs can produce. This is global to all APIs but
+ // can be overridden on specific API calls. Value MUST be as described under
+ // Mime Types.
+ repeated string produces = 7;
+ // field 8 is reserved for 'paths'.
+ reserved 8;
+ // field 9 is reserved for 'definitions', which at this time are already
+ // exposed as and customizable as proto messages.
+ reserved 9;
+ // An object to hold responses that can be used across operations. This
+ // property does not define global responses for all operations.
+ map responses = 10;
+ // Security scheme definitions that can be used across the specification.
+ SecurityDefinitions security_definitions = 11;
+ // A declaration of which security schemes are applied for the API as a whole.
+ // The list of values describes alternative security schemes that can be used
+ // (that is, there is a logical OR between the security requirements).
+ // Individual operations can override this definition.
+ repeated SecurityRequirement security = 12;
+ // field 13 is reserved for 'tags', which are supposed to be exposed as and
+ // customizable as proto services. TODO(ivucica): add processing of proto
+ // service objects into OpenAPI v2 Tag objects.
+ reserved 13;
+ // Additional external documentation.
+ ExternalDocumentation external_docs = 14;
+ map extensions = 15;
+}
+
+// `Operation` is a representation of OpenAPI v2 specification's Operation object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#operationObject
+//
+// Example:
+//
+// service EchoService {
+// rpc Echo(SimpleMessage) returns (SimpleMessage) {
+// option (google.api.http) = {
+// get: "/v1/example/echo/{id}"
+// };
+//
+// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
+// summary: "Get a message.";
+// operation_id: "getMessage";
+// tags: "echo";
+// responses: {
+// key: "200"
+// value: {
+// description: "OK";
+// }
+// }
+// };
+// }
+// }
+message Operation {
+ // A list of tags for API documentation control. Tags can be used for logical
+ // grouping of operations by resources or any other qualifier.
+ repeated string tags = 1;
+ // A short summary of what the operation does. For maximum readability in the
+ // swagger-ui, this field SHOULD be less than 120 characters.
+ string summary = 2;
+ // A verbose explanation of the operation behavior. GFM syntax can be used for
+ // rich text representation.
+ string description = 3;
+ // Additional external documentation for this operation.
+ ExternalDocumentation external_docs = 4;
+ // Unique string used to identify the operation. The id MUST be unique among
+ // all operations described in the API. Tools and libraries MAY use the
+ // operationId to uniquely identify an operation, therefore, it is recommended
+ // to follow common programming naming conventions.
+ string operation_id = 5;
+ // A list of MIME types the operation can consume. This overrides the consumes
+ // definition at the OpenAPI Object. An empty value MAY be used to clear the
+ // global definition. Value MUST be as described under Mime Types.
+ repeated string consumes = 6;
+ // A list of MIME types the operation can produce. This overrides the produces
+ // definition at the OpenAPI Object. An empty value MAY be used to clear the
+ // global definition. Value MUST be as described under Mime Types.
+ repeated string produces = 7;
+ // field 8 is reserved for 'parameters'.
+ reserved 8;
+ // The list of possible responses as they are returned from executing this
+ // operation.
+ map responses = 9;
+ // The transfer protocol for the operation. Values MUST be from the list:
+ // "http", "https", "ws", "wss". The value overrides the OpenAPI Object
+ // schemes definition.
+ repeated Scheme schemes = 10;
+ // Declares this operation to be deprecated. Usage of the declared operation
+ // should be refrained. Default value is false.
+ bool deprecated = 11;
+ // A declaration of which security schemes are applied for this operation. The
+ // list of values describes alternative security schemes that can be used
+ // (that is, there is a logical OR between the security requirements). This
+ // definition overrides any declared top-level security. To remove a top-level
+ // security declaration, an empty array can be used.
+ repeated SecurityRequirement security = 12;
+ map extensions = 13;
+}
+
+// `Header` is a representation of OpenAPI v2 specification's Header object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#headerObject
+//
+message Header {
+ // `Description` is a short description of the header.
+ string description = 1;
+ // The type of the object. The value MUST be one of "string", "number", "integer", or "boolean". The "array" type is not supported.
+ string type = 2;
+ // `Format` The extending format for the previously mentioned type.
+ string format = 3;
+ // field 4 is reserved for 'items', but in OpenAPI-specific way.
+ reserved 4;
+ // field 5 is reserved `Collection Format` Determines the format of the array if type array is used.
+ reserved 5;
+ // `Default` Declares the value of the header that the server will use if none is provided.
+ // See: https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-6.2.
+ // Unlike JSON Schema this value MUST conform to the defined type for the header.
+ string default = 6;
+ // field 7 is reserved for 'maximum'.
+ reserved 7;
+ // field 8 is reserved for 'exclusiveMaximum'.
+ reserved 8;
+ // field 9 is reserved for 'minimum'.
+ reserved 9;
+ // field 10 is reserved for 'exclusiveMinimum'.
+ reserved 10;
+ // field 11 is reserved for 'maxLength'.
+ reserved 11;
+ // field 12 is reserved for 'minLength'.
+ reserved 12;
+ // 'Pattern' See https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.2.3.
+ string pattern = 13;
+ // field 14 is reserved for 'maxItems'.
+ reserved 14;
+ // field 15 is reserved for 'minItems'.
+ reserved 15;
+ // field 16 is reserved for 'uniqueItems'.
+ reserved 16;
+ // field 17 is reserved for 'enum'.
+ reserved 17;
+ // field 18 is reserved for 'multipleOf'.
+ reserved 18;
+}
+
+// `Response` is a representation of OpenAPI v2 specification's Response object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#responseObject
+//
+message Response {
+ // `Description` is a short description of the response.
+ // GFM syntax can be used for rich text representation.
+ string description = 1;
+ // `Schema` optionally defines the structure of the response.
+ // If `Schema` is not provided, it means there is no content to the response.
+ Schema schema = 2;
+ // `Headers` A list of headers that are sent with the response.
+ // `Header` name is expected to be a string in the canonical format of the MIME header key
+ // See: https://golang.org/pkg/net/textproto/#CanonicalMIMEHeaderKey
+ map headers = 3;
+ // `Examples` gives per-mimetype response examples.
+ // See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#example-object
+ map examples = 4;
+ map extensions = 5;
+}
+
+// `Info` is a representation of OpenAPI v2 specification's Info object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#infoObject
+//
+// Example:
+//
+// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
+// info: {
+// title: "Echo API";
+// version: "1.0";
+// description: ";
+// contact: {
+// name: "gRPC-Gateway project";
+// url: "https://github.com/grpc-ecosystem/grpc-gateway";
+// email: "none@example.com";
+// };
+// license: {
+// name: "BSD 3-Clause License";
+// url: "https://github.com/grpc-ecosystem/grpc-gateway/blob/master/LICENSE.txt";
+// };
+// };
+// ...
+// };
+//
+message Info {
+ // The title of the application.
+ string title = 1;
+ // A short description of the application. GFM syntax can be used for rich
+ // text representation.
+ string description = 2;
+ // The Terms of Service for the API.
+ string terms_of_service = 3;
+ // The contact information for the exposed API.
+ Contact contact = 4;
+ // The license information for the exposed API.
+ License license = 5;
+ // Provides the version of the application API (not to be confused
+ // with the specification version).
+ string version = 6;
+ map extensions = 7;
+}
+
+// `Contact` is a representation of OpenAPI v2 specification's Contact object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#contactObject
+//
+// Example:
+//
+// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
+// info: {
+// ...
+// contact: {
+// name: "gRPC-Gateway project";
+// url: "https://github.com/grpc-ecosystem/grpc-gateway";
+// email: "none@example.com";
+// };
+// ...
+// };
+// ...
+// };
+//
+message Contact {
+ // The identifying name of the contact person/organization.
+ string name = 1;
+ // The URL pointing to the contact information. MUST be in the format of a
+ // URL.
+ string url = 2;
+ // The email address of the contact person/organization. MUST be in the format
+ // of an email address.
+ string email = 3;
+}
+
+// `License` is a representation of OpenAPI v2 specification's License object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#licenseObject
+//
+// Example:
+//
+// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
+// info: {
+// ...
+// license: {
+// name: "BSD 3-Clause License";
+// url: "https://github.com/grpc-ecosystem/grpc-gateway/blob/master/LICENSE.txt";
+// };
+// ...
+// };
+// ...
+// };
+//
+message License {
+ // The license name used for the API.
+ string name = 1;
+ // A URL to the license used for the API. MUST be in the format of a URL.
+ string url = 2;
+}
+
+// `ExternalDocumentation` is a representation of OpenAPI v2 specification's
+// ExternalDocumentation object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#externalDocumentationObject
+//
+// Example:
+//
+// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
+// ...
+// external_docs: {
+// description: "More about gRPC-Gateway";
+// url: "https://github.com/grpc-ecosystem/grpc-gateway";
+// }
+// ...
+// };
+//
+message ExternalDocumentation {
+ // A short description of the target documentation. GFM syntax can be used for
+ // rich text representation.
+ string description = 1;
+ // The URL for the target documentation. Value MUST be in the format
+ // of a URL.
+ string url = 2;
+}
+
+// `Schema` is a representation of OpenAPI v2 specification's Schema object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#schemaObject
+//
+message Schema {
+ JSONSchema json_schema = 1;
+ // Adds support for polymorphism. The discriminator is the schema property
+ // name that is used to differentiate between other schema that inherit this
+ // schema. The property name used MUST be defined at this schema and it MUST
+ // be in the required property list. When used, the value MUST be the name of
+ // this schema or any schema that inherits it.
+ string discriminator = 2;
+ // Relevant only for Schema "properties" definitions. Declares the property as
+ // "read only". This means that it MAY be sent as part of a response but MUST
+ // NOT be sent as part of the request. Properties marked as readOnly being
+ // true SHOULD NOT be in the required list of the defined schema. Default
+ // value is false.
+ bool read_only = 3;
+ // field 4 is reserved for 'xml'.
+ reserved 4;
+ // Additional external documentation for this schema.
+ ExternalDocumentation external_docs = 5;
+ // A free-form property to include an example of an instance for this schema in JSON.
+ // This is copied verbatim to the output.
+ string example = 6;
+}
+
+// `JSONSchema` represents properties from JSON Schema taken, and as used, in
+// the OpenAPI v2 spec.
+//
+// This includes changes made by OpenAPI v2.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#schemaObject
+//
+// See also: https://cswr.github.io/JsonSchema/spec/basic_types/,
+// https://github.com/json-schema-org/json-schema-spec/blob/master/schema.json
+//
+// Example:
+//
+// message SimpleMessage {
+// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
+// json_schema: {
+// title: "SimpleMessage"
+// description: "A simple message."
+// required: ["id"]
+// }
+// };
+//
+// // Id represents the message identifier.
+// string id = 1; [
+// (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
+// description: "The unique identifier of the simple message."
+// }];
+// }
+//
+message JSONSchema {
+ // field 1 is reserved for '$id', omitted from OpenAPI v2.
+ reserved 1;
+ // field 2 is reserved for '$schema', omitted from OpenAPI v2.
+ reserved 2;
+ // Ref is used to define an external reference to include in the message.
+ // This could be a fully qualified proto message reference, and that type must
+ // be imported into the protofile. If no message is identified, the Ref will
+ // be used verbatim in the output.
+ // For example:
+ // `ref: ".google.protobuf.Timestamp"`.
+ string ref = 3;
+ // field 4 is reserved for '$comment', omitted from OpenAPI v2.
+ reserved 4;
+ // The title of the schema.
+ string title = 5;
+ // A short description of the schema.
+ string description = 6;
+ string default = 7;
+ bool read_only = 8;
+ // A free-form property to include a JSON example of this field. This is copied
+ // verbatim to the output swagger.json. Quotes must be escaped.
+ // This property is the same for 2.0 and 3.0.0 https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/3.0.0.md#schemaObject https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#schemaObject
+ string example = 9;
+ double multiple_of = 10;
+ // Maximum represents an inclusive upper limit for a numeric instance. The
+ // value of MUST be a number,
+ double maximum = 11;
+ bool exclusive_maximum = 12;
+ // minimum represents an inclusive lower limit for a numeric instance. The
+ // value of MUST be a number,
+ double minimum = 13;
+ bool exclusive_minimum = 14;
+ uint64 max_length = 15;
+ uint64 min_length = 16;
+ string pattern = 17;
+ // field 18 is reserved for 'additionalItems', omitted from OpenAPI v2.
+ reserved 18;
+ // field 19 is reserved for 'items', but in OpenAPI-specific way.
+ // TODO(ivucica): add 'items'?
+ reserved 19;
+ uint64 max_items = 20;
+ uint64 min_items = 21;
+ bool unique_items = 22;
+ // field 23 is reserved for 'contains', omitted from OpenAPI v2.
+ reserved 23;
+ uint64 max_properties = 24;
+ uint64 min_properties = 25;
+ repeated string required = 26;
+ // field 27 is reserved for 'additionalProperties', but in OpenAPI-specific
+ // way. TODO(ivucica): add 'additionalProperties'?
+ reserved 27;
+ // field 28 is reserved for 'definitions', omitted from OpenAPI v2.
+ reserved 28;
+ // field 29 is reserved for 'properties', but in OpenAPI-specific way.
+ // TODO(ivucica): add 'additionalProperties'?
+ reserved 29;
+ // following fields are reserved, as the properties have been omitted from
+ // OpenAPI v2:
+ // patternProperties, dependencies, propertyNames, const
+ reserved 30 to 33;
+ // Items in 'array' must be unique.
+ repeated string array = 34;
+
+ enum JSONSchemaSimpleTypes {
+ UNKNOWN = 0;
+ ARRAY = 1;
+ BOOLEAN = 2;
+ INTEGER = 3;
+ NULL = 4;
+ NUMBER = 5;
+ OBJECT = 6;
+ STRING = 7;
+ }
+
+ repeated JSONSchemaSimpleTypes type = 35;
+ // `Format`
+ string format = 36;
+ // following fields are reserved, as the properties have been omitted from
+ // OpenAPI v2: contentMediaType, contentEncoding, if, then, else
+ reserved 37 to 41;
+ // field 42 is reserved for 'allOf', but in OpenAPI-specific way.
+ // TODO(ivucica): add 'allOf'?
+ reserved 42;
+ // following fields are reserved, as the properties have been omitted from
+ // OpenAPI v2:
+ // anyOf, oneOf, not
+ reserved 43 to 45;
+ // Items in `enum` must be unique https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.5.1
+ repeated string enum = 46;
+}
+
+// `Tag` is a representation of OpenAPI v2 specification's Tag object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#tagObject
+//
+message Tag {
+ // field 1 is reserved for 'name'. In our generator, this is (to be) extracted
+ // from the name of proto service, and thus not exposed to the user, as
+ // changing tag object's name would break the link to the references to the
+ // tag in individual operation specifications.
+ //
+ // TODO(ivucica): Add 'name' property. Use it to allow override of the name of
+ // global Tag object, then use that name to reference the tag throughout the
+ // OpenAPI file.
+ reserved 1;
+ // A short description for the tag. GFM syntax can be used for rich text
+ // representation.
+ string description = 2;
+ // Additional external documentation for this tag.
+ ExternalDocumentation external_docs = 3;
+}
+
+// `SecurityDefinitions` is a representation of OpenAPI v2 specification's
+// Security Definitions object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securityDefinitionsObject
+//
+// A declaration of the security schemes available to be used in the
+// specification. This does not enforce the security schemes on the operations
+// and only serves to provide the relevant details for each scheme.
+message SecurityDefinitions {
+ // A single security scheme definition, mapping a "name" to the scheme it
+ // defines.
+ map security = 1;
+}
+
+// `SecurityScheme` is a representation of OpenAPI v2 specification's
+// Security Scheme object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securitySchemeObject
+//
+// Allows the definition of a security scheme that can be used by the
+// operations. Supported schemes are basic authentication, an API key (either as
+// a header or as a query parameter) and OAuth2's common flows (implicit,
+// password, application and access code).
+message SecurityScheme {
+ // The type of the security scheme. Valid values are "basic",
+ // "apiKey" or "oauth2".
+ enum Type {
+ TYPE_INVALID = 0;
+ TYPE_BASIC = 1;
+ TYPE_API_KEY = 2;
+ TYPE_OAUTH2 = 3;
+ }
+
+ // The location of the API key. Valid values are "query" or "header".
+ enum In {
+ IN_INVALID = 0;
+ IN_QUERY = 1;
+ IN_HEADER = 2;
+ }
+
+ // The flow used by the OAuth2 security scheme. Valid values are
+ // "implicit", "password", "application" or "accessCode".
+ enum Flow {
+ FLOW_INVALID = 0;
+ FLOW_IMPLICIT = 1;
+ FLOW_PASSWORD = 2;
+ FLOW_APPLICATION = 3;
+ FLOW_ACCESS_CODE = 4;
+ }
+
+ // The type of the security scheme. Valid values are "basic",
+ // "apiKey" or "oauth2".
+ Type type = 1;
+ // A short description for security scheme.
+ string description = 2;
+ // The name of the header or query parameter to be used.
+ // Valid for apiKey.
+ string name = 3;
+ // The location of the API key. Valid values are "query" or
+ // "header".
+ // Valid for apiKey.
+ In in = 4;
+ // The flow used by the OAuth2 security scheme. Valid values are
+ // "implicit", "password", "application" or "accessCode".
+ // Valid for oauth2.
+ Flow flow = 5;
+ // The authorization URL to be used for this flow. This SHOULD be in
+ // the form of a URL.
+ // Valid for oauth2/implicit and oauth2/accessCode.
+ string authorization_url = 6;
+ // The token URL to be used for this flow. This SHOULD be in the
+ // form of a URL.
+ // Valid for oauth2/password, oauth2/application and oauth2/accessCode.
+ string token_url = 7;
+ // The available scopes for the OAuth2 security scheme.
+ // Valid for oauth2.
+ Scopes scopes = 8;
+ map extensions = 9;
+}
+
+// `SecurityRequirement` is a representation of OpenAPI v2 specification's
+// Security Requirement object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securityRequirementObject
+//
+// Lists the required security schemes to execute this operation. The object can
+// have multiple security schemes declared in it which are all required (that
+// is, there is a logical AND between the schemes).
+//
+// The name used for each property MUST correspond to a security scheme
+// declared in the Security Definitions.
+message SecurityRequirement {
+ // If the security scheme is of type "oauth2", then the value is a list of
+ // scope names required for the execution. For other security scheme types,
+ // the array MUST be empty.
+ message SecurityRequirementValue {
+ repeated string scope = 1;
+ }
+ // Each name must correspond to a security scheme which is declared in
+ // the Security Definitions. If the security scheme is of type "oauth2",
+ // then the value is a list of scope names required for the execution.
+ // For other security scheme types, the array MUST be empty.
+ map security_requirement = 1;
+}
+
+// `Scopes` is a representation of OpenAPI v2 specification's Scopes object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#scopesObject
+//
+// Lists the available scopes for an OAuth2 security scheme.
+message Scopes {
+ // Maps between a name of a scope to a short description of it (as the value
+ // of the property).
+ map scope = 1;
+}
diff --git a/gateway/protoc-gen-swagger/BUILD.bazel b/gateway/protoc-gen-swagger/BUILD.bazel
deleted file mode 100644
index 938be05..0000000
--- a/gateway/protoc-gen-swagger/BUILD.bazel
+++ /dev/null
@@ -1,30 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test")
-
-package(default_visibility = ["//visibility:public"])
-
-go_library(
- name = "go_default_library",
- srcs = ["main.go"],
- importpath = "github.com/binchencoder/ease-gateway/gateway/protoc-gen-swagger",
- deps = [
- "//gateway/codegenerator:go_default_library",
- "//gateway/protoc-gen-grpc-gateway/descriptor:go_default_library",
- "//gateway/protoc-gen-swagger/genswagger:go_default_library",
- "@com_github_golang_glog//:go_default_library",
- "@com_github_golang_protobuf//proto:go_default_library",
- "@io_bazel_rules_go//proto/wkt:compiler_plugin_go_proto",
- ],
-)
-
-go_binary(
- name = "protoc-gen-swagger",
- embed = [":go_default_library"],
- visibility = ["//visibility:public"],
-)
-
-go_test(
- name = "go_default_test",
- size = "small",
- srcs = ["main_test.go"],
- embed = [":go_default_library"],
-)
diff --git a/gateway/protoc-gen-swagger/defs.bzl b/gateway/protoc-gen-swagger/defs.bzl
deleted file mode 100644
index 565827c..0000000
--- a/gateway/protoc-gen-swagger/defs.bzl
+++ /dev/null
@@ -1,156 +0,0 @@
-"""Generated an open-api spec for a grpc api spec.
-
-Reads the the api spec in protobuf format and generate an open-api spec.
-Optionally applies settings from the grpc-service configuration.
-"""
-
-def _collect_includes(gen_dir, srcs):
- """Build an include path mapping.
-
- It is important to not just collect unique dirnames, to also support
- proto files of the same name from different packages.
-
- The implementation below is similar to what bazel does in its
- ProtoCompileActionBuilder.java
- """
- includes = []
- for src in srcs:
- ref_path = src.path
-
- if ref_path.startswith(gen_dir):
- ref_path = ref_path[len(gen_dir):].lstrip("/")
-
- if src.owner.workspace_root:
- workspace_root = src.owner.workspace_root
- ref_path = ref_path[len(workspace_root):].lstrip("/")
-
- include = ref_path + "=" + src.path
- if include not in includes:
- includes.append(include)
-
- return includes
-
-def _run_proto_gen_swagger(ctx, direct_proto_srcs, transitive_proto_srcs, actions, protoc, protoc_gen_swagger, grpc_api_configuration, single_output):
- swagger_files = []
-
- inputs = direct_proto_srcs + transitive_proto_srcs
- tools = [protoc_gen_swagger]
-
- options = ["logtostderr=true", "allow_repeated_fields_in_body=true"]
- if grpc_api_configuration:
- options.append("grpc_api_configuration=%s" % grpc_api_configuration.path)
- inputs.append(grpc_api_configuration)
-
- includes = _collect_includes(ctx.genfiles_dir.path, direct_proto_srcs + transitive_proto_srcs)
-
- if single_output:
- swagger_file = actions.declare_file(
- "%s.swagger.json" % ctx.attr.name,
- sibling = direct_proto_srcs[0],
- )
- output_dir = ctx.bin_dir.path
- if direct_proto_srcs[0].owner.workspace_root:
- output_dir = "/".join([output_dir, direct_proto_srcs[0].owner.workspace_root])
-
- output_dir = "/".join([output_dir, direct_proto_srcs[0].dirname])
-
- options.append("allow_merge=true")
- options.append("merge_file_name=%s" % ctx.attr.name)
-
- args = actions.args()
- args.add("--plugin=%s" % protoc_gen_swagger.path)
- args.add("--swagger_out=%s:%s" % (",".join(options), output_dir))
- args.add_all(["-I%s" % include for include in includes])
- args.add_all([src.path for src in direct_proto_srcs])
-
- actions.run(
- executable = protoc,
- inputs = inputs,
- tools = tools,
- outputs = [swagger_file],
- arguments = [args],
- )
-
- swagger_files.append(swagger_file)
- else:
- for proto in direct_proto_srcs:
- if proto.basename == "use_go_template.proto":
- options.append("use_go_templates=true")
-
- swagger_file = actions.declare_file(
- "%s.swagger.json" % proto.basename[:-len(".proto")],
- sibling = proto,
- )
-
- output_dir = ctx.bin_dir.path
- if proto.owner.workspace_root:
- output_dir = "/".join([output_dir, proto.owner.workspace_root])
-
- args = actions.args()
- args.add("--plugin=%s" % protoc_gen_swagger.path)
- args.add("--swagger_out=%s:%s" % (",".join(options), output_dir))
- args.add_all(["-I%s" % include for include in includes])
- args.add(proto.path)
-
- actions.run(
- executable = protoc,
- inputs = inputs,
- tools = tools,
- outputs = [swagger_file],
- arguments = [args],
- )
- swagger_files.append(swagger_file)
-
- return swagger_files
-
-def _proto_gen_swagger_impl(ctx):
- proto = ctx.attr.proto[ProtoInfo]
- grpc_api_configuration = ctx.file.grpc_api_configuration
-
- return [DefaultInfo(
- files = depset(
- _run_proto_gen_swagger(
- ctx,
- direct_proto_srcs = proto.direct_sources,
- transitive_proto_srcs = ctx.files._well_known_protos + proto.transitive_sources.to_list(),
- actions = ctx.actions,
- protoc = ctx.executable._protoc,
- protoc_gen_swagger = ctx.executable._protoc_gen_swagger,
- grpc_api_configuration = grpc_api_configuration,
- single_output = ctx.attr.single_output,
- ),
- ),
- )]
-
-protoc_gen_swagger = rule(
- attrs = {
- "proto": attr.label(
- allow_rules = ["proto_library"],
- mandatory = True,
- providers = ["proto"],
- ),
- "grpc_api_configuration": attr.label(
- allow_single_file = True,
- mandatory = False,
- ),
- "single_output": attr.bool(
- default = False,
- mandatory = False,
- ),
- "_protoc": attr.label(
- default = "@com_google_protobuf//:protoc",
- executable = True,
- cfg = "host",
- ),
- "_well_known_protos": attr.label(
- default = "@com_google_protobuf//:well_known_protos",
- allow_files = True,
- ),
- "_protoc_gen_swagger": attr.label(
- default = Label("//gateway/protoc-gen-swagger:protoc-gen-swagger"),
- executable = True,
- cfg = "host",
- ),
- },
- implementation = _proto_gen_swagger_impl,
-)
diff --git a/gateway/protoc-gen-swagger/genswagger/BUILD.bazel b/gateway/protoc-gen-swagger/genswagger/BUILD.bazel
deleted file mode 100644
index ee9f347..0000000
--- a/gateway/protoc-gen-swagger/genswagger/BUILD.bazel
+++ /dev/null
@@ -1,49 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-
-package(default_visibility = ["//visibility:public"])
-
-go_library(
- name = "go_default_library",
- srcs = [
- "doc.go",
- "generator.go",
- "helpers.go",
- "helpers_go111_old.go",
- "template.go",
- "types.go",
- ],
- importpath = "github.com/binchencoder/ease-gateway/gateway/protoc-gen-swagger/genswagger",
- deps = [
- "//httpoptions:go_default_library",
- "//gateway/protoc-gen-grpc-gateway/descriptor:go_default_library",
- "//gateway/protoc-gen-grpc-gateway/generator:go_default_library",
- "//gateway/protoc-gen-swagger/options:go_default_library",
- "@com_github_golang_glog//:go_default_library",
- "@com_github_golang_protobuf//descriptor:go_default_library_gen",
- "@com_github_golang_protobuf//jsonpb:go_default_library_gen",
- "@com_github_golang_protobuf//proto:go_default_library",
- "@com_github_golang_protobuf//protoc-gen-go/generator:go_default_library_gen",
- "@com_github_grpc_ecosystem_grpc_gateway//internal:go_default_library",
- "@io_bazel_rules_go//proto/wkt:any_go_proto",
- "@io_bazel_rules_go//proto/wkt:compiler_plugin_go_proto",
- "@io_bazel_rules_go//proto/wkt:descriptor_go_proto",
- "@io_bazel_rules_go//proto/wkt:struct_go_proto",
- ],
-)
-
-go_test(
- name = "go_default_test",
- size = "small",
- srcs = ["template_test.go"],
- embed = [":go_default_library"],
- deps = [
- "//gateway/protoc-gen-grpc-gateway/descriptor:go_default_library",
- "//gateway/protoc-gen-grpc-gateway/httprule:go_default_library",
- "//gateway/protoc-gen-swagger/options:go_default_library",
- "@com_github_golang_protobuf//proto:go_default_library",
- "@io_bazel_rules_go//proto/wkt:any_go_proto",
- "@io_bazel_rules_go//proto/wkt:compiler_plugin_go_proto",
- "@io_bazel_rules_go//proto/wkt:descriptor_go_proto",
- "@io_bazel_rules_go//proto/wkt:struct_go_proto",
- ],
-)
diff --git a/gateway/protoc-gen-swagger/genswagger/doc.go b/gateway/protoc-gen-swagger/genswagger/doc.go
deleted file mode 100644
index 4d28716..0000000
--- a/gateway/protoc-gen-swagger/genswagger/doc.go
+++ /dev/null
@@ -1,2 +0,0 @@
-// Package genswagger provides a code generator for swagger.
-package genswagger
diff --git a/gateway/protoc-gen-swagger/genswagger/template.go b/gateway/protoc-gen-swagger/genswagger/template.go
deleted file mode 100644
index 3d3b260..0000000
--- a/gateway/protoc-gen-swagger/genswagger/template.go
+++ /dev/null
@@ -1,1858 +0,0 @@
-package genswagger
-
-import (
- "bytes"
- "encoding/json"
- "fmt"
- "io/ioutil"
- "net/url"
- "os"
- "reflect"
- "regexp"
- "sort"
- "strconv"
- "strings"
- "sync"
- "text/template"
-
- "github.com/golang/glog"
- "github.com/golang/protobuf/jsonpb"
- "github.com/golang/protobuf/proto"
- pbdescriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
- gogen "github.com/golang/protobuf/protoc-gen-go/generator"
- structpb "github.com/golang/protobuf/ptypes/struct"
- // "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
- "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/descriptor"
- options "github.com/binchencoder/ease-gateway/httpoptions"
-
- // swagger_options "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options"
- swagger_options "github.com/binchencoder/ease-gateway/gateway/protoc-gen-swagger/options"
-)
-
-var wktSchemas = map[string]schemaCore{
- ".google.protobuf.Timestamp": schemaCore{
- Type: "string",
- Format: "date-time",
- },
- ".google.protobuf.Duration": schemaCore{
- Type: "string",
- },
- ".google.protobuf.StringValue": schemaCore{
- Type: "string",
- },
- ".google.protobuf.BytesValue": schemaCore{
- Type: "string",
- Format: "byte",
- },
- ".google.protobuf.Int32Value": schemaCore{
- Type: "integer",
- Format: "int32",
- },
- ".google.protobuf.UInt32Value": schemaCore{
- Type: "integer",
- Format: "int64",
- },
- ".google.protobuf.Int64Value": schemaCore{
- Type: "string",
- Format: "int64",
- },
- ".google.protobuf.UInt64Value": schemaCore{
- Type: "string",
- Format: "uint64",
- },
- ".google.protobuf.FloatValue": schemaCore{
- Type: "number",
- Format: "float",
- },
- ".google.protobuf.DoubleValue": schemaCore{
- Type: "number",
- Format: "double",
- },
- ".google.protobuf.BoolValue": schemaCore{
- Type: "boolean",
- Format: "boolean",
- },
- ".google.protobuf.Empty": schemaCore{},
- ".google.protobuf.Struct": schemaCore{
- Type: "object",
- },
- ".google.protobuf.Value": schemaCore{
- Type: "object",
- },
- ".google.protobuf.ListValue": schemaCore{
- Type: "array",
- Items: (*swaggerItemsObject)(&schemaCore{
- Type: "object",
- }),
- },
- ".google.protobuf.NullValue": schemaCore{
- Type: "string",
- },
-}
-
-func listEnumNames(enum *descriptor.Enum) (names []string) {
- for _, value := range enum.GetValue() {
- names = append(names, value.GetName())
- }
- return names
-}
-
-func getEnumDefault(enum *descriptor.Enum) string {
- for _, value := range enum.GetValue() {
- if value.GetNumber() == 0 {
- return value.GetName()
- }
- }
- return ""
-}
-
-// messageToQueryParameters converts a message to a list of swagger query parameters.
-func messageToQueryParameters(message *descriptor.Message, reg *descriptor.Registry, pathParams []descriptor.Parameter) (params []swaggerParameterObject, err error) {
- for _, field := range message.Fields {
- p, err := queryParams(message, field, "", reg, pathParams)
- if err != nil {
- return nil, err
- }
- params = append(params, p...)
- }
- return params, nil
-}
-
-// queryParams converts a field to a list of swagger query parameters recursively.
-func queryParams(message *descriptor.Message, field *descriptor.Field, prefix string, reg *descriptor.Registry, pathParams []descriptor.Parameter) (params []swaggerParameterObject, err error) {
- // make sure the parameter is not already listed as a path parameter
- for _, pathParam := range pathParams {
- if pathParam.Target == field {
- return nil, nil
- }
- }
- schema := schemaOfField(field, reg, nil)
- fieldType := field.GetTypeName()
- if message.File != nil {
- comments := fieldProtoComments(reg, message, field)
- if err := updateSwaggerDataFromComments(reg, &schema, message, comments, false); err != nil {
- return nil, err
- }
- }
-
- isEnum := field.GetType() == pbdescriptor.FieldDescriptorProto_TYPE_ENUM
- items := schema.Items
- if schema.Type != "" || isEnum {
- if schema.Type == "object" {
- return nil, nil // TODO: currently, mapping object in query parameter is not supported
- }
- if items != nil && (items.Type == "" || items.Type == "object") && !isEnum {
- return nil, nil // TODO: currently, mapping object in query parameter is not supported
- }
- desc := schema.Description
- if schema.Title != "" { // merge title because title of parameter object will be ignored
- desc = strings.TrimSpace(schema.Title + ". " + schema.Description)
- }
-
- // verify if the field is required
- required := false
- for _, fieldName := range schema.Required {
- if fieldName == field.GetName() {
- required = true
- break
- }
- }
-
- param := swaggerParameterObject{
- Description: desc,
- In: "query",
- Default: schema.Default,
- Type: schema.Type,
- Items: schema.Items,
- Format: schema.Format,
- Required: required,
- }
- if param.Type == "array" {
- param.CollectionFormat = "multi"
- }
-
- if reg.GetUseJSONNamesForFields() {
- param.Name = prefix + field.GetJsonName()
- } else {
- param.Name = prefix + field.GetName()
- }
-
- if isEnum {
- enum, err := reg.LookupEnum("", fieldType)
- if err != nil {
- return nil, fmt.Errorf("unknown enum type %s", fieldType)
- }
- if items != nil { // array
- param.Items = &swaggerItemsObject{
- Type: "string",
- Enum: listEnumNames(enum),
- }
- } else {
- param.Type = "string"
- param.Enum = listEnumNames(enum)
- param.Default = getEnumDefault(enum)
- }
- valueComments := enumValueProtoComments(reg, enum)
- if valueComments != "" {
- param.Description = strings.TrimLeft(param.Description+"\n\n "+valueComments, "\n")
- }
- }
- return []swaggerParameterObject{param}, nil
- }
-
- // nested type, recurse
- msg, err := reg.LookupMsg("", fieldType)
- if err != nil {
- return nil, fmt.Errorf("unknown message type %s", fieldType)
- }
- for _, nestedField := range msg.Fields {
- p, err := queryParams(msg, nestedField, prefix+field.GetName()+".", reg, pathParams)
- if err != nil {
- return nil, err
- }
- params = append(params, p...)
- }
- return params, nil
-}
-
-// findServicesMessagesAndEnumerations discovers all messages and enums defined in the RPC methods of the service.
-func findServicesMessagesAndEnumerations(s []*descriptor.Service, reg *descriptor.Registry, m messageMap, ms messageMap, e enumMap, refs refMap) {
- for _, svc := range s {
- for _, meth := range svc.Methods {
- // Request may be fully included in query
- if _, ok := refs[fmt.Sprintf("#/definitions/%s", fullyQualifiedNameToSwaggerName(meth.RequestType.FQMN(), reg))]; ok {
- if !skipRenderingRef(meth.RequestType.FQMN()) {
- m[fullyQualifiedNameToSwaggerName(meth.RequestType.FQMN(), reg)] = meth.RequestType
- }
- }
- findNestedMessagesAndEnumerations(meth.RequestType, reg, m, e)
-
- if !skipRenderingRef(meth.ResponseType.FQMN()) {
- m[fullyQualifiedNameToSwaggerName(meth.ResponseType.FQMN(), reg)] = meth.ResponseType
- if meth.GetServerStreaming() {
- runtimeStreamError := fullyQualifiedNameToSwaggerName(".grpc.gateway.runtime.StreamError", reg)
- glog.V(1).Infof("StreamError FQMN: %s", runtimeStreamError)
- streamError, err := reg.LookupMsg(".grpc.gateway.runtime", "StreamError")
- if err == nil {
- glog.V(1).Infof("StreamError: %v", streamError)
- m[runtimeStreamError] = streamError
- findNestedMessagesAndEnumerations(streamError, reg, m, e)
- } else {
- //just in case there is an error looking up StreamError
- glog.Error(err)
- }
- ms[fullyQualifiedNameToSwaggerName(meth.ResponseType.FQMN(), reg)] = meth.ResponseType
- }
- }
- findNestedMessagesAndEnumerations(meth.ResponseType, reg, m, e)
- }
- }
-}
-
-// findNestedMessagesAndEnumerations those can be generated by the services.
-func findNestedMessagesAndEnumerations(message *descriptor.Message, reg *descriptor.Registry, m messageMap, e enumMap) {
- // Iterate over all the fields that
- for _, t := range message.Fields {
- fieldType := t.GetTypeName()
- // If the type is an empty string then it is a proto primitive
- if fieldType != "" {
- if _, ok := m[fieldType]; !ok {
- msg, err := reg.LookupMsg("", fieldType)
- if err != nil {
- enum, err := reg.LookupEnum("", fieldType)
- if err != nil {
- panic(err)
- }
- e[fieldType] = enum
- continue
- }
- m[fieldType] = msg
- findNestedMessagesAndEnumerations(msg, reg, m, e)
- }
- }
- }
-}
-
-func skipRenderingRef(refName string) bool {
- _, ok := wktSchemas[refName]
- return ok
-}
-
-func renderMessagesAsDefinition(messages messageMap, d swaggerDefinitionsObject, reg *descriptor.Registry, customRefs refMap) {
- for name, msg := range messages {
- if skipRenderingRef(name) {
- continue
- }
-
- if opt := msg.GetOptions(); opt != nil && opt.MapEntry != nil && *opt.MapEntry {
- continue
- }
- schema := swaggerSchemaObject{
- schemaCore: schemaCore{
- Type: "object",
- },
- }
- msgComments := protoComments(reg, msg.File, msg.Outers, "MessageType", int32(msg.Index))
- if err := updateSwaggerDataFromComments(reg, &schema, msg, msgComments, false); err != nil {
- panic(err)
- }
- opts, err := extractSchemaOptionFromMessageDescriptor(msg.DescriptorProto)
- if err != nil {
- panic(err)
- }
- if opts != nil {
- protoSchema := swaggerSchemaFromProtoSchema(opts, reg, customRefs, msg)
-
- // Warning: Make sure not to overwrite any fields already set on the schema type.
- schema.ExternalDocs = protoSchema.ExternalDocs
- schema.ReadOnly = protoSchema.ReadOnly
- schema.MultipleOf = protoSchema.MultipleOf
- schema.Maximum = protoSchema.Maximum
- schema.ExclusiveMaximum = protoSchema.ExclusiveMaximum
- schema.Minimum = protoSchema.Minimum
- schema.ExclusiveMinimum = protoSchema.ExclusiveMinimum
- schema.MaxLength = protoSchema.MaxLength
- schema.MinLength = protoSchema.MinLength
- schema.Pattern = protoSchema.Pattern
- schema.Default = protoSchema.Default
- schema.MaxItems = protoSchema.MaxItems
- schema.MinItems = protoSchema.MinItems
- schema.UniqueItems = protoSchema.UniqueItems
- schema.MaxProperties = protoSchema.MaxProperties
- schema.MinProperties = protoSchema.MinProperties
- schema.Required = protoSchema.Required
- if protoSchema.schemaCore.Type != "" || protoSchema.schemaCore.Ref != "" {
- schema.schemaCore = protoSchema.schemaCore
- }
- if protoSchema.Title != "" {
- schema.Title = protoSchema.Title
- }
- if protoSchema.Description != "" {
- schema.Description = protoSchema.Description
- }
- if protoSchema.Example != nil {
- schema.Example = protoSchema.Example
- }
- }
-
- for _, f := range msg.Fields {
- fieldValue := schemaOfField(f, reg, customRefs)
- comments := fieldProtoComments(reg, msg, f)
- if err := updateSwaggerDataFromComments(reg, &fieldValue, f, comments, false); err != nil {
- panic(err)
- }
-
- kv := keyVal{Value: fieldValue}
- if reg.GetUseJSONNamesForFields() {
- kv.Key = f.GetJsonName()
- } else {
- kv.Key = f.GetName()
- }
- if schema.Properties == nil {
- schema.Properties = &swaggerSchemaObjectProperties{}
- }
- *schema.Properties = append(*schema.Properties, kv)
- }
- d[fullyQualifiedNameToSwaggerName(msg.FQMN(), reg)] = schema
- }
-}
-
-func renderMessagesAsStreamDefinition(messages messageMap, d swaggerDefinitionsObject, reg *descriptor.Registry) {
- for name, msg := range messages {
- if skipRenderingRef(name) {
- continue
- }
-
- if opt := msg.GetOptions(); opt != nil && opt.MapEntry != nil && *opt.MapEntry {
- continue
- }
- d[fullyQualifiedNameToSwaggerName(msg.FQMN(), reg)] = swaggerSchemaObject{
- schemaCore: schemaCore{
- Type: "object",
- },
- Title: fmt.Sprintf("Stream result of %s", fullyQualifiedNameToSwaggerName(msg.FQMN(), reg)),
- Properties: &swaggerSchemaObjectProperties{
- keyVal{
- Key: "result",
- Value: swaggerSchemaObject{
- schemaCore: schemaCore{
- Ref: fmt.Sprintf("#/definitions/%s", fullyQualifiedNameToSwaggerName(msg.FQMN(), reg)),
- },
- },
- },
- keyVal{
- Key: "error",
- Value: swaggerSchemaObject{
- schemaCore: schemaCore{
- Ref: fmt.Sprintf("#/definitions/%s", fullyQualifiedNameToSwaggerName(".grpc.gateway.runtime.StreamError", reg)),
- },
- },
- },
- },
- }
- }
-}
-
-// schemaOfField returns a swagger Schema Object for a protobuf field.
-func schemaOfField(f *descriptor.Field, reg *descriptor.Registry, refs refMap) swaggerSchemaObject {
- const (
- singular = 0
- array = 1
- object = 2
- )
- var (
- core schemaCore
- aggregate int
- )
-
- fd := f.FieldDescriptorProto
- if m, err := reg.LookupMsg("", f.GetTypeName()); err == nil {
- if opt := m.GetOptions(); opt != nil && opt.MapEntry != nil && *opt.MapEntry {
- fd = m.GetField()[1]
- aggregate = object
- }
- }
- if fd.GetLabel() == pbdescriptor.FieldDescriptorProto_LABEL_REPEATED {
- aggregate = array
- }
-
- var props *swaggerSchemaObjectProperties
-
- switch ft := fd.GetType(); ft {
- case pbdescriptor.FieldDescriptorProto_TYPE_ENUM, pbdescriptor.FieldDescriptorProto_TYPE_MESSAGE, pbdescriptor.FieldDescriptorProto_TYPE_GROUP:
- if wktSchema, ok := wktSchemas[fd.GetTypeName()]; ok {
- core = wktSchema
-
- if fd.GetTypeName() == ".google.protobuf.Empty" {
- props = &swaggerSchemaObjectProperties{}
- }
- } else {
- core = schemaCore{
- Ref: "#/definitions/" + fullyQualifiedNameToSwaggerName(fd.GetTypeName(), reg),
- }
- if refs != nil {
- refs[fd.GetTypeName()] = struct{}{}
-
- }
- }
- default:
- ftype, format, ok := primitiveSchema(ft)
- if ok {
- if f.HasRule() {
- core = schemaCore{Type: ftype, Format: format, Rules: getRules(f.Rules)}
- } else {
- core = schemaCore{Type: ftype, Format: format}
- }
- } else {
- core = schemaCore{Type: ft.String(), Format: "UNKNOWN"}
- }
- }
-
- ret := swaggerSchemaObject{}
-
- switch aggregate {
- case array:
- ret = swaggerSchemaObject{
- schemaCore: schemaCore{
- Type: "array",
- Items: (*swaggerItemsObject)(&core),
- },
- }
- case object:
- ret = swaggerSchemaObject{
- schemaCore: schemaCore{
- Type: "object",
- },
- AdditionalProperties: &swaggerSchemaObject{Properties: props, schemaCore: core},
- }
- default:
- ret = swaggerSchemaObject{
- schemaCore: core,
- Properties: props,
- }
- }
-
- if j, err := extractJSONSchemaFromFieldDescriptor(fd); err == nil {
- updateSwaggerObjectFromJSONSchema(&ret, j, reg, f)
- }
-
- return ret
-}
-
-// primitiveSchema returns a pair of "Type" and "Format" in JSON Schema for
-// the given primitive field type.
-// The last return parameter is true iff the field type is actually primitive.
-func primitiveSchema(t pbdescriptor.FieldDescriptorProto_Type) (ftype, format string, ok bool) {
- switch t {
- case pbdescriptor.FieldDescriptorProto_TYPE_DOUBLE:
- return "number", "double", true
- case pbdescriptor.FieldDescriptorProto_TYPE_FLOAT:
- return "number", "float", true
- case pbdescriptor.FieldDescriptorProto_TYPE_INT64:
- return "string", "int64", true
- case pbdescriptor.FieldDescriptorProto_TYPE_UINT64:
- // 64bit integer types are marshaled as string in the default JSONPb marshaler.
- // TODO(yugui) Add an option to declare 64bit integers as int64.
- //
- // NOTE: uint64 is not a predefined format of integer type in Swagger spec.
- // So we cannot expect that uint64 is commonly supported by swagger processor.
- return "string", "uint64", true
- case pbdescriptor.FieldDescriptorProto_TYPE_INT32:
- return "integer", "int32", true
- case pbdescriptor.FieldDescriptorProto_TYPE_FIXED64:
- // Ditto.
- return "string", "uint64", true
- case pbdescriptor.FieldDescriptorProto_TYPE_FIXED32:
- // Ditto.
- return "integer", "int64", true
- case pbdescriptor.FieldDescriptorProto_TYPE_BOOL:
- return "boolean", "boolean", true
- case pbdescriptor.FieldDescriptorProto_TYPE_STRING:
- // NOTE: in swagger specifition, format should be empty on string type
- return "string", "", true
- case pbdescriptor.FieldDescriptorProto_TYPE_BYTES:
- return "string", "byte", true
- case pbdescriptor.FieldDescriptorProto_TYPE_UINT32:
- // Ditto.
- return "integer", "int64", true
- case pbdescriptor.FieldDescriptorProto_TYPE_SFIXED32:
- return "integer", "int32", true
- case pbdescriptor.FieldDescriptorProto_TYPE_SFIXED64:
- return "string", "int64", true
- case pbdescriptor.FieldDescriptorProto_TYPE_SINT32:
- return "integer", "int32", true
- case pbdescriptor.FieldDescriptorProto_TYPE_SINT64:
- return "string", "int64", true
- default:
- return "", "", false
- }
-}
-
-// getRules returns a swagger rule slice.
-func getRules(rules []*descriptor.Rule) []options.ValidationRule {
- rs := []options.ValidationRule{}
- for _, v := range rules {
- rs = append(rs, *v.Rule())
- }
- return rs
-}
-
-// renderEnumerationsAsDefinition inserts enums into the definitions object.
-func renderEnumerationsAsDefinition(enums enumMap, d swaggerDefinitionsObject, reg *descriptor.Registry) {
- for _, enum := range enums {
- enumComments := protoComments(reg, enum.File, enum.Outers, "EnumType", int32(enum.Index))
-
- // it may be necessary to sort the result of the GetValue function.
- enumNames := listEnumNames(enum)
- defaultValue := getEnumDefault(enum)
- valueComments := enumValueProtoComments(reg, enum)
- if valueComments != "" {
- enumComments = strings.TrimLeft(enumComments+"\n\n "+valueComments, "\n")
- }
- enumSchemaObject := swaggerSchemaObject{
- schemaCore: schemaCore{
- Type: "string",
- Enum: enumNames,
- Default: defaultValue,
- },
- }
- if err := updateSwaggerDataFromComments(reg, &enumSchemaObject, enum, enumComments, false); err != nil {
- panic(err)
- }
-
- d[fullyQualifiedNameToSwaggerName(enum.FQEN(), reg)] = enumSchemaObject
- }
-}
-
-// Take in a FQMN or FQEN and return a swagger safe version of the FQMN
-func fullyQualifiedNameToSwaggerName(fqn string, reg *descriptor.Registry) string {
- registriesSeenMutex.Lock()
- defer registriesSeenMutex.Unlock()
- if mapping, present := registriesSeen[reg]; present {
- return mapping[fqn]
- }
- mapping := resolveFullyQualifiedNameToSwaggerNames(append(reg.GetAllFQMNs(), reg.GetAllFQENs()...), reg.GetUseFQNForSwaggerName())
- registriesSeen[reg] = mapping
- return mapping[fqn]
-}
-
-// registriesSeen is used to memoise calls to resolveFullyQualifiedNameToSwaggerNames so
-// we don't repeat it unnecessarily, since it can take some time.
-var registriesSeen = map[*descriptor.Registry]map[string]string{}
-var registriesSeenMutex sync.Mutex
-
-// Take the names of every proto and "uniq-ify" them. The idea is to produce a
-// set of names that meet a couple of conditions. They must be stable, they
-// must be unique, and they must be shorter than the FQN.
-//
-// This likely could be made better. This will always generate the same names
-// but may not always produce optimal names. This is a reasonably close
-// approximation of what they should look like in most cases.
-func resolveFullyQualifiedNameToSwaggerNames(messages []string, useFQNForSwaggerName bool) map[string]string {
- packagesByDepth := make(map[int][][]string)
- uniqueNames := make(map[string]string)
-
- hierarchy := func(pkg string) []string {
- return strings.Split(pkg, ".")
- }
-
- for _, p := range messages {
- h := hierarchy(p)
- for depth := range h {
- if _, ok := packagesByDepth[depth]; !ok {
- packagesByDepth[depth] = make([][]string, 0)
- }
- packagesByDepth[depth] = append(packagesByDepth[depth], h[len(h)-depth:])
- }
- }
-
- count := func(list [][]string, item []string) int {
- i := 0
- for _, element := range list {
- if reflect.DeepEqual(element, item) {
- i++
- }
- }
- return i
- }
-
- for _, p := range messages {
- if useFQNForSwaggerName {
- // strip leading dot from proto fqn
- uniqueNames[p] = p[1:]
- } else {
- h := hierarchy(p)
- for depth := 0; depth < len(h); depth++ {
- if count(packagesByDepth[depth], h[len(h)-depth:]) == 1 {
- uniqueNames[p] = strings.Join(h[len(h)-depth-1:], "")
- break
- }
- if depth == len(h)-1 {
- uniqueNames[p] = strings.Join(h, "")
- }
- }
- }
- }
- return uniqueNames
-}
-
-var canRegexp = regexp.MustCompile("{([a-zA-Z][a-zA-Z0-9_.]*).*}")
-
-// Swagger expects paths of the form /path/{string_value} but grpc-gateway paths are expected to be of the form /path/{string_value=strprefix/*}. This should reformat it correctly.
-func templateToSwaggerPath(path string, reg *descriptor.Registry) string {
- // It seems like the right thing to do here is to just use
- // strings.Split(path, "/") but that breaks badly when you hit a url like
- // /{my_field=prefix/*}/ and end up with 2 sections representing my_field.
- // Instead do the right thing and write a small pushdown (counter) automata
- // for it.
- var parts []string
- depth := 0
- buffer := ""
- jsonBuffer := ""
- for _, char := range path {
- switch char {
- case '{':
- // Push on the stack
- depth++
- buffer += string(char)
- jsonBuffer = ""
- jsonBuffer += string(char)
- break
- case '}':
- if depth == 0 {
- panic("Encountered } without matching { before it.")
- }
- // Pop from the stack
- depth--
- buffer += string(char)
- if reg.GetUseJSONNamesForFields() &&
- len(jsonBuffer) > 1 {
- jsonSnakeCaseName := string(jsonBuffer[1:])
- jsonCamelCaseName := string(lowerCamelCase(jsonSnakeCaseName))
- prev := string(buffer[:len(buffer)-len(jsonSnakeCaseName)-2])
- buffer = strings.Join([]string{prev, "{", jsonCamelCaseName, "}"}, "")
- jsonBuffer = ""
- }
- case '/':
- if depth == 0 {
- parts = append(parts, buffer)
- buffer = ""
- // Since the stack was empty when we hit the '/' we are done with this
- // section.
- continue
- }
- buffer += string(char)
- jsonBuffer += string(char)
- default:
- buffer += string(char)
- jsonBuffer += string(char)
- break
- }
- }
-
- // Now append the last element to parts
- parts = append(parts, buffer)
-
- // Parts is now an array of segments of the path. Interestingly, since the
- // syntax for this subsection CAN be handled by a regexp since it has no
- // memory.
- keyre := regexp.MustCompile("{(.*)}")
- for index, part := range parts {
- // If part is a resource name such as "parent", "name", "user.name", the format info must be retained.
- prefix := canRegexp.ReplaceAllString(part, "$1")
- if isResourceName(prefix) {
- sm := keyre.FindStringSubmatch(part)
- key := sm[1]
- esckey := url.PathEscape(key)
- parts[index] = keyre.ReplaceAllString(part, fmt.Sprintf("{%s}", esckey))
- } else {
- parts[index] = canRegexp.ReplaceAllString(part, "{$1}")
- }
- }
-
- return strings.Join(parts, "/")
-}
-
-func isResourceName(prefix string) bool {
- words := strings.Split(prefix, ".")
- l := len(words)
- field := words[l-1]
- words = strings.Split(field, ":")
- field = words[0]
- return field == "parent" || field == "name"
-}
-
-func extractResourceName(path string) map[string]string {
- m := map[string]string{}
- keyre := regexp.MustCompile("{(.*)}")
- sm := keyre.FindStringSubmatch(path)
- count := len(sm)
- for i := 0; i < count; i++ {
- key := sm[1]
- parts := strings.Split(key, "=")
- label := parts[0]
- parts = strings.Split(label, ".")
- l := len(parts)
- field := parts[l-1]
- if field == "parent" || field == "name" {
- m[label] = key
- }
- }
- return m
-}
-
-func renderServices(services []*descriptor.Service, paths swaggerPathsObject, reg *descriptor.Registry, requestResponseRefs, customRefs refMap) error {
- // Correctness of svcIdx and methIdx depends on 'services' containing the services in the same order as the 'file.Service' array.
- for svcIdx, svc := range services {
- for methIdx, meth := range svc.Methods {
- for bIdx, b := range meth.Bindings {
- pathParamMap := extractResourceName(templateToSwaggerPath(b.PathTmpl.Template, reg))
- // Iterate over all the swagger parameters
- parameters := swaggerParametersObject{}
- for _, parameter := range b.PathParams {
-
- var paramType, paramFormat, desc, collectionFormat, defaultValue string
- var enumNames []string
- var items *swaggerItemsObject
- var minItems *int
- switch pt := parameter.Target.GetType(); pt {
- case pbdescriptor.FieldDescriptorProto_TYPE_GROUP, pbdescriptor.FieldDescriptorProto_TYPE_MESSAGE:
- if descriptor.IsWellKnownType(parameter.Target.GetTypeName()) {
- if parameter.IsRepeated() {
- return fmt.Errorf("only primitive and enum types are allowed in repeated path parameters")
- }
- schema := schemaOfField(parameter.Target, reg, customRefs)
- paramType = schema.Type
- paramFormat = schema.Format
- desc = schema.Description
- defaultValue = schema.Default
- } else {
- return fmt.Errorf("only primitive and well-known types are allowed in path parameters")
- }
- case pbdescriptor.FieldDescriptorProto_TYPE_ENUM:
- paramType = "string"
- paramFormat = ""
- enum, err := reg.LookupEnum("", parameter.Target.GetTypeName())
- if err != nil {
- return err
- }
- enumNames = listEnumNames(enum)
- schema := schemaOfField(parameter.Target, reg, customRefs)
- desc = schema.Description
- defaultValue = schema.Default
- default:
- var ok bool
- paramType, paramFormat, ok = primitiveSchema(pt)
- if !ok {
- return fmt.Errorf("unknown field type %v", pt)
- }
-
- schema := schemaOfField(parameter.Target, reg, customRefs)
- desc = schema.Description
- defaultValue = schema.Default
- }
-
- if parameter.IsRepeated() {
- core := schemaCore{Type: paramType, Format: paramFormat}
- if parameter.IsEnum() {
- var s []string
- core.Enum = enumNames
- enumNames = s
- }
- items = (*swaggerItemsObject)(&core)
- paramType = "array"
- paramFormat = ""
- collectionFormat = reg.GetRepeatedPathParamSeparatorName()
- minItems = new(int)
- *minItems = 1
- }
-
- if desc == "" {
- desc = fieldProtoComments(reg, parameter.Target.Message, parameter.Target)
- }
- parameterString := parameter.String()
- if reg.GetUseJSONNamesForFields() {
- parameterString = lowerCamelCase(parameterString)
- }
- if esckey, ok := pathParamMap[parameterString]; ok {
- parameterString = esckey
- }
- parameters = append(parameters, swaggerParameterObject{
- Name: parameterString,
- Description: desc,
- In: "path",
- Required: true,
- Default: defaultValue,
- // Parameters in gRPC-Gateway can only be strings?
- Type: paramType,
- Format: paramFormat,
- Enum: enumNames,
- Items: items,
- CollectionFormat: collectionFormat,
- MinItems: minItems,
- })
- }
- // Now check if there is a body parameter
- if b.Body != nil {
- var schema swaggerSchemaObject
- desc := ""
-
- if len(b.Body.FieldPath) == 0 {
- schema = swaggerSchemaObject{
- schemaCore: schemaCore{},
- }
-
- wknSchemaCore, isWkn := wktSchemas[meth.RequestType.FQMN()]
- if !isWkn {
- schema.Ref = fmt.Sprintf("#/definitions/%s", fullyQualifiedNameToSwaggerName(meth.RequestType.FQMN(), reg))
- } else {
- schema.schemaCore = wknSchemaCore
-
- // Special workaround for Empty: it's well-known type but wknSchemas only returns schema.schemaCore; but we need to set schema.Properties which is a level higher.
- if meth.RequestType.FQMN() == ".google.protobuf.Empty" {
- schema.Properties = &swaggerSchemaObjectProperties{}
- }
- }
- } else {
- lastField := b.Body.FieldPath[len(b.Body.FieldPath)-1]
- schema = schemaOfField(lastField.Target, reg, customRefs)
- if schema.Description != "" {
- desc = schema.Description
- } else {
- desc = fieldProtoComments(reg, lastField.Target.Message, lastField.Target)
- }
- }
-
- if meth.GetClientStreaming() {
- desc += " (streaming inputs)"
- }
- parameters = append(parameters, swaggerParameterObject{
- Name: "body",
- Description: desc,
- In: "body",
- Required: true,
- Schema: &schema,
- })
- } else if b.HTTPMethod == "GET" || b.HTTPMethod == "DELETE" {
- // add the parameters to the query string
- queryParams, err := messageToQueryParameters(meth.RequestType, reg, b.PathParams)
- if err != nil {
- return err
- }
- parameters = append(parameters, queryParams...)
- }
-
- pathItemObject, ok := paths[templateToSwaggerPath(b.PathTmpl.Template, reg)]
- if !ok {
- pathItemObject = swaggerPathItemObject{}
- }
-
- methProtoPath := protoPathIndex(reflect.TypeOf((*pbdescriptor.ServiceDescriptorProto)(nil)), "Method")
- desc := "A successful response."
- var responseSchema swaggerSchemaObject
-
- if b.ResponseBody == nil || len(b.ResponseBody.FieldPath) == 0 {
- responseSchema = swaggerSchemaObject{
- schemaCore: schemaCore{},
- }
-
- // Don't link to a full definition for
- // empty; it's overly verbose.
- // schema.Properties{} renders it as
- // well, without a definition
- wknSchemaCore, isWkn := wktSchemas[meth.ResponseType.FQMN()]
- if !isWkn {
- responseSchema.Ref = fmt.Sprintf("#/definitions/%s", fullyQualifiedNameToSwaggerName(meth.ResponseType.FQMN(), reg))
- } else {
- responseSchema.schemaCore = wknSchemaCore
-
- // Special workaround for Empty: it's well-known type but wknSchemas only returns schema.schemaCore; but we need to set schema.Properties which is a level higher.
- if meth.ResponseType.FQMN() == ".google.protobuf.Empty" {
- responseSchema.Properties = &swaggerSchemaObjectProperties{}
- }
- }
- } else {
- // This is resolving the value of response_body in the google.api.HttpRule
- lastField := b.ResponseBody.FieldPath[len(b.ResponseBody.FieldPath)-1]
- responseSchema = schemaOfField(lastField.Target, reg, customRefs)
- if responseSchema.Description != "" {
- desc = responseSchema.Description
- } else {
- desc = fieldProtoComments(reg, lastField.Target.Message, lastField.Target)
- }
- }
- if meth.GetServerStreaming() {
- desc += "(streaming responses)"
- // Use the streamdefinition which wraps the message in a "result"
- responseSchema.Ref = strings.Replace(responseSchema.Ref, `#/definitions/`, `#/x-stream-definitions/`, 1)
- }
-
- tag := svc.GetName()
- if pkg := svc.File.GetPackage(); pkg != "" && reg.IsIncludePackageInTags() {
- tag = pkg + "." + tag
- }
-
- operationObject := &swaggerOperationObject{
- Tags: []string{tag},
- Parameters: parameters,
- Responses: swaggerResponsesObject{
- "200": swaggerResponseObject{
- Description: desc,
- Schema: responseSchema,
- },
- },
- }
- if bIdx == 0 {
- operationObject.OperationID = fmt.Sprintf("%s", meth.GetName())
- } else {
- // OperationID must be unique in an OpenAPI v2 definition.
- operationObject.OperationID = fmt.Sprintf("%s%d", meth.GetName(), bIdx+1)
- }
-
- // Fill reference map with referenced request messages
- for _, param := range operationObject.Parameters {
- if param.Schema != nil && param.Schema.Ref != "" {
- requestResponseRefs[param.Schema.Ref] = struct{}{}
- }
- }
-
- methComments := protoComments(reg, svc.File, nil, "Method", int32(svcIdx), methProtoPath, int32(methIdx))
- if err := updateSwaggerDataFromComments(reg, operationObject, meth, methComments, false); err != nil {
- panic(err)
- }
-
- opts, err := extractOperationOptionFromMethodDescriptor(meth.MethodDescriptorProto)
- if opts != nil {
- if err != nil {
- panic(err)
- }
- operationObject.ExternalDocs = protoExternalDocumentationToSwaggerExternalDocumentation(opts.ExternalDocs, reg, meth)
- // TODO(ivucica): this would be better supported by looking whether the method is deprecated in the proto file
- operationObject.Deprecated = opts.Deprecated
-
- if opts.Summary != "" {
- operationObject.Summary = opts.Summary
- }
- if opts.Description != "" {
- operationObject.Description = opts.Description
- }
- if len(opts.Tags) > 0 {
- operationObject.Tags = make([]string, len(opts.Tags))
- copy(operationObject.Tags, opts.Tags)
- }
- if opts.Security != nil {
- newSecurity := []swaggerSecurityRequirementObject{}
- if operationObject.Security != nil {
- newSecurity = *operationObject.Security
- }
- for _, secReq := range opts.Security {
- newSecReq := swaggerSecurityRequirementObject{}
- for secReqKey, secReqValue := range secReq.SecurityRequirement {
- if secReqValue == nil {
- continue
- }
-
- newSecReqValue := make([]string, len(secReqValue.Scope))
- copy(newSecReqValue, secReqValue.Scope)
- newSecReq[secReqKey] = newSecReqValue
- }
-
- if len(newSecReq) > 0 {
- newSecurity = append(newSecurity, newSecReq)
- }
- }
- operationObject.Security = &newSecurity
- }
- if opts.Responses != nil {
- for name, resp := range opts.Responses {
- respObj := swaggerResponseObject{
- Description: resp.Description,
- Schema: swaggerSchemaFromProtoSchema(resp.Schema, reg, customRefs, meth),
- }
- if resp.Extensions != nil {
- exts, err := processExtensions(resp.Extensions)
- if err != nil {
- return err
- }
- respObj.extensions = exts
- }
- operationObject.Responses[name] = respObj
- }
- }
-
- if opts.Extensions != nil {
- exts, err := processExtensions(opts.Extensions)
- if err != nil {
- return err
- }
- operationObject.extensions = exts
- }
-
- // TODO(ivucica): add remaining fields of operation object
- }
-
- switch b.HTTPMethod {
- case "DELETE":
- pathItemObject.Delete = operationObject
- break
- case "GET":
- pathItemObject.Get = operationObject
- break
- case "POST":
- pathItemObject.Post = operationObject
- break
- case "PUT":
- pathItemObject.Put = operationObject
- break
- case "PATCH":
- pathItemObject.Patch = operationObject
- break
- }
- paths[templateToSwaggerPath(b.PathTmpl.Template, reg)] = pathItemObject
- }
- }
- }
-
- // Success! return nil on the error object
- return nil
-}
-
-// This function is called with a param which contains the entire definition of a method.
-func applyTemplate(p param) (*swaggerObject, error) {
- // Create the basic template object. This is the object that everything is
- // defined off of.
- s := swaggerObject{
- // Swagger 2.0 is the version of this document
- Swagger: "2.0",
- Schemes: []string{"http", "https"},
- Consumes: []string{"application/json"},
- Produces: []string{"application/json"},
- Paths: make(swaggerPathsObject),
- Definitions: make(swaggerDefinitionsObject),
- StreamDefinitions: make(swaggerDefinitionsObject),
- Info: swaggerInfoObject{
- Title: *p.File.Name,
- Version: "version not set",
- },
- }
-
- // Loops through all the services and their exposed GET/POST/PUT/DELETE definitions
- // and create entries for all of them.
- // Also adds custom user specified references to second map.
- requestResponseRefs, customRefs := refMap{}, refMap{}
- if err := renderServices(p.Services, s.Paths, p.reg, requestResponseRefs, customRefs); err != nil {
- panic(err)
- }
-
- // Find all the service's messages and enumerations that are defined (recursively)
- // and write request, response and other custom (but referenced) types out as definition objects.
- m := messageMap{}
- ms := messageMap{}
- e := enumMap{}
- findServicesMessagesAndEnumerations(p.Services, p.reg, m, ms, e, requestResponseRefs)
- renderMessagesAsDefinition(m, s.Definitions, p.reg, customRefs)
- renderMessagesAsStreamDefinition(ms, s.StreamDefinitions, p.reg)
- renderEnumerationsAsDefinition(e, s.Definitions, p.reg)
-
- // File itself might have some comments and metadata.
- packageProtoPath := protoPathIndex(reflect.TypeOf((*pbdescriptor.FileDescriptorProto)(nil)), "Package")
- packageComments := protoComments(p.reg, p.File, nil, "Package", packageProtoPath)
- if err := updateSwaggerDataFromComments(p.reg, &s, p, packageComments, true); err != nil {
- panic(err)
- }
-
- // There may be additional options in the swagger option in the proto.
- spb, err := extractSwaggerOptionFromFileDescriptor(p.FileDescriptorProto)
- if err != nil {
- panic(err)
- }
- if spb != nil {
- if spb.Swagger != "" {
- s.Swagger = spb.Swagger
- }
- if spb.Info != nil {
- if spb.Info.Title != "" {
- s.Info.Title = spb.Info.Title
- }
- if spb.Info.Description != "" {
- s.Info.Description = spb.Info.Description
- }
- if spb.Info.TermsOfService != "" {
- s.Info.TermsOfService = spb.Info.TermsOfService
- }
- if spb.Info.Version != "" {
- s.Info.Version = spb.Info.Version
- }
- if spb.Info.Contact != nil {
- if s.Info.Contact == nil {
- s.Info.Contact = &swaggerContactObject{}
- }
- if spb.Info.Contact.Name != "" {
- s.Info.Contact.Name = spb.Info.Contact.Name
- }
- if spb.Info.Contact.Url != "" {
- s.Info.Contact.URL = spb.Info.Contact.Url
- }
- if spb.Info.Contact.Email != "" {
- s.Info.Contact.Email = spb.Info.Contact.Email
- }
- }
- if spb.Info.License != nil {
- if s.Info.License == nil {
- s.Info.License = &swaggerLicenseObject{}
- }
- if spb.Info.License.Name != "" {
- s.Info.License.Name = spb.Info.License.Name
- }
- if spb.Info.License.Url != "" {
- s.Info.License.URL = spb.Info.License.Url
- }
- }
- if spb.Info.Extensions != nil {
- exts, err := processExtensions(spb.Info.Extensions)
- if err != nil {
- return nil, err
- }
- s.Info.extensions = exts
- }
- }
- if spb.Host != "" {
- s.Host = spb.Host
- }
- if spb.BasePath != "" {
- s.BasePath = spb.BasePath
- }
- if len(spb.Schemes) > 0 {
- s.Schemes = make([]string, len(spb.Schemes))
- for i, scheme := range spb.Schemes {
- s.Schemes[i] = strings.ToLower(scheme.String())
- }
- }
- if len(spb.Consumes) > 0 {
- s.Consumes = make([]string, len(spb.Consumes))
- copy(s.Consumes, spb.Consumes)
- }
- if len(spb.Produces) > 0 {
- s.Produces = make([]string, len(spb.Produces))
- copy(s.Produces, spb.Produces)
- }
- if spb.SecurityDefinitions != nil && spb.SecurityDefinitions.Security != nil {
- if s.SecurityDefinitions == nil {
- s.SecurityDefinitions = swaggerSecurityDefinitionsObject{}
- }
- for secDefKey, secDefValue := range spb.SecurityDefinitions.Security {
- var newSecDefValue swaggerSecuritySchemeObject
- if oldSecDefValue, ok := s.SecurityDefinitions[secDefKey]; !ok {
- newSecDefValue = swaggerSecuritySchemeObject{}
- } else {
- newSecDefValue = oldSecDefValue
- }
- if secDefValue.Type != swagger_options.SecurityScheme_TYPE_INVALID {
- switch secDefValue.Type {
- case swagger_options.SecurityScheme_TYPE_BASIC:
- newSecDefValue.Type = "basic"
- case swagger_options.SecurityScheme_TYPE_API_KEY:
- newSecDefValue.Type = "apiKey"
- case swagger_options.SecurityScheme_TYPE_OAUTH2:
- newSecDefValue.Type = "oauth2"
- }
- }
- if secDefValue.Description != "" {
- newSecDefValue.Description = secDefValue.Description
- }
- if secDefValue.Name != "" {
- newSecDefValue.Name = secDefValue.Name
- }
- if secDefValue.In != swagger_options.SecurityScheme_IN_INVALID {
- switch secDefValue.In {
- case swagger_options.SecurityScheme_IN_QUERY:
- newSecDefValue.In = "query"
- case swagger_options.SecurityScheme_IN_HEADER:
- newSecDefValue.In = "header"
- }
- }
- if secDefValue.Flow != swagger_options.SecurityScheme_FLOW_INVALID {
- switch secDefValue.Flow {
- case swagger_options.SecurityScheme_FLOW_IMPLICIT:
- newSecDefValue.Flow = "implicit"
- case swagger_options.SecurityScheme_FLOW_PASSWORD:
- newSecDefValue.Flow = "password"
- case swagger_options.SecurityScheme_FLOW_APPLICATION:
- newSecDefValue.Flow = "application"
- case swagger_options.SecurityScheme_FLOW_ACCESS_CODE:
- newSecDefValue.Flow = "accessCode"
- }
- }
- if secDefValue.AuthorizationUrl != "" {
- newSecDefValue.AuthorizationURL = secDefValue.AuthorizationUrl
- }
- if secDefValue.TokenUrl != "" {
- newSecDefValue.TokenURL = secDefValue.TokenUrl
- }
- if secDefValue.Scopes != nil {
- if newSecDefValue.Scopes == nil {
- newSecDefValue.Scopes = swaggerScopesObject{}
- }
- for scopeKey, scopeDesc := range secDefValue.Scopes.Scope {
- newSecDefValue.Scopes[scopeKey] = scopeDesc
- }
- }
- if secDefValue.Extensions != nil {
- exts, err := processExtensions(secDefValue.Extensions)
- if err != nil {
- return nil, err
- }
- newSecDefValue.extensions = exts
- }
- s.SecurityDefinitions[secDefKey] = newSecDefValue
- }
- }
- if spb.Security != nil {
- newSecurity := []swaggerSecurityRequirementObject{}
- if s.Security == nil {
- newSecurity = []swaggerSecurityRequirementObject{}
- } else {
- newSecurity = s.Security
- }
- for _, secReq := range spb.Security {
- newSecReq := swaggerSecurityRequirementObject{}
- for secReqKey, secReqValue := range secReq.SecurityRequirement {
- newSecReqValue := make([]string, len(secReqValue.Scope))
- copy(newSecReqValue, secReqValue.Scope)
- newSecReq[secReqKey] = newSecReqValue
- }
- newSecurity = append(newSecurity, newSecReq)
- }
- s.Security = newSecurity
- }
- s.ExternalDocs = protoExternalDocumentationToSwaggerExternalDocumentation(spb.ExternalDocs, p.reg, spb)
- // Populate all Paths with Responses set at top level,
- // preferring Responses already set over those at the top level.
- if spb.Responses != nil {
- for _, verbs := range s.Paths {
- var maps []swaggerResponsesObject
- if verbs.Delete != nil {
- maps = append(maps, verbs.Delete.Responses)
- }
- if verbs.Get != nil {
- maps = append(maps, verbs.Get.Responses)
- }
- if verbs.Post != nil {
- maps = append(maps, verbs.Post.Responses)
- }
- if verbs.Put != nil {
- maps = append(maps, verbs.Put.Responses)
- }
- if verbs.Patch != nil {
- maps = append(maps, verbs.Patch.Responses)
- }
-
- for k, v := range spb.Responses {
- for _, respMap := range maps {
- if _, ok := respMap[k]; ok {
- // Don't overwrite already existing Responses
- continue
- }
- respMap[k] = swaggerResponseObject{
- Description: v.Description,
- Schema: swaggerSchemaFromProtoSchema(v.Schema, p.reg, customRefs, nil),
- }
- }
- }
- }
- }
-
- if spb.Extensions != nil {
- exts, err := processExtensions(spb.Extensions)
- if err != nil {
- return nil, err
- }
- s.extensions = exts
- }
-
- // Additional fields on the OpenAPI v2 spec's "Swagger" object
- // should be added here, once supported in the proto.
- }
-
- // Finally add any references added by users that aren't
- // otherwise rendered.
- addCustomRefs(s.Definitions, p.reg, customRefs)
-
- return &s, nil
-}
-
-func processExtensions(inputExts map[string]*structpb.Value) ([]extension, error) {
- exts := []extension{}
- for k, v := range inputExts {
- if !strings.HasPrefix(k, "x-") {
- return nil, fmt.Errorf("Extension keys need to start with \"x-\": %q", k)
- }
- ext, err := (&jsonpb.Marshaler{Indent: " "}).MarshalToString(v)
- if err != nil {
- return nil, err
- }
- exts = append(exts, extension{key: k, value: json.RawMessage(ext)})
- }
- sort.Slice(exts, func(i, j int) bool { return exts[i].key < exts[j].key })
- return exts, nil
-}
-
-// updateSwaggerDataFromComments updates a Swagger object based on a comment
-// from the proto file.
-//
-// First paragraph of a comment is used for summary. Remaining paragraphs of
-// a comment are used for description. If 'Summary' field is not present on
-// the passed swaggerObject, the summary and description are joined by \n\n.
-//
-// If there is a field named 'Info', its 'Summary' and 'Description' fields
-// will be updated instead.
-//
-// If there is no 'Summary', the same behavior will be attempted on 'Title',
-// but only if the last character is not a period.
-func updateSwaggerDataFromComments(reg *descriptor.Registry, swaggerObject interface{}, data interface{}, comment string, isPackageObject bool) error {
- if len(comment) == 0 {
- return nil
- }
-
- // Checks whether the "use_go_templates" flag is set to true
- if reg.GetUseGoTemplate() {
- comment = goTemplateComments(comment, data, reg)
- }
-
- // Figure out what to apply changes to.
- swaggerObjectValue := reflect.ValueOf(swaggerObject)
- infoObjectValue := swaggerObjectValue.Elem().FieldByName("Info")
- if !infoObjectValue.CanSet() {
- // No such field? Apply summary and description directly to
- // passed object.
- infoObjectValue = swaggerObjectValue.Elem()
- }
-
- // Figure out which properties to update.
- summaryValue := infoObjectValue.FieldByName("Summary")
- descriptionValue := infoObjectValue.FieldByName("Description")
- readOnlyValue := infoObjectValue.FieldByName("ReadOnly")
-
- if readOnlyValue.Kind() == reflect.Bool && readOnlyValue.CanSet() && strings.Contains(comment, "Output only.") {
- readOnlyValue.Set(reflect.ValueOf(true))
- }
-
- usingTitle := false
- if !summaryValue.CanSet() {
- summaryValue = infoObjectValue.FieldByName("Title")
- usingTitle = true
- }
-
- paragraphs := strings.Split(comment, "\n\n")
-
- // If there is a summary (or summary-equivalent) and it's empty, use the first
- // paragraph as summary, and the rest as description.
- if summaryValue.CanSet() {
- summary := strings.TrimSpace(paragraphs[0])
- description := strings.TrimSpace(strings.Join(paragraphs[1:], "\n\n"))
- if !usingTitle || (len(summary) > 0 && summary[len(summary)-1] != '.') {
- // overrides the schema value only if it's empty
- // keep the comment precedence when updating the package definition
- if summaryValue.Len() == 0 || isPackageObject {
- summaryValue.Set(reflect.ValueOf(summary))
- }
- if len(description) > 0 {
- if !descriptionValue.CanSet() {
- return fmt.Errorf("Encountered object type with a summary, but no description")
- }
- // overrides the schema value only if it's empty
- // keep the comment precedence when updating the package definition
- if descriptionValue.Len() == 0 || isPackageObject {
- descriptionValue.Set(reflect.ValueOf(description))
- }
- }
- return nil
- }
- }
-
- // There was no summary field on the swaggerObject. Try to apply the
- // whole comment into description if the swagger object description is empty.
- if descriptionValue.CanSet() {
- if descriptionValue.Len() == 0 || isPackageObject {
- descriptionValue.Set(reflect.ValueOf(strings.Join(paragraphs, "\n\n")))
- }
- return nil
- }
-
- return fmt.Errorf("no description nor summary property")
-}
-
-func fieldProtoComments(reg *descriptor.Registry, msg *descriptor.Message, field *descriptor.Field) string {
- protoPath := protoPathIndex(reflect.TypeOf((*pbdescriptor.DescriptorProto)(nil)), "Field")
- for i, f := range msg.Fields {
- if f == field {
- return protoComments(reg, msg.File, msg.Outers, "MessageType", int32(msg.Index), protoPath, int32(i))
- }
- }
- return ""
-}
-
-func enumValueProtoComments(reg *descriptor.Registry, enum *descriptor.Enum) string {
- protoPath := protoPathIndex(reflect.TypeOf((*pbdescriptor.EnumDescriptorProto)(nil)), "Value")
- var comments []string
- for idx, value := range enum.GetValue() {
- name := value.GetName()
- str := protoComments(reg, enum.File, enum.Outers, "EnumType", int32(enum.Index), protoPath, int32(idx))
- if str != "" {
- comments = append(comments, name+": "+str)
- }
- }
- if len(comments) > 0 {
- return "- " + strings.Join(comments, "\n - ")
- }
- return ""
-}
-
-func protoComments(reg *descriptor.Registry, file *descriptor.File, outers []string, typeName string, typeIndex int32, fieldPaths ...int32) string {
- if file.SourceCodeInfo == nil {
- fmt.Fprintln(os.Stderr, "descriptor.File should not contain nil SourceCodeInfo")
- return ""
- }
-
- outerPaths := make([]int32, len(outers))
- for i := range outers {
- location := ""
- if file.Package != nil {
- location = file.GetPackage()
- }
-
- msg, err := reg.LookupMsg(location, strings.Join(outers[:i+1], "."))
- if err != nil {
- panic(err)
- }
- outerPaths[i] = int32(msg.Index)
- }
-
- for _, loc := range file.SourceCodeInfo.Location {
- if !isProtoPathMatches(loc.Path, outerPaths, typeName, typeIndex, fieldPaths) {
- continue
- }
- comments := ""
- if loc.LeadingComments != nil {
- comments = strings.TrimRight(*loc.LeadingComments, "\n")
- comments = strings.TrimSpace(comments)
- // TODO(ivucica): this is a hack to fix "// " being interpreted as "//".
- // perhaps we should:
- // - split by \n
- // - determine if every (but first and last) line begins with " "
- // - trim every line only if that is the case
- // - join by \n
- comments = strings.Replace(comments, "\n ", "\n", -1)
- }
- return comments
- }
- return ""
-}
-
-func goTemplateComments(comment string, data interface{}, reg *descriptor.Registry) string {
- var temp bytes.Buffer
- tpl, err := template.New("").Funcs(template.FuncMap{
- // Allows importing documentation from a file
- "import": func(name string) string {
- file, err := ioutil.ReadFile(name)
- if err != nil {
- return err.Error()
- }
- // Runs template over imported file
- return goTemplateComments(string(file), data, reg)
- },
- // Grabs title and description from a field
- "fieldcomments": func(msg *descriptor.Message, field *descriptor.Field) string {
- return strings.Replace(fieldProtoComments(reg, msg, field), "\n", "
", -1)
- },
- }).Parse(comment)
- if err != nil {
- // If there is an error parsing the templating insert the error as string in the comment
- // to make it easier to debug the template error
- return err.Error()
- }
- err = tpl.Execute(&temp, data)
- if err != nil {
- // If there is an error executing the templating insert the error as string in the comment
- // to make it easier to debug the error
- return err.Error()
- }
- return temp.String()
-}
-
-var messageProtoPath = protoPathIndex(reflect.TypeOf((*pbdescriptor.FileDescriptorProto)(nil)), "MessageType")
-var nestedProtoPath = protoPathIndex(reflect.TypeOf((*pbdescriptor.DescriptorProto)(nil)), "NestedType")
-var packageProtoPath = protoPathIndex(reflect.TypeOf((*pbdescriptor.FileDescriptorProto)(nil)), "Package")
-var serviceProtoPath = protoPathIndex(reflect.TypeOf((*pbdescriptor.FileDescriptorProto)(nil)), "Service")
-var methodProtoPath = protoPathIndex(reflect.TypeOf((*pbdescriptor.ServiceDescriptorProto)(nil)), "Method")
-
-func isProtoPathMatches(paths []int32, outerPaths []int32, typeName string, typeIndex int32, fieldPaths []int32) bool {
- if typeName == "Package" && typeIndex == packageProtoPath {
- // path for package comments is just [2], and all the other processing
- // is too complex for it.
- if len(paths) == 0 || typeIndex != paths[0] {
- return false
- }
- return true
- }
-
- if len(paths) != len(outerPaths)*2+2+len(fieldPaths) {
- return false
- }
-
- if typeName == "Method" {
- if paths[0] != serviceProtoPath || paths[2] != methodProtoPath {
- return false
- }
- paths = paths[2:]
- } else {
- typeNameDescriptor := reflect.TypeOf((*pbdescriptor.FileDescriptorProto)(nil))
-
- if len(outerPaths) > 0 {
- if paths[0] != messageProtoPath || paths[1] != outerPaths[0] {
- return false
- }
- paths = paths[2:]
- outerPaths = outerPaths[1:]
-
- for i, v := range outerPaths {
- if paths[i*2] != nestedProtoPath || paths[i*2+1] != v {
- return false
- }
- }
- paths = paths[len(outerPaths)*2:]
-
- if typeName == "MessageType" {
- typeName = "NestedType"
- }
- typeNameDescriptor = reflect.TypeOf((*pbdescriptor.DescriptorProto)(nil))
- }
-
- if paths[0] != protoPathIndex(typeNameDescriptor, typeName) || paths[1] != typeIndex {
- return false
- }
- paths = paths[2:]
- }
-
- for i, v := range fieldPaths {
- if paths[i] != v {
- return false
- }
- }
- return true
-}
-
-// protoPathIndex returns a path component for google.protobuf.descriptor.SourceCode_Location.
-//
-// Specifically, it returns an id as generated from descriptor proto which
-// can be used to determine what type the id following it in the path is.
-// For example, if we are trying to locate comments related to a field named
-// `Address` in a message named `Person`, the path will be:
-//
-// [4, a, 2, b]
-//
-// While `a` gets determined by the order in which the messages appear in
-// the proto file, and `b` is the field index specified in the proto
-// file itself, the path actually needs to specify that `a` refers to a
-// message and not, say, a service; and that `b` refers to a field and not
-// an option.
-//
-// protoPathIndex figures out the values 4 and 2 in the above example. Because
-// messages are top level objects, the value of 4 comes from field id for
-// `MessageType` inside `google.protobuf.descriptor.FileDescriptor` message.
-// This field has a message type `google.protobuf.descriptor.DescriptorProto`.
-// And inside message `DescriptorProto`, there is a field named `Field` with id
-// 2.
-//
-// Some code generators seem to be hardcoding these values; this method instead
-// interprets them from `descriptor.proto`-derived Go source as necessary.
-func protoPathIndex(descriptorType reflect.Type, what string) int32 {
- field, ok := descriptorType.Elem().FieldByName(what)
- if !ok {
- panic(fmt.Errorf("could not find protobuf descriptor type id for %s", what))
- }
- pbtag := field.Tag.Get("protobuf")
- if pbtag == "" {
- panic(fmt.Errorf("no Go tag 'protobuf' on protobuf descriptor for %s", what))
- }
- path, err := strconv.Atoi(strings.Split(pbtag, ",")[1])
- if err != nil {
- panic(fmt.Errorf("protobuf descriptor id for %s cannot be converted to a number: %s", what, err.Error()))
- }
-
- return int32(path)
-}
-
-// extractOperationOptionFromMethodDescriptor extracts the message of type
-// swagger_options.Operation from a given proto method's descriptor.
-func extractOperationOptionFromMethodDescriptor(meth *pbdescriptor.MethodDescriptorProto) (*swagger_options.Operation, error) {
- if meth.Options == nil {
- return nil, nil
- }
- if !proto.HasExtension(meth.Options, swagger_options.E_Openapiv2Operation) {
- return nil, nil
- }
- ext, err := proto.GetExtension(meth.Options, swagger_options.E_Openapiv2Operation)
- if err != nil {
- return nil, err
- }
- opts, ok := ext.(*swagger_options.Operation)
- if !ok {
- return nil, fmt.Errorf("extension is %T; want an Operation", ext)
- }
- return opts, nil
-}
-
-// extractSchemaOptionFromMessageDescriptor extracts the message of type
-// swagger_options.Schema from a given proto message's descriptor.
-func extractSchemaOptionFromMessageDescriptor(msg *pbdescriptor.DescriptorProto) (*swagger_options.Schema, error) {
- if msg.Options == nil {
- return nil, nil
- }
- if !proto.HasExtension(msg.Options, swagger_options.E_Openapiv2Schema) {
- return nil, nil
- }
- ext, err := proto.GetExtension(msg.Options, swagger_options.E_Openapiv2Schema)
- if err != nil {
- return nil, err
- }
- opts, ok := ext.(*swagger_options.Schema)
- if !ok {
- return nil, fmt.Errorf("extension is %T; want a Schema", ext)
- }
- return opts, nil
-}
-
-// extractSwaggerOptionFromFileDescriptor extracts the message of type
-// swagger_options.Swagger from a given proto method's descriptor.
-func extractSwaggerOptionFromFileDescriptor(file *pbdescriptor.FileDescriptorProto) (*swagger_options.Swagger, error) {
- if file.Options == nil {
- return nil, nil
- }
- if !proto.HasExtension(file.Options, swagger_options.E_Openapiv2Swagger) {
- return nil, nil
- }
- ext, err := proto.GetExtension(file.Options, swagger_options.E_Openapiv2Swagger)
- if err != nil {
- return nil, err
- }
- opts, ok := ext.(*swagger_options.Swagger)
- if !ok {
- return nil, fmt.Errorf("extension is %T; want a Swagger object", ext)
- }
- return opts, nil
-}
-
-func extractJSONSchemaFromFieldDescriptor(fd *pbdescriptor.FieldDescriptorProto) (*swagger_options.JSONSchema, error) {
- if fd.Options == nil {
- return nil, nil
- }
- if !proto.HasExtension(fd.Options, swagger_options.E_Openapiv2Field) {
- return nil, nil
- }
- ext, err := proto.GetExtension(fd.Options, swagger_options.E_Openapiv2Field)
- if err != nil {
- return nil, err
- }
- opts, ok := ext.(*swagger_options.JSONSchema)
- if !ok {
- return nil, fmt.Errorf("extension is %T; want a JSONSchema object", ext)
- }
- return opts, nil
-}
-
-func protoJSONSchemaToSwaggerSchemaCore(j *swagger_options.JSONSchema, reg *descriptor.Registry, refs refMap) schemaCore {
- ret := schemaCore{}
-
- if j.GetRef() != "" {
- swaggerName := fullyQualifiedNameToSwaggerName(j.GetRef(), reg)
- if swaggerName != "" {
- ret.Ref = "#/definitions/" + swaggerName
- if refs != nil {
- refs[j.GetRef()] = struct{}{}
- }
- } else {
- ret.Ref += j.GetRef()
- }
- } else {
- f, t := protoJSONSchemaTypeToFormat(j.GetType())
- ret.Format = f
- ret.Type = t
- }
-
- return ret
-}
-
-func updateSwaggerObjectFromJSONSchema(s *swaggerSchemaObject, j *swagger_options.JSONSchema, reg *descriptor.Registry, data interface{}) {
- s.Title = j.GetTitle()
- s.Description = j.GetDescription()
- if reg.GetUseGoTemplate() {
- s.Title = goTemplateComments(s.Title, data, reg)
- s.Description = goTemplateComments(s.Description, data, reg)
- }
-
- s.ReadOnly = j.GetReadOnly()
- s.MultipleOf = j.GetMultipleOf()
- s.Maximum = j.GetMaximum()
- s.ExclusiveMaximum = j.GetExclusiveMaximum()
- s.Minimum = j.GetMinimum()
- s.ExclusiveMinimum = j.GetExclusiveMinimum()
- s.MaxLength = j.GetMaxLength()
- s.MinLength = j.GetMinLength()
- s.Pattern = j.GetPattern()
- s.Default = j.GetDefault()
- s.MaxItems = j.GetMaxItems()
- s.MinItems = j.GetMinItems()
- s.UniqueItems = j.GetUniqueItems()
- s.MaxProperties = j.GetMaxProperties()
- s.MinProperties = j.GetMinProperties()
- s.Required = j.GetRequired()
- if overrideType := j.GetType(); len(overrideType) > 0 {
- s.Type = strings.ToLower(overrideType[0].String())
- }
-}
-
-func swaggerSchemaFromProtoSchema(s *swagger_options.Schema, reg *descriptor.Registry, refs refMap, data interface{}) swaggerSchemaObject {
- ret := swaggerSchemaObject{
- ExternalDocs: protoExternalDocumentationToSwaggerExternalDocumentation(s.GetExternalDocs(), reg, data),
- }
-
- ret.schemaCore = protoJSONSchemaToSwaggerSchemaCore(s.GetJsonSchema(), reg, refs)
- updateSwaggerObjectFromJSONSchema(&ret, s.GetJsonSchema(), reg, data)
-
- if s != nil && s.Example != nil {
- ret.Example = json.RawMessage(s.Example.Value)
- }
-
- return ret
-}
-
-func protoJSONSchemaTypeToFormat(in []swagger_options.JSONSchema_JSONSchemaSimpleTypes) (string, string) {
- if len(in) == 0 {
- return "", ""
- }
-
- // Can't support more than 1 type, just return the first element.
- // This is due to an inconsistency in the design of the openapiv2 proto
- // and that used in schemaCore. schemaCore uses the v3 definition of types,
- // which only allows a single string, while the openapiv2 proto uses the OpenAPI v2
- // definition, which defers to the JSON schema definition, which allows a string or an array.
- // Sources:
- // https://swagger.io/specification/#itemsObject
- // https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.5.2
- switch in[0] {
- case swagger_options.JSONSchema_UNKNOWN, swagger_options.JSONSchema_NULL:
- return "", ""
- case swagger_options.JSONSchema_OBJECT:
- return "object", ""
- case swagger_options.JSONSchema_ARRAY:
- return "array", ""
- case swagger_options.JSONSchema_BOOLEAN:
- return "boolean", "boolean"
- case swagger_options.JSONSchema_INTEGER:
- return "integer", "int32"
- case swagger_options.JSONSchema_NUMBER:
- return "number", "double"
- case swagger_options.JSONSchema_STRING:
- // NOTE: in swagger specifition, format should be empty on string type
- return "string", ""
- default:
- // Maybe panic?
- return "", ""
- }
-}
-
-func protoExternalDocumentationToSwaggerExternalDocumentation(in *swagger_options.ExternalDocumentation, reg *descriptor.Registry, data interface{}) *swaggerExternalDocumentationObject {
- if in == nil {
- return nil
- }
-
- if reg.GetUseGoTemplate() {
- in.Description = goTemplateComments(in.Description, data, reg)
- }
-
- return &swaggerExternalDocumentationObject{
- Description: in.Description,
- URL: in.Url,
- }
-}
-
-func addCustomRefs(d swaggerDefinitionsObject, reg *descriptor.Registry, refs refMap) {
- if len(refs) == 0 {
- return
- }
- msgMap := make(messageMap)
- enumMap := make(enumMap)
- for ref := range refs {
- if _, ok := d[fullyQualifiedNameToSwaggerName(ref, reg)]; ok {
- // Skip already existing definitions
- delete(refs, ref)
- continue
- }
- msg, err := reg.LookupMsg("", ref)
- if err == nil {
- msgMap[fullyQualifiedNameToSwaggerName(ref, reg)] = msg
- continue
- }
- enum, err := reg.LookupEnum("", ref)
- if err == nil {
- enumMap[fullyQualifiedNameToSwaggerName(ref, reg)] = enum
- continue
- }
-
- // ?? Should be either enum or msg
- }
- renderMessagesAsDefinition(msgMap, d, reg, refs)
- renderEnumerationsAsDefinition(enumMap, d, reg)
-
- // Run again in case any new refs were added
- addCustomRefs(d, reg, refs)
-}
-
-func lowerCamelCase(parameter string) string {
- parameterString := gogen.CamelCase(parameter)
- builder := &strings.Builder{}
- builder.WriteString(strings.ToLower(string(parameterString[0])))
- builder.WriteString(parameterString[1:])
- return builder.String()
-}
diff --git a/gateway/protoc-gen-swagger/genswagger/template_test.go b/gateway/protoc-gen-swagger/genswagger/template_test.go
deleted file mode 100644
index 2571d87..0000000
--- a/gateway/protoc-gen-swagger/genswagger/template_test.go
+++ /dev/null
@@ -1,1965 +0,0 @@
-package genswagger
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "reflect"
- "testing"
-
- "github.com/golang/protobuf/proto"
- protodescriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
- plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
- "github.com/golang/protobuf/ptypes/any"
- structpb "github.com/golang/protobuf/ptypes/struct"
- // "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
- "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/descriptor"
-
- // "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule"
- "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/httprule"
-
- // swagger_options "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options"
- swagger_options "github.com/binchencoder/ease-gateway/gateway/protoc-gen-swagger/options"
-)
-
-func crossLinkFixture(f *descriptor.File) *descriptor.File {
- for _, m := range f.Messages {
- m.File = f
- }
- for _, svc := range f.Services {
- svc.File = f
- for _, m := range svc.Methods {
- m.Service = svc
- for _, b := range m.Bindings {
- b.Method = m
- for _, param := range b.PathParams {
- param.Method = m
- }
- }
- }
- }
- return f
-}
-
-func TestMessageToQueryParameters(t *testing.T) {
- type test struct {
- MsgDescs []*protodescriptor.DescriptorProto
- Message string
- Params []swaggerParameterObject
- }
-
- tests := []test{
- {
- MsgDescs: []*protodescriptor.DescriptorProto{
- &protodescriptor.DescriptorProto{
- Name: proto.String("ExampleMessage"),
- Field: []*protodescriptor.FieldDescriptorProto{
- {
- Name: proto.String("a"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_STRING.Enum(),
- Number: proto.Int32(1),
- },
- {
- Name: proto.String("b"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_DOUBLE.Enum(),
- Number: proto.Int32(2),
- },
- {
- Name: proto.String("c"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_STRING.Enum(),
- Label: protodescriptor.FieldDescriptorProto_LABEL_REPEATED.Enum(),
- Number: proto.Int32(3),
- },
- },
- },
- },
- Message: "ExampleMessage",
- Params: []swaggerParameterObject{
- swaggerParameterObject{
- Name: "a",
- In: "query",
- Required: false,
- Type: "string",
- },
- swaggerParameterObject{
- Name: "b",
- In: "query",
- Required: false,
- Type: "number",
- Format: "double",
- },
- swaggerParameterObject{
- Name: "c",
- In: "query",
- Required: false,
- Type: "array",
- CollectionFormat: "multi",
- },
- },
- },
- {
- MsgDescs: []*protodescriptor.DescriptorProto{
- &protodescriptor.DescriptorProto{
- Name: proto.String("ExampleMessage"),
- Field: []*protodescriptor.FieldDescriptorProto{
- {
- Name: proto.String("nested"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
- TypeName: proto.String(".example.Nested"),
- Number: proto.Int32(1),
- },
- },
- },
- &protodescriptor.DescriptorProto{
- Name: proto.String("Nested"),
- Field: []*protodescriptor.FieldDescriptorProto{
- {
- Name: proto.String("a"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_STRING.Enum(),
- Number: proto.Int32(1),
- },
- {
- Name: proto.String("deep"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
- TypeName: proto.String(".example.Nested.DeepNested"),
- Number: proto.Int32(2),
- },
- },
- NestedType: []*protodescriptor.DescriptorProto{{
- Name: proto.String("DeepNested"),
- Field: []*protodescriptor.FieldDescriptorProto{
- {
- Name: proto.String("b"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_STRING.Enum(),
- Number: proto.Int32(1),
- },
- {
- Name: proto.String("c"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_ENUM.Enum(),
- TypeName: proto.String(".example.Nested.DeepNested.DeepEnum"),
- Number: proto.Int32(2),
- },
- },
- EnumType: []*protodescriptor.EnumDescriptorProto{
- {
- Name: proto.String("DeepEnum"),
- Value: []*protodescriptor.EnumValueDescriptorProto{
- {Name: proto.String("FALSE"), Number: proto.Int32(0)},
- {Name: proto.String("TRUE"), Number: proto.Int32(1)},
- },
- },
- },
- }},
- },
- },
- Message: "ExampleMessage",
- Params: []swaggerParameterObject{
- swaggerParameterObject{
- Name: "nested.a",
- In: "query",
- Required: false,
- Type: "string",
- },
- swaggerParameterObject{
- Name: "nested.deep.b",
- In: "query",
- Required: false,
- Type: "string",
- },
- swaggerParameterObject{
- Name: "nested.deep.c",
- In: "query",
- Required: false,
- Type: "string",
- Enum: []string{"FALSE", "TRUE"},
- Default: "FALSE",
- },
- },
- },
- }
-
- for _, test := range tests {
- reg := descriptor.NewRegistry()
- msgs := []*descriptor.Message{}
- for _, msgdesc := range test.MsgDescs {
- msgs = append(msgs, &descriptor.Message{DescriptorProto: msgdesc})
- }
- file := descriptor.File{
- FileDescriptorProto: &protodescriptor.FileDescriptorProto{
- SourceCodeInfo: &protodescriptor.SourceCodeInfo{},
- Name: proto.String("example.proto"),
- Package: proto.String("example"),
- Dependency: []string{},
- MessageType: test.MsgDescs,
- Service: []*protodescriptor.ServiceDescriptorProto{},
- },
- GoPkg: descriptor.GoPackage{
- Path: "example.com/path/to/example/example.pb",
- Name: "example_pb",
- },
- Messages: msgs,
- }
- reg.Load(&plugin.CodeGeneratorRequest{
- ProtoFile: []*protodescriptor.FileDescriptorProto{file.FileDescriptorProto},
- })
-
- message, err := reg.LookupMsg("", ".example."+test.Message)
- if err != nil {
- t.Fatalf("failed to lookup message: %s", err)
- }
- params, err := messageToQueryParameters(message, reg, []descriptor.Parameter{})
- if err != nil {
- t.Fatalf("failed to convert message to query parameters: %s", err)
- }
- // avoid checking Items for array types
- for i := range params {
- params[i].Items = nil
- }
- if !reflect.DeepEqual(params, test.Params) {
- t.Errorf("expected %v, got %v", test.Params, params)
- }
- }
-}
-
-func TestMessageToQueryParametersWithJsonName(t *testing.T) {
- type test struct {
- MsgDescs []*protodescriptor.DescriptorProto
- Message string
- Params []swaggerParameterObject
- }
-
- tests := []test{
- {
- MsgDescs: []*protodescriptor.DescriptorProto{
- &protodescriptor.DescriptorProto{
- Name: proto.String("ExampleMessage"),
- Field: []*protodescriptor.FieldDescriptorProto{
- {
- Name: proto.String("test_field_a"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_STRING.Enum(),
- Number: proto.Int32(1),
- JsonName: proto.String("testFieldA"),
- },
- },
- },
- },
- Message: "ExampleMessage",
- Params: []swaggerParameterObject{
- swaggerParameterObject{
- Name: "testFieldA",
- In: "query",
- Required: false,
- Type: "string",
- },
- },
- },
- }
-
- for _, test := range tests {
- reg := descriptor.NewRegistry()
- reg.SetUseJSONNamesForFields(true)
- msgs := []*descriptor.Message{}
- for _, msgdesc := range test.MsgDescs {
- msgs = append(msgs, &descriptor.Message{DescriptorProto: msgdesc})
- }
- file := descriptor.File{
- FileDescriptorProto: &protodescriptor.FileDescriptorProto{
- SourceCodeInfo: &protodescriptor.SourceCodeInfo{},
- Name: proto.String("example.proto"),
- Package: proto.String("example"),
- Dependency: []string{},
- MessageType: test.MsgDescs,
- Service: []*protodescriptor.ServiceDescriptorProto{},
- },
- GoPkg: descriptor.GoPackage{
- Path: "example.com/path/to/example/example.pb",
- Name: "example_pb",
- },
- Messages: msgs,
- }
- reg.Load(&plugin.CodeGeneratorRequest{
- ProtoFile: []*protodescriptor.FileDescriptorProto{file.FileDescriptorProto},
- })
-
- message, err := reg.LookupMsg("", ".example."+test.Message)
- if err != nil {
- t.Fatalf("failed to lookup message: %s", err)
- }
- params, err := messageToQueryParameters(message, reg, []descriptor.Parameter{})
- if err != nil {
- t.Fatalf("failed to convert message to query parameters: %s", err)
- }
- if !reflect.DeepEqual(params, test.Params) {
- t.Errorf("expected %v, got %v", test.Params, params)
- }
- }
-}
-
-func TestApplyTemplateSimple(t *testing.T) {
- msgdesc := &protodescriptor.DescriptorProto{
- Name: proto.String("ExampleMessage"),
- }
- meth := &protodescriptor.MethodDescriptorProto{
- Name: proto.String("Example"),
- InputType: proto.String("ExampleMessage"),
- OutputType: proto.String("ExampleMessage"),
- }
- svc := &protodescriptor.ServiceDescriptorProto{
- Name: proto.String("ExampleService"),
- Method: []*protodescriptor.MethodDescriptorProto{meth},
- }
- msg := &descriptor.Message{
- DescriptorProto: msgdesc,
- }
- file := descriptor.File{
- FileDescriptorProto: &protodescriptor.FileDescriptorProto{
- SourceCodeInfo: &protodescriptor.SourceCodeInfo{},
- Name: proto.String("example.proto"),
- Package: proto.String("example"),
- Dependency: []string{"a.example/b/c.proto", "a.example/d/e.proto"},
- MessageType: []*protodescriptor.DescriptorProto{msgdesc},
- Service: []*protodescriptor.ServiceDescriptorProto{svc},
- },
- GoPkg: descriptor.GoPackage{
- Path: "example.com/path/to/example/example.pb",
- Name: "example_pb",
- },
- Messages: []*descriptor.Message{msg},
- Services: []*descriptor.Service{
- {
- ServiceDescriptorProto: svc,
- Methods: []*descriptor.Method{
- {
- MethodDescriptorProto: meth,
- RequestType: msg,
- ResponseType: msg,
- Bindings: []*descriptor.Binding{
- {
- HTTPMethod: "GET",
- Body: &descriptor.Body{FieldPath: nil},
- PathTmpl: httprule.Template{
- Version: 1,
- OpCodes: []int{0, 0},
- Template: "/v1/echo", // TODO(achew22): Figure out what this should really be
- },
- },
- },
- },
- },
- },
- },
- }
- result, err := applyTemplate(param{File: crossLinkFixture(&file), reg: descriptor.NewRegistry()})
- if err != nil {
- t.Errorf("applyTemplate(%#v) failed with %v; want success", file, err)
- return
- }
- if want, is, name := "2.0", result.Swagger, "Swagger"; !reflect.DeepEqual(is, want) {
- t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
- }
- if want, is, name := "", result.BasePath, "BasePath"; !reflect.DeepEqual(is, want) {
- t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
- }
- if want, is, name := []string{"http", "https"}, result.Schemes, "Schemes"; !reflect.DeepEqual(is, want) {
- t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
- }
- if want, is, name := []string{"application/json"}, result.Consumes, "Consumes"; !reflect.DeepEqual(is, want) {
- t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
- }
- if want, is, name := []string{"application/json"}, result.Produces, "Produces"; !reflect.DeepEqual(is, want) {
- t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
- }
-
- // If there was a failure, print out the input and the json result for debugging.
- if t.Failed() {
- t.Errorf("had: %s", file)
- t.Errorf("got: %s", fmt.Sprint(result))
- }
-}
-
-func TestApplyTemplateExtensions(t *testing.T) {
- msgdesc := &protodescriptor.DescriptorProto{
- Name: proto.String("ExampleMessage"),
- }
- meth := &protodescriptor.MethodDescriptorProto{
- Name: proto.String("Example"),
- InputType: proto.String("ExampleMessage"),
- OutputType: proto.String("ExampleMessage"),
- Options: &protodescriptor.MethodOptions{},
- }
- svc := &protodescriptor.ServiceDescriptorProto{
- Name: proto.String("ExampleService"),
- Method: []*protodescriptor.MethodDescriptorProto{meth},
- }
- msg := &descriptor.Message{
- DescriptorProto: msgdesc,
- }
- file := descriptor.File{
- FileDescriptorProto: &protodescriptor.FileDescriptorProto{
- SourceCodeInfo: &protodescriptor.SourceCodeInfo{},
- Name: proto.String("example.proto"),
- Package: proto.String("example"),
- Dependency: []string{"a.example/b/c.proto", "a.example/d/e.proto"},
- MessageType: []*protodescriptor.DescriptorProto{msgdesc},
- Service: []*protodescriptor.ServiceDescriptorProto{svc},
- Options: &protodescriptor.FileOptions{},
- },
- GoPkg: descriptor.GoPackage{
- Path: "example.com/path/to/example/example.pb",
- Name: "example_pb",
- },
- Messages: []*descriptor.Message{msg},
- Services: []*descriptor.Service{
- {
- ServiceDescriptorProto: svc,
- Methods: []*descriptor.Method{
- {
- MethodDescriptorProto: meth,
- RequestType: msg,
- ResponseType: msg,
- Bindings: []*descriptor.Binding{
- {
- HTTPMethod: "GET",
- Body: &descriptor.Body{FieldPath: nil},
- PathTmpl: httprule.Template{
- Version: 1,
- OpCodes: []int{0, 0},
- Template: "/v1/echo", // TODO(achew22): Figure out what this should really be
- },
- },
- },
- },
- },
- },
- },
- }
- swagger := swagger_options.Swagger{
- Info: &swagger_options.Info{
- Title: "test",
- Extensions: map[string]*structpb.Value{
- "x-info-extension": &structpb.Value{Kind: &structpb.Value_StringValue{StringValue: "bar"}},
- },
- },
- Extensions: map[string]*structpb.Value{
- "x-foo": &structpb.Value{Kind: &structpb.Value_StringValue{StringValue: "bar"}},
- "x-bar": &structpb.Value{Kind: &structpb.Value_ListValue{ListValue: &structpb.ListValue{
- Values: []*structpb.Value{{Kind: &structpb.Value_StringValue{StringValue: "baz"}}},
- }}},
- },
- SecurityDefinitions: &swagger_options.SecurityDefinitions{
- Security: map[string]*swagger_options.SecurityScheme{
- "somescheme": &swagger_options.SecurityScheme{
- Extensions: map[string]*structpb.Value{
- "x-security-baz": &structpb.Value{Kind: &structpb.Value_BoolValue{BoolValue: true}},
- },
- },
- },
- },
- }
- if err := proto.SetExtension(proto.Message(file.FileDescriptorProto.Options), swagger_options.E_Openapiv2Swagger, &swagger); err != nil {
- t.Fatalf("proto.SetExtension(FileDescriptorProto.Options) failed: %v", err)
- }
-
- swaggerOperation := swagger_options.Operation{
- Responses: map[string]*swagger_options.Response{
- "200": &swagger_options.Response{
- Extensions: map[string]*structpb.Value{
- "x-resp-id": &structpb.Value{Kind: &structpb.Value_StringValue{StringValue: "resp1000"}},
- },
- },
- },
- Extensions: map[string]*structpb.Value{
- "x-op-foo": &structpb.Value{Kind: &structpb.Value_StringValue{StringValue: "baz"}},
- },
- }
- if err := proto.SetExtension(proto.Message(meth.Options), swagger_options.E_Openapiv2Operation, &swaggerOperation); err != nil {
- t.Fatalf("proto.SetExtension(MethodDescriptorProto.Options) failed: %v", err)
- }
- result, err := applyTemplate(param{File: crossLinkFixture(&file), reg: descriptor.NewRegistry()})
- if err != nil {
- t.Errorf("applyTemplate(%#v) failed with %v; want success", file, err)
- return
- }
- if want, is, name := "2.0", result.Swagger, "Swagger"; !reflect.DeepEqual(is, want) {
- t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
- }
- if want, is, name := []extension{
- {key: "x-bar", value: json.RawMessage("[\n \"baz\"\n ]")},
- {key: "x-foo", value: json.RawMessage("\"bar\"")},
- }, result.extensions, "Extensions"; !reflect.DeepEqual(is, want) {
- t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
- }
-
- var scheme swaggerSecuritySchemeObject
- for _, v := range result.SecurityDefinitions {
- scheme = v
- }
- if want, is, name := []extension{
- {key: "x-security-baz", value: json.RawMessage("true")},
- }, scheme.extensions, "SecurityScheme.Extensions"; !reflect.DeepEqual(is, want) {
- t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
- }
-
- if want, is, name := []extension{
- {key: "x-info-extension", value: json.RawMessage("\"bar\"")},
- }, result.Info.extensions, "Info.Extensions"; !reflect.DeepEqual(is, want) {
- t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
- }
-
- var operation *swaggerOperationObject
- var response swaggerResponseObject
- for _, v := range result.Paths {
- operation = v.Get
- response = v.Get.Responses["200"]
- }
- if want, is, name := []extension{
- {key: "x-op-foo", value: json.RawMessage("\"baz\"")},
- }, operation.extensions, "operation.Extensions"; !reflect.DeepEqual(is, want) {
- t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
- }
- if want, is, name := []extension{
- {key: "x-resp-id", value: json.RawMessage("\"resp1000\"")},
- }, response.extensions, "response.Extensions"; !reflect.DeepEqual(is, want) {
- t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
- }
-}
-
-func TestApplyTemplateRequestWithoutClientStreaming(t *testing.T) {
- msgdesc := &protodescriptor.DescriptorProto{
- Name: proto.String("ExampleMessage"),
- Field: []*protodescriptor.FieldDescriptorProto{
- {
- Name: proto.String("nested"),
- Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
- TypeName: proto.String("NestedMessage"),
- Number: proto.Int32(1),
- },
- },
- }
- nesteddesc := &protodescriptor.DescriptorProto{
- Name: proto.String("NestedMessage"),
- Field: []*protodescriptor.FieldDescriptorProto{
- {
- Name: proto.String("int32"),
- Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
- Type: protodescriptor.FieldDescriptorProto_TYPE_INT32.Enum(),
- Number: proto.Int32(1),
- },
- {
- Name: proto.String("bool"),
- Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
- Type: protodescriptor.FieldDescriptorProto_TYPE_BOOL.Enum(),
- Number: proto.Int32(2),
- },
- },
- }
- meth := &protodescriptor.MethodDescriptorProto{
- Name: proto.String("Echo"),
- InputType: proto.String("ExampleMessage"),
- OutputType: proto.String("ExampleMessage"),
- ClientStreaming: proto.Bool(false),
- }
- svc := &protodescriptor.ServiceDescriptorProto{
- Name: proto.String("ExampleService"),
- Method: []*protodescriptor.MethodDescriptorProto{meth},
- }
-
- meth.ServerStreaming = proto.Bool(false)
-
- msg := &descriptor.Message{
- DescriptorProto: msgdesc,
- }
- nested := &descriptor.Message{
- DescriptorProto: nesteddesc,
- }
-
- nestedField := &descriptor.Field{
- Message: msg,
- FieldDescriptorProto: msg.GetField()[0],
- }
- intField := &descriptor.Field{
- Message: nested,
- FieldDescriptorProto: nested.GetField()[0],
- }
- boolField := &descriptor.Field{
- Message: nested,
- FieldDescriptorProto: nested.GetField()[1],
- }
- file := descriptor.File{
- FileDescriptorProto: &protodescriptor.FileDescriptorProto{
- SourceCodeInfo: &protodescriptor.SourceCodeInfo{},
- Name: proto.String("example.proto"),
- Package: proto.String("example"),
- MessageType: []*protodescriptor.DescriptorProto{msgdesc, nesteddesc},
- Service: []*protodescriptor.ServiceDescriptorProto{svc},
- },
- GoPkg: descriptor.GoPackage{
- Path: "example.com/path/to/example/example.pb",
- Name: "example_pb",
- },
- Messages: []*descriptor.Message{msg, nested},
- Services: []*descriptor.Service{
- {
- ServiceDescriptorProto: svc,
- Methods: []*descriptor.Method{
- {
- MethodDescriptorProto: meth,
- RequestType: msg,
- ResponseType: msg,
- Bindings: []*descriptor.Binding{
- {
- HTTPMethod: "POST",
- PathTmpl: httprule.Template{
- Version: 1,
- OpCodes: []int{0, 0},
- Template: "/v1/echo", // TODO(achew): Figure out what this hsould really be
- },
- PathParams: []descriptor.Parameter{
- {
- FieldPath: descriptor.FieldPath([]descriptor.FieldPathComponent{
- {
- Name: "nested",
- Target: nestedField,
- },
- {
- Name: "int32",
- Target: intField,
- },
- }),
- Target: intField,
- },
- },
- Body: &descriptor.Body{
- FieldPath: descriptor.FieldPath([]descriptor.FieldPathComponent{
- {
- Name: "nested",
- Target: nestedField,
- },
- {
- Name: "bool",
- Target: boolField,
- },
- }),
- },
- },
- },
- },
- },
- },
- },
- }
- reg := descriptor.NewRegistry()
- reg.Load(&plugin.CodeGeneratorRequest{ProtoFile: []*protodescriptor.FileDescriptorProto{file.FileDescriptorProto}})
- result, err := applyTemplate(param{File: crossLinkFixture(&file), reg: reg})
- if err != nil {
- t.Errorf("applyTemplate(%#v) failed with %v; want success", file, err)
- return
- }
- if want, got := "2.0", result.Swagger; !reflect.DeepEqual(got, want) {
- t.Errorf("applyTemplate(%#v).Swagger = %s want to be %s", file, got, want)
- }
- if want, got := "", result.BasePath; !reflect.DeepEqual(got, want) {
- t.Errorf("applyTemplate(%#v).BasePath = %s want to be %s", file, got, want)
- }
- if want, got := []string{"http", "https"}, result.Schemes; !reflect.DeepEqual(got, want) {
- t.Errorf("applyTemplate(%#v).Schemes = %s want to be %s", file, got, want)
- }
- if want, got := []string{"application/json"}, result.Consumes; !reflect.DeepEqual(got, want) {
- t.Errorf("applyTemplate(%#v).Consumes = %s want to be %s", file, got, want)
- }
- if want, got := []string{"application/json"}, result.Produces; !reflect.DeepEqual(got, want) {
- t.Errorf("applyTemplate(%#v).Produces = %s want to be %s", file, got, want)
- }
-
- // If there was a failure, print out the input and the json result for debugging.
- if t.Failed() {
- t.Errorf("had: %s", file)
- t.Errorf("got: %s", fmt.Sprint(result))
- }
-}
-
-func TestApplyTemplateRequestWithClientStreaming(t *testing.T) {
- msgdesc := &protodescriptor.DescriptorProto{
- Name: proto.String("ExampleMessage"),
- Field: []*protodescriptor.FieldDescriptorProto{
- {
- Name: proto.String("nested"),
- Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
- TypeName: proto.String("NestedMessage"),
- Number: proto.Int32(1),
- },
- },
- }
- nesteddesc := &protodescriptor.DescriptorProto{
- Name: proto.String("NestedMessage"),
- Field: []*protodescriptor.FieldDescriptorProto{
- {
- Name: proto.String("int32"),
- Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
- Type: protodescriptor.FieldDescriptorProto_TYPE_INT32.Enum(),
- Number: proto.Int32(1),
- },
- {
- Name: proto.String("bool"),
- Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
- Type: protodescriptor.FieldDescriptorProto_TYPE_BOOL.Enum(),
- Number: proto.Int32(2),
- },
- },
- }
- meth := &protodescriptor.MethodDescriptorProto{
- Name: proto.String("Echo"),
- InputType: proto.String("ExampleMessage"),
- OutputType: proto.String("ExampleMessage"),
- ClientStreaming: proto.Bool(true),
- ServerStreaming: proto.Bool(true),
- }
- svc := &protodescriptor.ServiceDescriptorProto{
- Name: proto.String("ExampleService"),
- Method: []*protodescriptor.MethodDescriptorProto{meth},
- }
-
- msg := &descriptor.Message{
- DescriptorProto: msgdesc,
- }
- nested := &descriptor.Message{
- DescriptorProto: nesteddesc,
- }
-
- nestedField := &descriptor.Field{
- Message: msg,
- FieldDescriptorProto: msg.GetField()[0],
- }
- intField := &descriptor.Field{
- Message: nested,
- FieldDescriptorProto: nested.GetField()[0],
- }
- boolField := &descriptor.Field{
- Message: nested,
- FieldDescriptorProto: nested.GetField()[1],
- }
- file := descriptor.File{
- FileDescriptorProto: &protodescriptor.FileDescriptorProto{
- SourceCodeInfo: &protodescriptor.SourceCodeInfo{},
- Name: proto.String("example.proto"),
- Package: proto.String("example"),
- MessageType: []*protodescriptor.DescriptorProto{msgdesc, nesteddesc},
- Service: []*protodescriptor.ServiceDescriptorProto{svc},
- },
- GoPkg: descriptor.GoPackage{
- Path: "example.com/path/to/example/example.pb",
- Name: "example_pb",
- },
- Messages: []*descriptor.Message{msg, nested},
- Services: []*descriptor.Service{
- {
- ServiceDescriptorProto: svc,
- Methods: []*descriptor.Method{
- {
- MethodDescriptorProto: meth,
- RequestType: msg,
- ResponseType: msg,
- Bindings: []*descriptor.Binding{
- {
- HTTPMethod: "POST",
- PathTmpl: httprule.Template{
- Version: 1,
- OpCodes: []int{0, 0},
- Template: "/v1/echo", // TODO(achew): Figure out what this hsould really be
- },
- PathParams: []descriptor.Parameter{
- {
- FieldPath: descriptor.FieldPath([]descriptor.FieldPathComponent{
- {
- Name: "nested",
- Target: nestedField,
- },
- {
- Name: "int32",
- Target: intField,
- },
- }),
- Target: intField,
- },
- },
- Body: &descriptor.Body{
- FieldPath: descriptor.FieldPath([]descriptor.FieldPathComponent{
- {
- Name: "nested",
- Target: nestedField,
- },
- {
- Name: "bool",
- Target: boolField,
- },
- }),
- },
- },
- },
- },
- },
- },
- },
- }
- reg := descriptor.NewRegistry()
- if err := AddStreamError(reg); err != nil {
- t.Errorf("AddStreamError(%#v) failed with %v; want success", reg, err)
- return
- }
- reg.Load(&plugin.CodeGeneratorRequest{ProtoFile: []*protodescriptor.FileDescriptorProto{file.FileDescriptorProto}})
- result, err := applyTemplate(param{File: crossLinkFixture(&file), reg: reg})
- if err != nil {
- t.Errorf("applyTemplate(%#v) failed with %v; want success", file, err)
- return
- }
-
- // Only ExampleMessage must be present, not NestedMessage
- if want, got, name := 3, len(result.Definitions), "len(Definitions)"; !reflect.DeepEqual(got, want) {
- t.Errorf("applyTemplate(%#v).%s = %d want to be %d", file, name, got, want)
- }
- // stream ExampleMessage must be present
- if want, got, name := 1, len(result.StreamDefinitions), "len(StreamDefinitions)"; !reflect.DeepEqual(got, want) {
- t.Errorf("applyTemplate(%#v).%s = %d want to be %d", file, name, got, want)
- } else {
- streamExampleExampleMessage := result.StreamDefinitions["exampleExampleMessage"]
- if want, got, name := "object", streamExampleExampleMessage.Type, `StreamDefinitions["exampleExampleMessage"].Type`; !reflect.DeepEqual(got, want) {
- t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, got, want)
- }
- if want, got, name := "Stream result of exampleExampleMessage", streamExampleExampleMessage.Title, `StreamDefinitions["exampleExampleMessage"].Title`; !reflect.DeepEqual(got, want) {
- t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, got, want)
- }
- streamExampleExampleMessageProperties := *(streamExampleExampleMessage.Properties)
- if want, got, name := 2, len(streamExampleExampleMessageProperties), `len(StreamDefinitions["exampleExampleMessage"].Properties)`; !reflect.DeepEqual(got, want) {
- t.Errorf("applyTemplate(%#v).%s = %d want to be %d", file, name, got, want)
- } else {
- resultProperty := streamExampleExampleMessageProperties[0]
- if want, got, name := "result", resultProperty.Key, `(*(StreamDefinitions["exampleExampleMessage"].Properties))[0].Key`; !reflect.DeepEqual(got, want) {
- t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, got, want)
- }
- result := resultProperty.Value.(swaggerSchemaObject)
- if want, got, name := "#/definitions/exampleExampleMessage", result.Ref, `((*(StreamDefinitions["exampleExampleMessage"].Properties))[0].Value.(swaggerSchemaObject)).Ref`; !reflect.DeepEqual(got, want) {
- t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, got, want)
- }
- errorProperty := streamExampleExampleMessageProperties[1]
- if want, got, name := "error", errorProperty.Key, `(*(StreamDefinitions["exampleExampleMessage"].Properties))[0].Key`; !reflect.DeepEqual(got, want) {
- t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, got, want)
- }
- err := errorProperty.Value.(swaggerSchemaObject)
- if want, got, name := "#/definitions/runtimeStreamError", err.Ref, `((*(StreamDefinitions["exampleExampleMessage"].Properties))[0].Value.(swaggerSchemaObject)).Ref`; !reflect.DeepEqual(got, want) {
- t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, got, want)
- }
- }
- }
- if want, got, name := 1, len(result.Paths["/v1/echo"].Post.Responses), "len(Paths[/v1/echo].Post.Responses)"; !reflect.DeepEqual(got, want) {
- t.Errorf("applyTemplate(%#v).%s = %d want to be %d", file, name, got, want)
- } else {
- if want, got, name := "A successful response.(streaming responses)", result.Paths["/v1/echo"].Post.Responses["200"].Description, `result.Paths["/v1/echo"].Post.Responses["200"].Description`; !reflect.DeepEqual(got, want) {
- t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, got, want)
- }
- if want, got, name := "#/x-stream-definitions/exampleExampleMessage", result.Paths["/v1/echo"].Post.Responses["200"].Schema.Ref, `result.Paths["/v1/echo"].Post.Responses["200"].Description`; !reflect.DeepEqual(got, want) {
- t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, got, want)
- }
- }
-
- // If there was a failure, print out the input and the json result for debugging.
- if t.Failed() {
- t.Errorf("had: %s", file)
- t.Errorf("got: %s", fmt.Sprint(result))
- }
-}
-
-func TestApplyTemplateRequestWithUnusedReferences(t *testing.T) {
- reqdesc := &protodescriptor.DescriptorProto{
- Name: proto.String("ExampleMessage"),
- Field: []*protodescriptor.FieldDescriptorProto{
- {
- Name: proto.String("string"),
- Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
- Type: protodescriptor.FieldDescriptorProto_TYPE_STRING.Enum(),
- Number: proto.Int32(1),
- },
- },
- }
- respdesc := &protodescriptor.DescriptorProto{
- Name: proto.String("EmptyMessage"),
- }
- meth := &protodescriptor.MethodDescriptorProto{
- Name: proto.String("Example"),
- InputType: proto.String("ExampleMessage"),
- OutputType: proto.String("EmptyMessage"),
- ClientStreaming: proto.Bool(false),
- ServerStreaming: proto.Bool(false),
- }
- svc := &protodescriptor.ServiceDescriptorProto{
- Name: proto.String("ExampleService"),
- Method: []*protodescriptor.MethodDescriptorProto{meth},
- }
-
- req := &descriptor.Message{
- DescriptorProto: reqdesc,
- }
- resp := &descriptor.Message{
- DescriptorProto: respdesc,
- }
- stringField := &descriptor.Field{
- Message: req,
- FieldDescriptorProto: req.GetField()[0],
- }
- file := descriptor.File{
- FileDescriptorProto: &protodescriptor.FileDescriptorProto{
- SourceCodeInfo: &protodescriptor.SourceCodeInfo{},
- Name: proto.String("example.proto"),
- Package: proto.String("example"),
- MessageType: []*protodescriptor.DescriptorProto{reqdesc, respdesc},
- Service: []*protodescriptor.ServiceDescriptorProto{svc},
- },
- GoPkg: descriptor.GoPackage{
- Path: "example.com/path/to/example/example.pb",
- Name: "example_pb",
- },
- Messages: []*descriptor.Message{req, resp},
- Services: []*descriptor.Service{
- {
- ServiceDescriptorProto: svc,
- Methods: []*descriptor.Method{
- {
- MethodDescriptorProto: meth,
- RequestType: req,
- ResponseType: resp,
- Bindings: []*descriptor.Binding{
- {
- HTTPMethod: "GET",
- PathTmpl: httprule.Template{
- Version: 1,
- OpCodes: []int{0, 0},
- Template: "/v1/example",
- },
- },
- {
- HTTPMethod: "POST",
- PathTmpl: httprule.Template{
- Version: 1,
- OpCodes: []int{0, 0},
- Template: "/v1/example/{string}",
- },
- PathParams: []descriptor.Parameter{
- {
- FieldPath: descriptor.FieldPath([]descriptor.FieldPathComponent{
- {
- Name: "string",
- Target: stringField,
- },
- }),
- Target: stringField,
- },
- },
- Body: &descriptor.Body{
- FieldPath: descriptor.FieldPath([]descriptor.FieldPathComponent{
- {
- Name: "string",
- Target: stringField,
- },
- }),
- },
- },
- },
- },
- },
- },
- },
- }
-
- reg := descriptor.NewRegistry()
- reg.Load(&plugin.CodeGeneratorRequest{ProtoFile: []*protodescriptor.FileDescriptorProto{file.FileDescriptorProto}})
- result, err := applyTemplate(param{File: crossLinkFixture(&file), reg: reg})
- if err != nil {
- t.Errorf("applyTemplate(%#v) failed with %v; want success", file, err)
- return
- }
-
- // Only EmptyMessage must be present, not ExampleMessage
- if want, got, name := 1, len(result.Definitions), "len(Definitions)"; !reflect.DeepEqual(got, want) {
- t.Errorf("applyTemplate(%#v).%s = %d want to be %d", file, name, got, want)
- }
-
- // If there was a failure, print out the input and the json result for debugging.
- if t.Failed() {
- t.Errorf("had: %s", file)
- t.Errorf("got: %s", fmt.Sprint(result))
- }
-}
-
-func TestTemplateWithJsonCamelCase(t *testing.T) {
- var tests = []struct {
- input string
- expected string
- }{
- {"/test/{test_id}", "/test/{testId}"},
- {"/test1/{test1_id}/test2/{test2_id}", "/test1/{test1Id}/test2/{test2Id}"},
- {"/test1/{test1_id}/{test2_id}", "/test1/{test1Id}/{test2Id}"},
- {"/test1/test2/{test1_id}/{test2_id}", "/test1/test2/{test1Id}/{test2Id}"},
- {"/test1/{test1_id1_id2}", "/test1/{test1Id1Id2}"},
- {"/test1/{test1_id1_id2}/test2/{test2_id3_id4}", "/test1/{test1Id1Id2}/test2/{test2Id3Id4}"},
- {"/test1/test2/{test1_id1_id2}/{test2_id3_id4}", "/test1/test2/{test1Id1Id2}/{test2Id3Id4}"},
- {"test/{a}", "test/{a}"},
- {"test/{ab}", "test/{ab}"},
- {"test/{a_a}", "test/{aA}"},
- {"test/{ab_c}", "test/{abC}"},
- }
- reg := descriptor.NewRegistry()
- reg.SetUseJSONNamesForFields(true)
- for _, data := range tests {
- actual := templateToSwaggerPath(data.input, reg)
- if data.expected != actual {
- t.Errorf("Expected templateToSwaggerPath(%v) = %v, actual: %v", data.input, data.expected, actual)
- }
- }
-}
-
-func TestTemplateWithoutJsonCamelCase(t *testing.T) {
- var tests = []struct {
- input string
- expected string
- }{
- {"/test/{test_id}", "/test/{test_id}"},
- {"/test1/{test1_id}/test2/{test2_id}", "/test1/{test1_id}/test2/{test2_id}"},
- {"/test1/{test1_id}/{test2_id}", "/test1/{test1_id}/{test2_id}"},
- {"/test1/test2/{test1_id}/{test2_id}", "/test1/test2/{test1_id}/{test2_id}"},
- {"/test1/{test1_id1_id2}", "/test1/{test1_id1_id2}"},
- {"/test1/{test1_id1_id2}/test2/{test2_id3_id4}", "/test1/{test1_id1_id2}/test2/{test2_id3_id4}"},
- {"/test1/test2/{test1_id1_id2}/{test2_id3_id4}", "/test1/test2/{test1_id1_id2}/{test2_id3_id4}"},
- {"test/{a}", "test/{a}"},
- {"test/{ab}", "test/{ab}"},
- {"test/{a_a}", "test/{a_a}"},
- }
- reg := descriptor.NewRegistry()
- reg.SetUseJSONNamesForFields(false)
- for _, data := range tests {
- actual := templateToSwaggerPath(data.input, reg)
- if data.expected != actual {
- t.Errorf("Expected templateToSwaggerPath(%v) = %v, actual: %v", data.input, data.expected, actual)
- }
- }
-}
-
-func TestTemplateToSwaggerPath(t *testing.T) {
- var tests = []struct {
- input string
- expected string
- }{
- {"/test", "/test"},
- {"/{test}", "/{test}"},
- {"/{test=prefix/*}", "/{test}"},
- {"/{test=prefix/that/has/multiple/parts/to/it/*}", "/{test}"},
- {"/{test1}/{test2}", "/{test1}/{test2}"},
- {"/{test1}/{test2}/", "/{test1}/{test2}/"},
- {"/{name=prefix/*}", "/{name=prefix%2F%2A}"},
- {"/{name=prefix1/*/prefix2/*}", "/{name=prefix1%2F%2A%2Fprefix2%2F%2A}"},
- {"/{parent=prefix1/*}/{name=prefix2/*}", "/{parent=prefix1%2F%2A}/{name=prefix2%2F%2A}"},
- {"/{user.name=prefix/*}", "/{user.name=prefix%2F%2A}"},
- {"/{user.name=prefix1/*/prefix2/*}", "/{user.name=prefix1%2F%2A%2Fprefix2%2F%2A}"},
- {"/{parent=prefix/*}/children", "/{parent=prefix%2F%2A}/children"},
- {"/{name=prefix/*}:customMethod", "/{name=prefix%2F%2A}:customMethod"},
- {"/{name=prefix1/*/prefix2/*}:customMethod", "/{name=prefix1%2F%2A%2Fprefix2%2F%2A}:customMethod"},
- {"/{user.name=prefix/*}:customMethod", "/{user.name=prefix%2F%2A}:customMethod"},
- {"/{user.name=prefix1/*/prefix2/*}:customMethod", "/{user.name=prefix1%2F%2A%2Fprefix2%2F%2A}:customMethod"},
- {"/{parent=prefix/*}/children:customMethod", "/{parent=prefix%2F%2A}/children:customMethod"},
- }
- reg := descriptor.NewRegistry()
- reg.SetUseJSONNamesForFields(false)
- for _, data := range tests {
- actual := templateToSwaggerPath(data.input, reg)
- if data.expected != actual {
- t.Errorf("Expected templateToSwaggerPath(%v) = %v, actual: %v", data.input, data.expected, actual)
- }
- }
- reg.SetUseJSONNamesForFields(true)
- for _, data := range tests {
- actual := templateToSwaggerPath(data.input, reg)
- if data.expected != actual {
- t.Errorf("Expected templateToSwaggerPath(%v) = %v, actual: %v", data.input, data.expected, actual)
- }
- }
-}
-
-func BenchmarkTemplateToSwaggerPath(b *testing.B) {
- const input = "/{user.name=prefix1/*/prefix2/*}:customMethod"
-
- b.Run("with JSON names", func(b *testing.B) {
- reg := descriptor.NewRegistry()
- reg.SetUseJSONNamesForFields(false)
-
- for i := 0; i < b.N; i++ {
- _ = templateToSwaggerPath(input, reg)
- }
- })
-
- b.Run("without JSON names", func(b *testing.B) {
- reg := descriptor.NewRegistry()
- reg.SetUseJSONNamesForFields(true)
-
- for i := 0; i < b.N; i++ {
- _ = templateToSwaggerPath(input, reg)
- }
- })
-}
-
-func TestResolveFullyQualifiedNameToSwaggerName(t *testing.T) {
- var tests = []struct {
- input string
- output string
- listOfFQMNs []string
- useFQNForSwaggerName bool
- }{
- {
- ".a.b.C",
- "C",
- []string{
- ".a.b.C",
- },
- false,
- },
- {
- ".a.b.C",
- "abC",
- []string{
- ".a.C",
- ".a.b.C",
- },
- false,
- },
- {
- ".a.b.C",
- "abC",
- []string{
- ".C",
- ".a.C",
- ".a.b.C",
- },
- false,
- },
- {
- ".a.b.C",
- "a.b.C",
- []string{
- ".C",
- ".a.C",
- ".a.b.C",
- },
- true,
- },
- }
-
- for _, data := range tests {
- names := resolveFullyQualifiedNameToSwaggerNames(data.listOfFQMNs, data.useFQNForSwaggerName)
- output := names[data.input]
- if output != data.output {
- t.Errorf("Expected fullyQualifiedNameToSwaggerName(%v) to be %s but got %s",
- data.input, data.output, output)
- }
- }
-}
-
-func TestFQMNtoSwaggerName(t *testing.T) {
- var tests = []struct {
- input string
- expected string
- }{
- {"/test", "/test"},
- {"/{test}", "/{test}"},
- {"/{test=prefix/*}", "/{test}"},
- {"/{test=prefix/that/has/multiple/parts/to/it/*}", "/{test}"},
- {"/{test1}/{test2}", "/{test1}/{test2}"},
- {"/{test1}/{test2}/", "/{test1}/{test2}/"},
- }
- reg := descriptor.NewRegistry()
- reg.SetUseJSONNamesForFields(false)
- for _, data := range tests {
- actual := templateToSwaggerPath(data.input, reg)
- if data.expected != actual {
- t.Errorf("Expected templateToSwaggerPath(%v) = %v, actual: %v", data.input, data.expected, actual)
- }
- }
- reg.SetUseJSONNamesForFields(true)
- for _, data := range tests {
- actual := templateToSwaggerPath(data.input, reg)
- if data.expected != actual {
- t.Errorf("Expected templateToSwaggerPath(%v) = %v, actual: %v", data.input, data.expected, actual)
- }
- }
-}
-
-func TestSchemaOfField(t *testing.T) {
- type test struct {
- field *descriptor.Field
- refs refMap
- expected schemaCore
- }
-
- tests := []test{
- {
- field: &descriptor.Field{
- FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
- Name: proto.String("primitive_field"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_STRING.Enum(),
- },
- },
- refs: make(refMap),
- expected: schemaCore{
- Type: "string",
- },
- },
- {
- field: &descriptor.Field{
- FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
- Name: proto.String("repeated_primitive_field"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_STRING.Enum(),
- Label: protodescriptor.FieldDescriptorProto_LABEL_REPEATED.Enum(),
- },
- },
- refs: make(refMap),
- expected: schemaCore{
- Type: "array",
- Items: &swaggerItemsObject{
- Type: "string",
- },
- },
- },
- {
- field: &descriptor.Field{
- FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
- Name: proto.String("wrapped_field"),
- TypeName: proto.String(".google.protobuf.StringValue"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
- },
- },
- refs: make(refMap),
- expected: schemaCore{
- Type: "string",
- },
- },
- {
- field: &descriptor.Field{
- FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
- Name: proto.String("repeated_wrapped_field"),
- TypeName: proto.String(".google.protobuf.StringValue"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
- Label: protodescriptor.FieldDescriptorProto_LABEL_REPEATED.Enum(),
- },
- },
- refs: make(refMap),
- expected: schemaCore{
- Type: "array",
- Items: &swaggerItemsObject{
- Type: "string",
- },
- },
- },
- {
- field: &descriptor.Field{
- FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
- Name: proto.String("wrapped_field"),
- TypeName: proto.String(".google.protobuf.BytesValue"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
- },
- },
- refs: make(refMap),
- expected: schemaCore{
- Type: "string",
- Format: "byte",
- },
- },
- {
- field: &descriptor.Field{
- FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
- Name: proto.String("wrapped_field"),
- TypeName: proto.String(".google.protobuf.Int32Value"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
- },
- },
- refs: make(refMap),
- expected: schemaCore{
- Type: "integer",
- Format: "int32",
- },
- },
- {
- field: &descriptor.Field{
- FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
- Name: proto.String("wrapped_field"),
- TypeName: proto.String(".google.protobuf.UInt32Value"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
- },
- },
- refs: make(refMap),
- expected: schemaCore{
- Type: "integer",
- Format: "int64",
- },
- },
- {
- field: &descriptor.Field{
- FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
- Name: proto.String("wrapped_field"),
- TypeName: proto.String(".google.protobuf.Int64Value"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
- },
- },
- refs: make(refMap),
- expected: schemaCore{
- Type: "string",
- Format: "int64",
- },
- },
- {
- field: &descriptor.Field{
- FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
- Name: proto.String("wrapped_field"),
- TypeName: proto.String(".google.protobuf.UInt64Value"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
- },
- },
- refs: make(refMap),
- expected: schemaCore{
- Type: "string",
- Format: "uint64",
- },
- },
- {
- field: &descriptor.Field{
- FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
- Name: proto.String("wrapped_field"),
- TypeName: proto.String(".google.protobuf.FloatValue"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
- },
- },
- refs: make(refMap),
- expected: schemaCore{
- Type: "number",
- Format: "float",
- },
- },
- {
- field: &descriptor.Field{
- FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
- Name: proto.String("wrapped_field"),
- TypeName: proto.String(".google.protobuf.DoubleValue"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
- },
- },
- refs: make(refMap),
- expected: schemaCore{
- Type: "number",
- Format: "double",
- },
- },
- {
- field: &descriptor.Field{
- FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
- Name: proto.String("wrapped_field"),
- TypeName: proto.String(".google.protobuf.BoolValue"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
- },
- },
- refs: make(refMap),
- expected: schemaCore{
- Type: "boolean",
- Format: "boolean",
- },
- },
- {
- field: &descriptor.Field{
- FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
- Name: proto.String("wrapped_field"),
- TypeName: proto.String(".google.protobuf.Struct"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
- },
- },
- refs: make(refMap),
- expected: schemaCore{
- Type: "object",
- },
- },
- {
- field: &descriptor.Field{
- FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
- Name: proto.String("wrapped_field"),
- TypeName: proto.String(".google.protobuf.Value"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
- },
- },
- refs: make(refMap),
- expected: schemaCore{
- Type: "object",
- },
- },
- {
- field: &descriptor.Field{
- FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
- Name: proto.String("wrapped_field"),
- TypeName: proto.String(".google.protobuf.ListValue"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
- },
- },
- refs: make(refMap),
- expected: schemaCore{
- Type: "array",
- Items: (*swaggerItemsObject)(&schemaCore{
- Type: "object",
- }),
- },
- },
- {
- field: &descriptor.Field{
- FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
- Name: proto.String("wrapped_field"),
- TypeName: proto.String(".google.protobuf.NullValue"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
- },
- },
- refs: make(refMap),
- expected: schemaCore{
- Type: "string",
- },
- },
- {
- field: &descriptor.Field{
- FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
- Name: proto.String("message_field"),
- TypeName: proto.String(".example.Message"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
- },
- },
- refs: refMap{".example.Message": struct{}{}},
- expected: schemaCore{
- Ref: "#/definitions/exampleMessage",
- },
- },
- }
-
- reg := descriptor.NewRegistry()
- reg.Load(&plugin.CodeGeneratorRequest{
- ProtoFile: []*protodescriptor.FileDescriptorProto{
- {
- SourceCodeInfo: &protodescriptor.SourceCodeInfo{},
- Name: proto.String("example.proto"),
- Package: proto.String("example"),
- Dependency: []string{},
- MessageType: []*protodescriptor.DescriptorProto{
- {
- Name: proto.String("Message"),
- Field: []*protodescriptor.FieldDescriptorProto{
- {
- Name: proto.String("value"),
- Type: protodescriptor.FieldDescriptorProto_TYPE_STRING.Enum(),
- },
- },
- },
- },
- EnumType: []*protodescriptor.EnumDescriptorProto{
- {
- Name: proto.String("Message"),
- },
- },
- Service: []*protodescriptor.ServiceDescriptorProto{},
- },
- },
- })
-
- for _, test := range tests {
- refs := make(refMap)
- actual := schemaOfField(test.field, reg, refs)
- expectedSchemaObject := swaggerSchemaObject{schemaCore: test.expected}
- if e, a := expectedSchemaObject, actual; !reflect.DeepEqual(a, e) {
- t.Errorf("Expected schemaOfField(%v) = %v, actual: %v", test.field, e, a)
- }
- if !reflect.DeepEqual(refs, test.refs) {
- t.Errorf("Expected schemaOfField(%v) to add refs %v, not %v", test.field, test.refs, refs)
- }
- }
-}
-
-func TestRenderMessagesAsDefinition(t *testing.T) {
-
- tests := []struct {
- descr string
- msgDescs []*protodescriptor.DescriptorProto
- schema map[string]swagger_options.Schema // per-message schema to add
- defs swaggerDefinitionsObject
- }{
- {
- descr: "no swagger options",
- msgDescs: []*protodescriptor.DescriptorProto{
- &protodescriptor.DescriptorProto{Name: proto.String("Message")},
- },
- schema: map[string]swagger_options.Schema{},
- defs: map[string]swaggerSchemaObject{
- "Message": swaggerSchemaObject{schemaCore: schemaCore{Type: "object"}},
- },
- },
- {
- descr: "example option",
- msgDescs: []*protodescriptor.DescriptorProto{
- &protodescriptor.DescriptorProto{Name: proto.String("Message")},
- },
- schema: map[string]swagger_options.Schema{
- "Message": swagger_options.Schema{
- Example: &any.Any{
- TypeUrl: "this_isnt_used",
- Value: []byte(`{"foo":"bar"}`),
- },
- },
- },
- defs: map[string]swaggerSchemaObject{
- "Message": swaggerSchemaObject{schemaCore: schemaCore{
- Type: "object",
- Example: json.RawMessage(`{"foo":"bar"}`),
- }},
- },
- },
- {
- descr: "example option with something non-json",
- msgDescs: []*protodescriptor.DescriptorProto{
- &protodescriptor.DescriptorProto{Name: proto.String("Message")},
- },
- schema: map[string]swagger_options.Schema{
- "Message": swagger_options.Schema{
- Example: &any.Any{
- Value: []byte(`XXXX anything goes XXXX`),
- },
- },
- },
- defs: map[string]swaggerSchemaObject{
- "Message": swaggerSchemaObject{schemaCore: schemaCore{
- Type: "object",
- Example: json.RawMessage(`XXXX anything goes XXXX`),
- }},
- },
- },
- {
- descr: "external docs option",
- msgDescs: []*protodescriptor.DescriptorProto{
- &protodescriptor.DescriptorProto{Name: proto.String("Message")},
- },
- schema: map[string]swagger_options.Schema{
- "Message": swagger_options.Schema{
- ExternalDocs: &swagger_options.ExternalDocumentation{
- Description: "glorious docs",
- Url: "https://nada",
- },
- },
- },
- defs: map[string]swaggerSchemaObject{
- "Message": swaggerSchemaObject{
- schemaCore: schemaCore{
- Type: "object",
- },
- ExternalDocs: &swaggerExternalDocumentationObject{
- Description: "glorious docs",
- URL: "https://nada",
- },
- },
- },
- },
- {
- descr: "JSONSchema options",
- msgDescs: []*protodescriptor.DescriptorProto{
- &protodescriptor.DescriptorProto{Name: proto.String("Message")},
- },
- schema: map[string]swagger_options.Schema{
- "Message": swagger_options.Schema{
- JsonSchema: &swagger_options.JSONSchema{
- Title: "title",
- Description: "desc",
- MultipleOf: 100,
- Maximum: 101,
- ExclusiveMaximum: true,
- Minimum: 1,
- ExclusiveMinimum: true,
- MaxLength: 10,
- MinLength: 3,
- Pattern: "[a-z]+",
- MaxItems: 20,
- MinItems: 2,
- UniqueItems: true,
- MaxProperties: 33,
- MinProperties: 22,
- Required: []string{"req"},
- ReadOnly: true,
- },
- },
- },
- defs: map[string]swaggerSchemaObject{
- "Message": swaggerSchemaObject{
- schemaCore: schemaCore{
- Type: "object",
- },
- Title: "title",
- Description: "desc",
- MultipleOf: 100,
- Maximum: 101,
- ExclusiveMaximum: true,
- Minimum: 1,
- ExclusiveMinimum: true,
- MaxLength: 10,
- MinLength: 3,
- Pattern: "[a-z]+",
- MaxItems: 20,
- MinItems: 2,
- UniqueItems: true,
- MaxProperties: 33,
- MinProperties: 22,
- Required: []string{"req"},
- ReadOnly: true,
- },
- },
- },
- }
-
- for _, test := range tests {
- t.Run(test.descr, func(t *testing.T) {
-
- msgs := []*descriptor.Message{}
- for _, msgdesc := range test.msgDescs {
- msgdesc.Options = &protodescriptor.MessageOptions{}
- msgs = append(msgs, &descriptor.Message{DescriptorProto: msgdesc})
- }
-
- reg := descriptor.NewRegistry()
- file := descriptor.File{
- FileDescriptorProto: &protodescriptor.FileDescriptorProto{
- SourceCodeInfo: &protodescriptor.SourceCodeInfo{},
- Name: proto.String("example.proto"),
- Package: proto.String("example"),
- Dependency: []string{},
- MessageType: test.msgDescs,
- EnumType: []*protodescriptor.EnumDescriptorProto{},
- Service: []*protodescriptor.ServiceDescriptorProto{},
- },
- Messages: msgs,
- }
- reg.Load(&plugin.CodeGeneratorRequest{
- ProtoFile: []*protodescriptor.FileDescriptorProto{file.FileDescriptorProto},
- })
-
- msgMap := map[string]*descriptor.Message{}
- for _, d := range test.msgDescs {
- name := d.GetName()
- msg, err := reg.LookupMsg("example", name)
- if err != nil {
- t.Fatalf("lookup message %v: %v", name, err)
- }
- msgMap[msg.FQMN()] = msg
-
- if schema, ok := test.schema[name]; ok {
- err := proto.SetExtension(d.Options, swagger_options.E_Openapiv2Schema, &schema)
- if err != nil {
- t.Fatalf("SetExtension(%s, ...) returned error: %v", msg, err)
- }
- }
- }
-
- refs := make(refMap)
- actual := make(swaggerDefinitionsObject)
- renderMessagesAsDefinition(msgMap, actual, reg, refs)
-
- if !reflect.DeepEqual(actual, test.defs) {
- t.Errorf("Expected renderMessagesAsDefinition() to add defs %+v, not %+v", test.defs, actual)
- }
- })
- }
-}
-
-func TestUpdateSwaggerDataFromComments(t *testing.T) {
-
- tests := []struct {
- descr string
- swaggerObject interface{}
- comments string
- expectedError error
- expectedSwaggerObject interface{}
- useGoTemplate bool
- }{
- {
- descr: "empty comments",
- swaggerObject: nil,
- expectedSwaggerObject: nil,
- comments: "",
- expectedError: nil,
- },
- {
- descr: "set field to read only",
- swaggerObject: &swaggerSchemaObject{},
- expectedSwaggerObject: &swaggerSchemaObject{
- ReadOnly: true,
- Description: "... Output only. ...",
- },
- comments: "... Output only. ...",
- expectedError: nil,
- },
- {
- descr: "set title",
- swaggerObject: &swaggerSchemaObject{},
- expectedSwaggerObject: &swaggerSchemaObject{
- Title: "Comment with no trailing dot",
- },
- comments: "Comment with no trailing dot",
- expectedError: nil,
- },
- {
- descr: "set description",
- swaggerObject: &swaggerSchemaObject{},
- expectedSwaggerObject: &swaggerSchemaObject{
- Description: "Comment with trailing dot.",
- },
- comments: "Comment with trailing dot.",
- expectedError: nil,
- },
- {
- descr: "use info object",
- swaggerObject: &swaggerObject{
- Info: swaggerInfoObject{},
- },
- expectedSwaggerObject: &swaggerObject{
- Info: swaggerInfoObject{
- Description: "Comment with trailing dot.",
- },
- },
- comments: "Comment with trailing dot.",
- expectedError: nil,
- },
- {
- descr: "multi line comment with title",
- swaggerObject: &swaggerSchemaObject{},
- expectedSwaggerObject: &swaggerSchemaObject{
- Title: "First line",
- Description: "Second line",
- },
- comments: "First line\n\nSecond line",
- expectedError: nil,
- },
- {
- descr: "multi line comment no title",
- swaggerObject: &swaggerSchemaObject{},
- expectedSwaggerObject: &swaggerSchemaObject{
- Description: "First line.\n\nSecond line",
- },
- comments: "First line.\n\nSecond line",
- expectedError: nil,
- },
- {
- descr: "multi line comment with summary with dot",
- swaggerObject: &swaggerOperationObject{},
- expectedSwaggerObject: &swaggerOperationObject{
- Summary: "First line.",
- Description: "Second line",
- },
- comments: "First line.\n\nSecond line",
- expectedError: nil,
- },
- {
- descr: "multi line comment with summary no dot",
- swaggerObject: &swaggerOperationObject{},
- expectedSwaggerObject: &swaggerOperationObject{
- Summary: "First line",
- Description: "Second line",
- },
- comments: "First line\n\nSecond line",
- expectedError: nil,
- },
- {
- descr: "multi line comment with summary no dot",
- swaggerObject: &schemaCore{},
- expectedSwaggerObject: &schemaCore{},
- comments: "Any comment",
- expectedError: errors.New("no description nor summary property"),
- },
- {
- descr: "without use_go_template",
- swaggerObject: &swaggerSchemaObject{},
- expectedSwaggerObject: &swaggerSchemaObject{
- Title: "First line",
- Description: "{{import \"documentation.md\"}}",
- },
- comments: "First line\n\n{{import \"documentation.md\"}}",
- expectedError: nil,
- },
- {
- descr: "error with use_go_template",
- swaggerObject: &swaggerSchemaObject{},
- expectedSwaggerObject: &swaggerSchemaObject{
- Title: "First line",
- Description: "open noneexistingfile.txt: no such file or directory",
- },
- comments: "First line\n\n{{import \"noneexistingfile.txt\"}}",
- expectedError: nil,
- useGoTemplate: true,
- },
- {
- descr: "template with use_go_template",
- swaggerObject: &swaggerSchemaObject{},
- expectedSwaggerObject: &swaggerSchemaObject{
- Title: "Template",
- Description: `Description "which means nothing"`,
- },
- comments: "Template\n\nDescription {{with \"which means nothing\"}}{{printf \"%q\" .}}{{end}}",
- expectedError: nil,
- useGoTemplate: true,
- },
- }
-
- for _, test := range tests {
- t.Run(test.descr, func(t *testing.T) {
- reg := descriptor.NewRegistry()
- if test.useGoTemplate {
- reg.SetUseGoTemplate(true)
- }
- err := updateSwaggerDataFromComments(reg, test.swaggerObject, nil, test.comments, false)
- if test.expectedError == nil {
- if err != nil {
- t.Errorf("unexpected error '%v'", err)
- }
- if !reflect.DeepEqual(test.swaggerObject, test.expectedSwaggerObject) {
- t.Errorf("swaggerObject was not updated corretly, expected '%+v', got '%+v'", test.expectedSwaggerObject, test.swaggerObject)
- }
- } else {
- if err == nil {
- t.Error("expected update error not returned")
- }
- if !reflect.DeepEqual(test.swaggerObject, test.expectedSwaggerObject) {
- t.Errorf("swaggerObject was not updated corretly, expected '%+v', got '%+v'", test.expectedSwaggerObject, test.swaggerObject)
- }
- if err.Error() != test.expectedError.Error() {
- t.Errorf("expected error malformed, expected %q, got %q", test.expectedError.Error(), err.Error())
- }
- }
- })
- }
-}
-
-func TestMessageOptionsWithGoTemplate(t *testing.T) {
- tests := []struct {
- descr string
- msgDescs []*protodescriptor.DescriptorProto
- schema map[string]swagger_options.Schema // per-message schema to add
- defs swaggerDefinitionsObject
- useGoTemplate bool
- }{
- {
- descr: "external docs option",
- msgDescs: []*protodescriptor.DescriptorProto{
- &protodescriptor.DescriptorProto{Name: proto.String("Message")},
- },
- schema: map[string]swagger_options.Schema{
- "Message": swagger_options.Schema{
- JsonSchema: &swagger_options.JSONSchema{
- Title: "{{.Name}}",
- Description: "Description {{with \"which means nothing\"}}{{printf \"%q\" .}}{{end}}",
- },
- ExternalDocs: &swagger_options.ExternalDocumentation{
- Description: "Description {{with \"which means nothing\"}}{{printf \"%q\" .}}{{end}}",
- },
- },
- },
- defs: map[string]swaggerSchemaObject{
- "Message": swaggerSchemaObject{
- schemaCore: schemaCore{
- Type: "object",
- },
- Title: "Message",
- Description: `Description "which means nothing"`,
- ExternalDocs: &swaggerExternalDocumentationObject{
- Description: `Description "which means nothing"`,
- },
- },
- },
- useGoTemplate: true,
- },
- {
- descr: "external docs option",
- msgDescs: []*protodescriptor.DescriptorProto{
- &protodescriptor.DescriptorProto{Name: proto.String("Message")},
- },
- schema: map[string]swagger_options.Schema{
- "Message": swagger_options.Schema{
- JsonSchema: &swagger_options.JSONSchema{
- Title: "{{.Name}}",
- Description: "Description {{with \"which means nothing\"}}{{printf \"%q\" .}}{{end}}",
- },
- ExternalDocs: &swagger_options.ExternalDocumentation{
- Description: "Description {{with \"which means nothing\"}}{{printf \"%q\" .}}{{end}}",
- },
- },
- },
- defs: map[string]swaggerSchemaObject{
- "Message": swaggerSchemaObject{
- schemaCore: schemaCore{
- Type: "object",
- },
- Title: "{{.Name}}",
- Description: "Description {{with \"which means nothing\"}}{{printf \"%q\" .}}{{end}}",
- ExternalDocs: &swaggerExternalDocumentationObject{
- Description: "Description {{with \"which means nothing\"}}{{printf \"%q\" .}}{{end}}",
- },
- },
- },
- useGoTemplate: false,
- },
- }
-
- for _, test := range tests {
- t.Run(test.descr, func(t *testing.T) {
-
- msgs := []*descriptor.Message{}
- for _, msgdesc := range test.msgDescs {
- msgdesc.Options = &protodescriptor.MessageOptions{}
- msgs = append(msgs, &descriptor.Message{DescriptorProto: msgdesc})
- }
-
- reg := descriptor.NewRegistry()
- reg.SetUseGoTemplate(test.useGoTemplate)
- file := descriptor.File{
- FileDescriptorProto: &protodescriptor.FileDescriptorProto{
- SourceCodeInfo: &protodescriptor.SourceCodeInfo{},
- Name: proto.String("example.proto"),
- Package: proto.String("example"),
- Dependency: []string{},
- MessageType: test.msgDescs,
- EnumType: []*protodescriptor.EnumDescriptorProto{},
- Service: []*protodescriptor.ServiceDescriptorProto{},
- },
- Messages: msgs,
- }
- reg.Load(&plugin.CodeGeneratorRequest{
- ProtoFile: []*protodescriptor.FileDescriptorProto{file.FileDescriptorProto},
- })
-
- msgMap := map[string]*descriptor.Message{}
- for _, d := range test.msgDescs {
- name := d.GetName()
- msg, err := reg.LookupMsg("example", name)
- if err != nil {
- t.Fatalf("lookup message %v: %v", name, err)
- }
- msgMap[msg.FQMN()] = msg
-
- if schema, ok := test.schema[name]; ok {
- err := proto.SetExtension(d.Options, swagger_options.E_Openapiv2Schema, &schema)
- if err != nil {
- t.Fatalf("SetExtension(%s, ...) returned error: %v", msg, err)
- }
- }
- }
-
- refs := make(refMap)
- actual := make(swaggerDefinitionsObject)
- renderMessagesAsDefinition(msgMap, actual, reg, refs)
-
- if !reflect.DeepEqual(actual, test.defs) {
- t.Errorf("Expected renderMessagesAsDefinition() to add defs %+v, not %+v", test.defs, actual)
- }
- })
- }
-}
diff --git a/gateway/protoc-gen-swagger/genswagger/types.go b/gateway/protoc-gen-swagger/genswagger/types.go
deleted file mode 100644
index 0406fce..0000000
--- a/gateway/protoc-gen-swagger/genswagger/types.go
+++ /dev/null
@@ -1,257 +0,0 @@
-package genswagger
-
-import (
- "bytes"
- "encoding/json"
-
- // "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
- "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/descriptor"
- options "github.com/binchencoder/ease-gateway/httpoptions"
-)
-
-type param struct {
- *descriptor.File
- reg *descriptor.Registry
-}
-
-type binding struct {
- *descriptor.Binding
-}
-
-// http://swagger.io/specification/#infoObject
-type swaggerInfoObject struct {
- Title string `json:"title"`
- Description string `json:"description,omitempty"`
- TermsOfService string `json:"termsOfService,omitempty"`
- Version string `json:"version"`
-
- Contact *swaggerContactObject `json:"contact,omitempty"`
- License *swaggerLicenseObject `json:"license,omitempty"`
-
- extensions []extension
-}
-
-// http://swagger.io/specification/#contactObject
-type swaggerContactObject struct {
- Name string `json:"name,omitempty"`
- URL string `json:"url,omitempty"`
- Email string `json:"email,omitempty"`
-}
-
-// http://swagger.io/specification/#licenseObject
-type swaggerLicenseObject struct {
- Name string `json:"name,omitempty"`
- URL string `json:"url,omitempty"`
-}
-
-// http://swagger.io/specification/#externalDocumentationObject
-type swaggerExternalDocumentationObject struct {
- Description string `json:"description,omitempty"`
- URL string `json:"url,omitempty"`
-}
-
-type extension struct {
- key string
- value json.RawMessage
-}
-
-// http://swagger.io/specification/#swaggerObject
-type swaggerObject struct {
- Swagger string `json:"swagger"`
- Info swaggerInfoObject `json:"info"`
- Host string `json:"host,omitempty"`
- BasePath string `json:"basePath,omitempty"`
- Schemes []string `json:"schemes"`
- Consumes []string `json:"consumes"`
- Produces []string `json:"produces"`
- Paths swaggerPathsObject `json:"paths"`
- Definitions swaggerDefinitionsObject `json:"definitions"`
- StreamDefinitions swaggerDefinitionsObject `json:"x-stream-definitions,omitempty"`
- SecurityDefinitions swaggerSecurityDefinitionsObject `json:"securityDefinitions,omitempty"`
- Security []swaggerSecurityRequirementObject `json:"security,omitempty"`
- ExternalDocs *swaggerExternalDocumentationObject `json:"externalDocs,omitempty"`
-
- extensions []extension
-}
-
-// http://swagger.io/specification/#securityDefinitionsObject
-type swaggerSecurityDefinitionsObject map[string]swaggerSecuritySchemeObject
-
-// http://swagger.io/specification/#securitySchemeObject
-type swaggerSecuritySchemeObject struct {
- Type string `json:"type"`
- Description string `json:"description,omitempty"`
- Name string `json:"name,omitempty"`
- In string `json:"in,omitempty"`
- Flow string `json:"flow,omitempty"`
- AuthorizationURL string `json:"authorizationUrl,omitempty"`
- TokenURL string `json:"tokenUrl,omitempty"`
- Scopes swaggerScopesObject `json:"scopes,omitempty"`
-
- extensions []extension
-}
-
-// http://swagger.io/specification/#scopesObject
-type swaggerScopesObject map[string]string
-
-// http://swagger.io/specification/#securityRequirementObject
-type swaggerSecurityRequirementObject map[string][]string
-
-// http://swagger.io/specification/#pathsObject
-type swaggerPathsObject map[string]swaggerPathItemObject
-
-// http://swagger.io/specification/#pathItemObject
-type swaggerPathItemObject struct {
- Get *swaggerOperationObject `json:"get,omitempty"`
- Delete *swaggerOperationObject `json:"delete,omitempty"`
- Post *swaggerOperationObject `json:"post,omitempty"`
- Put *swaggerOperationObject `json:"put,omitempty"`
- Patch *swaggerOperationObject `json:"patch,omitempty"`
-}
-
-// http://swagger.io/specification/#operationObject
-type swaggerOperationObject struct {
- Summary string `json:"summary,omitempty"`
- Description string `json:"description,omitempty"`
- OperationID string `json:"operationId"`
- Responses swaggerResponsesObject `json:"responses"`
- Parameters swaggerParametersObject `json:"parameters,omitempty"`
- Tags []string `json:"tags,omitempty"`
- Deprecated bool `json:"deprecated,omitempty"`
-
- Security *[]swaggerSecurityRequirementObject `json:"security,omitempty"`
- ExternalDocs *swaggerExternalDocumentationObject `json:"externalDocs,omitempty"`
-
- extensions []extension
-}
-
-type swaggerParametersObject []swaggerParameterObject
-
-// http://swagger.io/specification/#parameterObject
-type swaggerParameterObject struct {
- Name string `json:"name"`
- Description string `json:"description,omitempty"`
- In string `json:"in,omitempty"`
- Required bool `json:"required"`
- Type string `json:"type,omitempty"`
- Format string `json:"format,omitempty"`
- Items *swaggerItemsObject `json:"items,omitempty"`
- Enum []string `json:"enum,omitempty"`
- CollectionFormat string `json:"collectionFormat,omitempty"`
- Default string `json:"default,omitempty"`
- MinItems *int `json:"minItems,omitempty"`
-
- // Or you can explicitly refer to another type. If this is defined all
- // other fields should be empty
- Schema *swaggerSchemaObject `json:"schema,omitempty"`
-}
-
-// core part of schema, which is common to itemsObject and schemaObject.
-// http://swagger.io/specification/#itemsObject
-type schemaCore struct {
- Type string `json:"type,omitempty"`
- Format string `json:"format,omitempty"`
- Ref string `json:"$ref,omitempty"`
- Example json.RawMessage `json:"example,omitempty"`
-
- Items *swaggerItemsObject `json:"items,omitempty"`
-
- // If the item is an enumeration include a list of all the *NAMES* of the
- // enum values. I'm not sure how well this will work but assuming all enums
- // start from 0 index it will be great. I don't think that is a good assumption.
- Enum []string `json:"enum,omitempty"`
- Default string `json:"default,omitempty"`
- Rules []options.ValidationRule `json:"rules,omitempty"`
-}
-
-type swaggerItemsObject schemaCore
-
-// http://swagger.io/specification/#responsesObject
-type swaggerResponsesObject map[string]swaggerResponseObject
-
-// http://swagger.io/specification/#responseObject
-type swaggerResponseObject struct {
- Description string `json:"description"`
- Schema swaggerSchemaObject `json:"schema"`
-
- extensions []extension
-}
-
-type keyVal struct {
- Key string
- Value interface{}
-}
-
-type swaggerSchemaObjectProperties []keyVal
-
-func (op swaggerSchemaObjectProperties) MarshalJSON() ([]byte, error) {
- var buf bytes.Buffer
- buf.WriteString("{")
- for i, kv := range op {
- if i != 0 {
- buf.WriteString(",")
- }
- key, err := json.Marshal(kv.Key)
- if err != nil {
- return nil, err
- }
- buf.Write(key)
- buf.WriteString(":")
- val, err := json.Marshal(kv.Value)
- if err != nil {
- return nil, err
- }
- buf.Write(val)
- }
-
- buf.WriteString("}")
- return buf.Bytes(), nil
-}
-
-// http://swagger.io/specification/#schemaObject
-type swaggerSchemaObject struct {
- schemaCore
- // Properties can be recursively defined
- Properties *swaggerSchemaObjectProperties `json:"properties,omitempty"`
- AdditionalProperties *swaggerSchemaObject `json:"additionalProperties,omitempty"`
-
- Description string `json:"description,omitempty"`
- Title string `json:"title,omitempty"`
-
- ExternalDocs *swaggerExternalDocumentationObject `json:"externalDocs,omitempty"`
-
- ReadOnly bool `json:"readOnly,omitempty"`
- MultipleOf float64 `json:"multipleOf,omitempty"`
- Maximum float64 `json:"maximum,omitempty"`
- ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"`
- Minimum float64 `json:"minimum,omitempty"`
- ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty"`
- MaxLength uint64 `json:"maxLength,omitempty"`
- MinLength uint64 `json:"minLength,omitempty"`
- Pattern string `json:"pattern,omitempty"`
- MaxItems uint64 `json:"maxItems,omitempty"`
- MinItems uint64 `json:"minItems,omitempty"`
- UniqueItems bool `json:"uniqueItems,omitempty"`
- MaxProperties uint64 `json:"maxProperties,omitempty"`
- MinProperties uint64 `json:"minProperties,omitempty"`
- Required []string `json:"required,omitempty"`
-}
-
-// http://swagger.io/specification/#referenceObject
-type swaggerReferenceObject struct {
- Ref string `json:"$ref"`
-}
-
-// http://swagger.io/specification/#definitionsObject
-type swaggerDefinitionsObject map[string]swaggerSchemaObject
-
-// Internal type mapping from FQMN to descriptor.Message. Used as a set by the
-// findServiceMessages function.
-type messageMap map[string]*descriptor.Message
-
-// Internal type mapping from FQEN to descriptor.Enum. Used as a set by the
-// findServiceMessages function.
-type enumMap map[string]*descriptor.Enum
-
-// Internal type to store used references.
-type refMap map[string]struct{}
diff --git a/gateway/protoc-gen-swagger/main.go b/gateway/protoc-gen-swagger/main.go
deleted file mode 100644
index 22ecf14..0000000
--- a/gateway/protoc-gen-swagger/main.go
+++ /dev/null
@@ -1,206 +0,0 @@
-package main
-
-import (
- "flag"
- "fmt"
- "os"
- "strings"
-
- "github.com/golang/glog"
- "github.com/golang/protobuf/proto"
- plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
-
- // "github.com/grpc-ecosystem/grpc-gateway/codegenerator"
- "github.com/binchencoder/ease-gateway/gateway/codegenerator"
-
- // "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
- "github.com/binchencoder/ease-gateway/gateway/protoc-gen-grpc-gateway/descriptor"
-
- // "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/genswagger"
- "github.com/binchencoder/ease-gateway/gateway/protoc-gen-swagger/genswagger"
-)
-
-var (
- importPrefix = flag.String("import_prefix", "", "prefix to be added to go package paths for imported proto files")
- file = flag.String("file", "-", "where to load data from")
- allowDeleteBody = flag.Bool("allow_delete_body", false, "unless set, HTTP DELETE methods may not have a body")
- grpcAPIConfiguration = flag.String("grpc_api_configuration", "", "path to gRPC API Configuration in YAML format")
- allowMerge = flag.Bool("allow_merge", false, "if set, generation one swagger file out of multiple protos")
- mergeFileName = flag.String("merge_file_name", "apidocs", "target swagger file name prefix after merge")
- useJSONNamesForFields = flag.Bool("json_names_for_fields", false, "if it sets Field.GetJsonName() will be used for generating swagger definitions, otherwise Field.GetName() will be used")
- repeatedPathParamSeparator = flag.String("repeated_path_param_separator", "csv", "configures how repeated fields should be split. Allowed values are `csv`, `pipes`, `ssv` and `tsv`.")
- versionFlag = flag.Bool("version", false, "print the current verison")
- allowRepeatedFieldsInBody = flag.Bool("allow_repeated_fields_in_body", false, "allows to use repeated field in `body` and `response_body` field of `google.api.http` annotation option")
- includePackageInTags = flag.Bool("include_package_in_tags", false, "if unset, the gRPC service name is added to the `Tags` field of each operation. if set and the `package` directive is shown in the proto file, the package name will be prepended to the service name")
- useFQNForSwaggerName = flag.Bool("fqn_for_swagger_name", false, "if set, the object's swagger names will use the fully qualify name from the proto definition (ie my.package.MyMessage.MyInnerMessage")
- useGoTemplate = flag.Bool("use_go_templates", false, "if set, you can use Go templates in protofile comments")
-)
-
-// Variables set by goreleaser at build time
-var (
- version = "dev"
- commit = "unknown"
- date = "unknown"
-)
-
-func main() {
- flag.Parse()
- defer glog.Flush()
-
- if *versionFlag {
- fmt.Printf("Version %v, commit %v, built at %v\n", version, commit, date)
- os.Exit(0)
- }
-
- reg := descriptor.NewRegistry()
-
- glog.V(1).Info("Processing code generator request")
- f := os.Stdin
- if *file != "-" {
- var err error
- f, err = os.Open(*file)
- if err != nil {
- glog.Fatal(err)
- }
- }
- glog.V(1).Info("Parsing code generator request")
- req, err := codegenerator.ParseRequest(f)
- if err != nil {
- glog.Fatal(err)
- }
- glog.V(1).Info("Parsed code generator request")
- pkgMap := make(map[string]string)
- if req.Parameter != nil {
- err := parseReqParam(req.GetParameter(), flag.CommandLine, pkgMap)
- if err != nil {
- glog.Fatalf("Error parsing flags: %v", err)
- }
- }
-
- reg.SetPrefix(*importPrefix)
- reg.SetAllowDeleteBody(*allowDeleteBody)
- reg.SetAllowMerge(*allowMerge)
- reg.SetMergeFileName(*mergeFileName)
- reg.SetUseJSONNamesForFields(*useJSONNamesForFields)
- reg.SetAllowRepeatedFieldsInBody(*allowRepeatedFieldsInBody)
- reg.SetIncludePackageInTags(*includePackageInTags)
- reg.SetUseFQNForSwaggerName(*useFQNForSwaggerName)
- reg.SetUseGoTemplate(*useGoTemplate)
- if err := reg.SetRepeatedPathParamSeparator(*repeatedPathParamSeparator); err != nil {
- emitError(err)
- return
- }
- for k, v := range pkgMap {
- reg.AddPkgMap(k, v)
- }
-
- if *grpcAPIConfiguration != "" {
- if err := reg.LoadGrpcAPIServiceFromYAML(*grpcAPIConfiguration); err != nil {
- emitError(err)
- return
- }
- }
-
- g := genswagger.New(reg)
-
- if err := genswagger.AddStreamError(reg); err != nil {
- emitError(err)
- return
- }
-
- if err := reg.Load(req); err != nil {
- emitError(err)
- return
- }
-
- var targets []*descriptor.File
- for _, target := range req.FileToGenerate {
- f, err := reg.LookupFile(target)
- if err != nil {
- glog.Fatal(err)
- }
- targets = append(targets, f)
- }
-
- out, err := g.Generate(targets)
- glog.V(1).Info("Processed code generator request")
- if err != nil {
- emitError(err)
- return
- }
- emitFiles(out)
-}
-
-func emitFiles(out []*plugin.CodeGeneratorResponse_File) {
- emitResp(&plugin.CodeGeneratorResponse{File: out})
-}
-
-func emitError(err error) {
- emitResp(&plugin.CodeGeneratorResponse{Error: proto.String(err.Error())})
-}
-
-func emitResp(resp *plugin.CodeGeneratorResponse) {
- buf, err := proto.Marshal(resp)
- if err != nil {
- glog.Fatal(err)
- }
- if _, err := os.Stdout.Write(buf); err != nil {
- glog.Fatal(err)
- }
-}
-
-// parseReqParam parses a CodeGeneratorRequest parameter and adds the
-// extracted values to the given FlagSet and pkgMap. Returns a non-nil
-// error if setting a flag failed.
-func parseReqParam(param string, f *flag.FlagSet, pkgMap map[string]string) error {
- if param == "" {
- return nil
- }
- for _, p := range strings.Split(param, ",") {
- spec := strings.SplitN(p, "=", 2)
- if len(spec) == 1 {
- if spec[0] == "allow_delete_body" {
- err := f.Set(spec[0], "true")
- if err != nil {
- return fmt.Errorf("Cannot set flag %s: %v", p, err)
- }
- continue
- }
- if spec[0] == "allow_merge" {
- err := f.Set(spec[0], "true")
- if err != nil {
- return fmt.Errorf("Cannot set flag %s: %v", p, err)
- }
- continue
- }
- if spec[0] == "allow_repeated_fields_in_body" {
- err := f.Set(spec[0], "true")
- if err != nil {
- return fmt.Errorf("Cannot set flag %s: %v", p, err)
- }
- continue
- }
- if spec[0] == "include_package_in_tags" {
- err := f.Set(spec[0], "true")
- if err != nil {
- return fmt.Errorf("Cannot set flag %s: %v", p, err)
- }
- continue
- }
- err := f.Set(spec[0], "")
- if err != nil {
- return fmt.Errorf("Cannot set flag %s: %v", p, err)
- }
- continue
- }
- name, value := spec[0], spec[1]
- if strings.HasPrefix(name, "M") {
- pkgMap[name[1:]] = value
- continue
- }
- if err := f.Set(name, value); err != nil {
- return fmt.Errorf("Cannot set flag %s: %v", p, err)
- }
- }
- return nil
-}
diff --git a/gateway/protoc-gen-swagger/main_test.go b/gateway/protoc-gen-swagger/main_test.go
deleted file mode 100644
index 7dcbf0c..0000000
--- a/gateway/protoc-gen-swagger/main_test.go
+++ /dev/null
@@ -1,186 +0,0 @@
-package main
-
-import (
- "errors"
- "flag"
- "reflect"
- "testing"
-)
-
-func TestParseReqParam(t *testing.T) {
-
- testcases := []struct {
- name string
- expected map[string]string
- request string
- expectedError error
- allowDeleteBodyV bool
- allowMergeV bool
- allowRepeatedFieldsInBodyV bool
- includePackageInTagsV bool
- fileV string
- importPathV string
- mergeFileNameV string
- useFQNForSwaggerNameV bool
- }{
- {
- // this one must be first - with no leading clearFlags call it
- // verifies our expectation of default values as we reset by
- // clearFlags
- name: "Test 0",
- expected: map[string]string{},
- request: "",
- allowDeleteBodyV: false, allowMergeV: false, allowRepeatedFieldsInBodyV: false, includePackageInTagsV: false,
- fileV: "-", importPathV: "", mergeFileNameV: "apidocs",
- },
- {
- name: "Test 1",
- expected: map[string]string{"google/api/annotations.proto": "github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/google/api"},
- request: "allow_delete_body,allow_merge,allow_repeated_fields_in_body,include_package_in_tags,file=./foo.pb,import_prefix=/bar/baz,Mgoogle/api/annotations.proto=github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/google/api",
- allowDeleteBodyV: true, allowMergeV: true, allowRepeatedFieldsInBodyV: true, includePackageInTagsV: true,
- fileV: "./foo.pb", importPathV: "/bar/baz", mergeFileNameV: "apidocs",
- },
- {
- name: "Test 2",
- expected: map[string]string{"google/api/annotations.proto": "github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/google/api"},
- request: "allow_delete_body=true,allow_merge=true,allow_repeated_fields_in_body=true,include_package_in_tags=true,merge_file_name=test_name,file=./foo.pb,import_prefix=/bar/baz,Mgoogle/api/annotations.proto=github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/google/api",
- allowDeleteBodyV: true, allowMergeV: true, allowRepeatedFieldsInBodyV: true, includePackageInTagsV: true,
- fileV: "./foo.pb", importPathV: "/bar/baz", mergeFileNameV: "test_name",
- },
- {
- name: "Test 3",
- expected: map[string]string{"a/b/c.proto": "github.com/x/y/z", "f/g/h.proto": "github.com/1/2/3/"},
- request: "allow_delete_body=false,allow_merge=false,Ma/b/c.proto=github.com/x/y/z,Mf/g/h.proto=github.com/1/2/3/",
- allowDeleteBodyV: false, allowMergeV: false, allowRepeatedFieldsInBodyV: false, includePackageInTagsV: false,
- fileV: "stdin", importPathV: "", mergeFileNameV: "apidocs",
- },
- {
- name: "Test 4",
- expected: map[string]string{},
- request: "",
- allowDeleteBodyV: false, allowMergeV: false, allowRepeatedFieldsInBodyV: false, includePackageInTagsV: false,
- fileV: "stdin", importPathV: "", mergeFileNameV: "apidocs",
- },
- {
- name: "Test 5",
- expected: map[string]string{},
- request: "unknown_param=17",
- expectedError: errors.New("Cannot set flag unknown_param=17: no such flag -unknown_param"),
- allowDeleteBodyV: false, allowMergeV: false, allowRepeatedFieldsInBodyV: false, includePackageInTagsV: false,
- fileV: "stdin", importPathV: "", mergeFileNameV: "apidocs",
- },
- {
- name: "Test 6",
- expected: map[string]string{},
- request: "Mfoo",
- expectedError: errors.New("Cannot set flag Mfoo: no such flag -Mfoo"),
- allowDeleteBodyV: false, allowMergeV: false, allowRepeatedFieldsInBodyV: false, includePackageInTagsV: false,
- fileV: "stdin", importPathV: "", mergeFileNameV: "apidocs",
- },
- {
- name: "Test 7",
- expected: map[string]string{},
- request: "allow_delete_body,file,import_prefix,allow_merge,allow_repeated_fields_in_body,include_package_in_tags,merge_file_name",
- allowDeleteBodyV: true, allowMergeV: true, allowRepeatedFieldsInBodyV: true, includePackageInTagsV: true,
- fileV: "", importPathV: "", mergeFileNameV: "",
- },
- {
- name: "Test 8",
- expected: map[string]string{},
- request: "allow_delete_body,file,import_prefix,allow_merge,allow_repeated_fields_in_body=3,merge_file_name",
- expectedError: errors.New(`Cannot set flag allow_repeated_fields_in_body=3: parse error`),
- allowDeleteBodyV: true, allowMergeV: true, allowRepeatedFieldsInBodyV: false, includePackageInTagsV: false,
- fileV: "", importPathV: "", mergeFileNameV: "apidocs",
- },
- {
- name: "Test 9",
- expected: map[string]string{},
- request: "include_package_in_tags=3",
- expectedError: errors.New(`Cannot set flag include_package_in_tags=3: parse error`),
- allowDeleteBodyV: false, allowMergeV: false, allowRepeatedFieldsInBodyV: false, includePackageInTagsV: false,
- fileV: "stdin", importPathV: "", mergeFileNameV: "apidocs",
- },
- {
- name: "Test 10",
- expected: map[string]string{},
- request: "fqn_for_swagger_name=3",
- expectedError: errors.New(`Cannot set flag fqn_for_swagger_name=3: parse error`),
- allowDeleteBodyV: false, allowMergeV: false, allowRepeatedFieldsInBodyV: false, includePackageInTagsV: false, useFQNForSwaggerNameV: false,
- fileV: "stdin", importPathV: "", mergeFileNameV: "apidocs",
- },
- {
- name: "Test 11",
- expected: map[string]string{},
- request: "fqn_for_swagger_name=true",
- allowDeleteBodyV: false, allowMergeV: false, allowRepeatedFieldsInBodyV: false, includePackageInTagsV: false, useFQNForSwaggerNameV: true,
- fileV: "stdin", importPathV: "", mergeFileNameV: "apidocs",
- },
- }
-
- for i, tc := range testcases {
- t.Run(tc.name, func(tt *testing.T) {
- f := flag.CommandLine
- pkgMap := make(map[string]string)
- err := parseReqParam(tc.request, f, pkgMap)
- if tc.expectedError == nil {
- if err != nil {
- tt.Errorf("unexpected parse error '%v'", err)
- }
- if !reflect.DeepEqual(pkgMap, tc.expected) {
- tt.Errorf("pkgMap parse error, expected '%v', got '%v'", tc.expected, pkgMap)
- }
- } else {
- if err == nil {
- tt.Error("expected parse error not returned")
- }
- if !reflect.DeepEqual(pkgMap, tc.expected) {
- tt.Errorf("pkgMap parse error, expected '%v', got '%v'", tc.expected, pkgMap)
- }
- if err.Error() != tc.expectedError.Error() {
- tt.Errorf("expected error malformed, expected %q, got %q", tc.expectedError.Error(), err.Error())
- }
- }
- checkFlags(tc.allowDeleteBodyV, tc.allowMergeV, tc.allowRepeatedFieldsInBodyV, tc.includePackageInTagsV, tc.useFQNForSwaggerNameV, tc.fileV, tc.importPathV, tc.mergeFileNameV, tt, i)
-
- clearFlags()
- })
- }
-
-}
-
-func checkFlags(allowDeleteV, allowMergeV, allowRepeatedFieldsInBodyV, includePackageInTagsV bool, useFQNForSwaggerNameV bool, fileV, importPathV, mergeFileNameV string, t *testing.T, tid int) {
- if *importPrefix != importPathV {
- t.Errorf("Test %v: import_prefix misparsed, expected '%v', got '%v'", tid, importPathV, *importPrefix)
- }
- if *file != fileV {
- t.Errorf("Test %v: file misparsed, expected '%v', got '%v'", tid, fileV, *file)
- }
- if *allowDeleteBody != allowDeleteV {
- t.Errorf("Test %v: allow_delete_body misparsed, expected '%v', got '%v'", tid, allowDeleteV, *allowDeleteBody)
- }
- if *allowMerge != allowMergeV {
- t.Errorf("Test %v: allow_merge misparsed, expected '%v', got '%v'", tid, allowMergeV, *allowMerge)
- }
- if *mergeFileName != mergeFileNameV {
- t.Errorf("Test %v: merge_file_name misparsed, expected '%v', got '%v'", tid, mergeFileNameV, *mergeFileName)
- }
- if *allowRepeatedFieldsInBody != allowRepeatedFieldsInBodyV {
- t.Errorf("Test %v: allow_repeated_fields_in_body misparsed, expected '%v', got '%v'", tid, allowRepeatedFieldsInBodyV, *allowRepeatedFieldsInBody)
- }
- if *includePackageInTags != includePackageInTagsV {
- t.Errorf("Test %v: include_package_in_tags misparsed, expected '%v', got '%v'", tid, includePackageInTagsV, *includePackageInTags)
- }
- if *useFQNForSwaggerName != useFQNForSwaggerNameV {
- t.Errorf("Test %v: fqn_for_swagger_name misparsed, expected '%v', got '%v'", tid, useFQNForSwaggerNameV, *useFQNForSwaggerName)
- }
-}
-
-func clearFlags() {
- *importPrefix = ""
- *file = "stdin"
- *allowDeleteBody = false
- *allowMerge = false
- *allowRepeatedFieldsInBody = false
- *includePackageInTags = false
- *mergeFileName = "apidocs"
-}
diff --git a/gateway/protoc-gen-swagger/options/annotations.pb.go b/gateway/protoc-gen-swagger/options/annotations.pb.go
deleted file mode 100644
index 6514002..0000000
--- a/gateway/protoc-gen-swagger/options/annotations.pb.go
+++ /dev/null
@@ -1,105 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: protoc-gen-swagger/options/annotations.proto
-
-package options
-
-import (
- fmt "fmt"
- proto "github.com/golang/protobuf/proto"
- descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
- 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
-
-var E_Openapiv2Swagger = &proto.ExtensionDesc{
- ExtendedType: (*descriptor.FileOptions)(nil),
- ExtensionType: (*Swagger)(nil),
- Field: 1042,
- Name: "grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger",
- Tag: "bytes,1042,opt,name=openapiv2_swagger",
- Filename: "protoc-gen-swagger/options/annotations.proto",
-}
-
-var E_Openapiv2Operation = &proto.ExtensionDesc{
- ExtendedType: (*descriptor.MethodOptions)(nil),
- ExtensionType: (*Operation)(nil),
- Field: 1042,
- Name: "grpc.gateway.protoc_gen_swagger.options.openapiv2_operation",
- Tag: "bytes,1042,opt,name=openapiv2_operation",
- Filename: "protoc-gen-swagger/options/annotations.proto",
-}
-
-var E_Openapiv2Schema = &proto.ExtensionDesc{
- ExtendedType: (*descriptor.MessageOptions)(nil),
- ExtensionType: (*Schema)(nil),
- Field: 1042,
- Name: "grpc.gateway.protoc_gen_swagger.options.openapiv2_schema",
- Tag: "bytes,1042,opt,name=openapiv2_schema",
- Filename: "protoc-gen-swagger/options/annotations.proto",
-}
-
-var E_Openapiv2Tag = &proto.ExtensionDesc{
- ExtendedType: (*descriptor.ServiceOptions)(nil),
- ExtensionType: (*Tag)(nil),
- Field: 1042,
- Name: "grpc.gateway.protoc_gen_swagger.options.openapiv2_tag",
- Tag: "bytes,1042,opt,name=openapiv2_tag",
- Filename: "protoc-gen-swagger/options/annotations.proto",
-}
-
-var E_Openapiv2Field = &proto.ExtensionDesc{
- ExtendedType: (*descriptor.FieldOptions)(nil),
- ExtensionType: (*JSONSchema)(nil),
- Field: 1042,
- Name: "grpc.gateway.protoc_gen_swagger.options.openapiv2_field",
- Tag: "bytes,1042,opt,name=openapiv2_field",
- Filename: "protoc-gen-swagger/options/annotations.proto",
-}
-
-func init() {
- proto.RegisterExtension(E_Openapiv2Swagger)
- proto.RegisterExtension(E_Openapiv2Operation)
- proto.RegisterExtension(E_Openapiv2Schema)
- proto.RegisterExtension(E_Openapiv2Tag)
- proto.RegisterExtension(E_Openapiv2Field)
-}
-
-func init() {
- proto.RegisterFile("protoc-gen-swagger/options/annotations.proto", fileDescriptor_a6a34ca6badab664)
-}
-
-var fileDescriptor_a6a34ca6badab664 = []byte{
- // 346 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x4f, 0x4f, 0xea, 0x40,
- 0x14, 0xc5, 0xc3, 0xe6, 0xe5, 0xa5, 0xef, 0xa9, 0x58, 0x37, 0x86, 0xf8, 0x87, 0x9d, 0xc6, 0xc0,
- 0x8c, 0x81, 0x5d, 0x77, 0x6a, 0xe2, 0xc2, 0x44, 0x49, 0x0a, 0x2b, 0x37, 0x64, 0x18, 0x2e, 0x97,
- 0x49, 0x4a, 0xef, 0x64, 0x66, 0x80, 0x90, 0xb0, 0xf4, 0x13, 0xf8, 0x89, 0x8d, 0xd3, 0xd2, 0x9a,
- 0x8a, 0xa6, 0xbb, 0xce, 0xe9, 0xbd, 0xe7, 0x77, 0x7a, 0x3a, 0x41, 0x47, 0x1b, 0x72, 0x24, 0xbb,
- 0x08, 0x69, 0xd7, 0xae, 0x05, 0x22, 0x18, 0x4e, 0xda, 0x29, 0x4a, 0x2d, 0x17, 0x69, 0x4a, 0x4e,
- 0xf8, 0x67, 0xe6, 0xc7, 0xc2, 0x2b, 0x34, 0x5a, 0x32, 0x14, 0x0e, 0xd6, 0x62, 0x93, 0x69, 0x72,
- 0x8c, 0x90, 0x8e, 0xf3, 0x55, 0x96, 0xaf, 0xb6, 0xda, 0x48, 0x84, 0x09, 0x70, 0x3f, 0x32, 0x59,
- 0xce, 0xf8, 0x14, 0xac, 0x34, 0x4a, 0x3b, 0x32, 0xd9, 0x5a, 0xeb, 0xe6, 0x17, 0x30, 0x69, 0x48,
- 0x85, 0x56, 0xab, 0x5e, 0x36, 0x1b, 0x6d, 0x83, 0xe3, 0x42, 0xda, 0xa1, 0xc2, 0x33, 0x96, 0x31,
- 0xd8, 0x8e, 0xc1, 0x1e, 0x55, 0x02, 0x83, 0xcc, 0xe2, 0xf4, 0xfd, 0x6f, 0xbb, 0x71, 0xfd, 0xaf,
- 0x77, 0xcb, 0x6a, 0x26, 0x66, 0xc3, 0xec, 0x1c, 0x37, 0x0b, 0x52, 0xae, 0x44, 0x6f, 0x8d, 0xe0,
- 0xa4, 0xc4, 0x93, 0x06, 0xe3, 0x3b, 0x09, 0x2f, 0xbe, 0x05, 0x78, 0x06, 0x37, 0xa7, 0x69, 0x25,
- 0x42, 0xaf, 0x76, 0x84, 0xc1, 0xce, 0x3a, 0x0e, 0x0b, 0x5e, 0xa1, 0x45, 0xdb, 0xa0, 0xf9, 0xa5,
- 0x04, 0x39, 0x87, 0x85, 0x08, 0x2f, 0xf7, 0x44, 0xb0, 0x56, 0x60, 0xb5, 0x06, 0x5e, 0xbf, 0x06,
- 0x6f, 0x1c, 0x1f, 0x95, 0x2d, 0x78, 0x21, 0xb2, 0xc1, 0x41, 0x49, 0x77, 0x02, 0xf7, 0xa0, 0x87,
- 0x60, 0x56, 0x4a, 0x56, 0xd1, 0x9d, 0xda, 0xe8, 0x91, 0xc0, 0xf8, 0x7f, 0x01, 0x19, 0x09, 0x8c,
- 0xb6, 0x41, 0x99, 0x63, 0x3c, 0x53, 0x90, 0x4c, 0xc3, 0xf3, 0x3d, 0x7f, 0x1d, 0x92, 0x6a, 0xe7,
- 0xfd, 0xda, 0xd0, 0xa7, 0xe1, 0xe0, 0x25, 0xff, 0xe6, 0xc3, 0x82, 0xe5, 0x2d, 0xef, 0x1f, 0x5e,
- 0xef, 0x50, 0xb9, 0xf9, 0x72, 0xc2, 0x24, 0x2d, 0xf8, 0xa7, 0x61, 0x17, 0x24, 0xd9, 0x8d, 0x75,
- 0x90, 0x1f, 0x73, 0x7f, 0xfe, 0xf3, 0x55, 0x9e, 0xfc, 0xf1, 0xef, 0xfa, 0x1f, 0x01, 0x00, 0x00,
- 0xff, 0xff, 0x59, 0x78, 0xb0, 0x03, 0x68, 0x03, 0x00, 0x00,
-}
diff --git a/gateway/protoc-gen-swagger/options/openapiv2.pb.go b/gateway/protoc-gen-swagger/options/openapiv2.pb.go
deleted file mode 100644
index 727ca52..0000000
--- a/gateway/protoc-gen-swagger/options/openapiv2.pb.go
+++ /dev/null
@@ -1,1625 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: protoc-gen-swagger/options/openapiv2.proto
-
-package options
-
-import (
- fmt "fmt"
- proto "github.com/golang/protobuf/proto"
- any "github.com/golang/protobuf/ptypes/any"
- _struct "github.com/golang/protobuf/ptypes/struct"
- 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 Swagger_SwaggerScheme int32
-
-const (
- Swagger_UNKNOWN Swagger_SwaggerScheme = 0
- Swagger_HTTP Swagger_SwaggerScheme = 1
- Swagger_HTTPS Swagger_SwaggerScheme = 2
- Swagger_WS Swagger_SwaggerScheme = 3
- Swagger_WSS Swagger_SwaggerScheme = 4
-)
-
-var Swagger_SwaggerScheme_name = map[int32]string{
- 0: "UNKNOWN",
- 1: "HTTP",
- 2: "HTTPS",
- 3: "WS",
- 4: "WSS",
-}
-
-var Swagger_SwaggerScheme_value = map[string]int32{
- "UNKNOWN": 0,
- "HTTP": 1,
- "HTTPS": 2,
- "WS": 3,
- "WSS": 4,
-}
-
-func (x Swagger_SwaggerScheme) String() string {
- return proto.EnumName(Swagger_SwaggerScheme_name, int32(x))
-}
-
-func (Swagger_SwaggerScheme) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_ba35ad8af024fb48, []int{0, 0}
-}
-
-type JSONSchema_JSONSchemaSimpleTypes int32
-
-const (
- JSONSchema_UNKNOWN JSONSchema_JSONSchemaSimpleTypes = 0
- JSONSchema_ARRAY JSONSchema_JSONSchemaSimpleTypes = 1
- JSONSchema_BOOLEAN JSONSchema_JSONSchemaSimpleTypes = 2
- JSONSchema_INTEGER JSONSchema_JSONSchemaSimpleTypes = 3
- JSONSchema_NULL JSONSchema_JSONSchemaSimpleTypes = 4
- JSONSchema_NUMBER JSONSchema_JSONSchemaSimpleTypes = 5
- JSONSchema_OBJECT JSONSchema_JSONSchemaSimpleTypes = 6
- JSONSchema_STRING JSONSchema_JSONSchemaSimpleTypes = 7
-)
-
-var JSONSchema_JSONSchemaSimpleTypes_name = map[int32]string{
- 0: "UNKNOWN",
- 1: "ARRAY",
- 2: "BOOLEAN",
- 3: "INTEGER",
- 4: "NULL",
- 5: "NUMBER",
- 6: "OBJECT",
- 7: "STRING",
-}
-
-var JSONSchema_JSONSchemaSimpleTypes_value = map[string]int32{
- "UNKNOWN": 0,
- "ARRAY": 1,
- "BOOLEAN": 2,
- "INTEGER": 3,
- "NULL": 4,
- "NUMBER": 5,
- "OBJECT": 6,
- "STRING": 7,
-}
-
-func (x JSONSchema_JSONSchemaSimpleTypes) String() string {
- return proto.EnumName(JSONSchema_JSONSchemaSimpleTypes_name, int32(x))
-}
-
-func (JSONSchema_JSONSchemaSimpleTypes) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_ba35ad8af024fb48, []int{8, 0}
-}
-
-// Required. The type of the security scheme. Valid values are "basic",
-// "apiKey" or "oauth2".
-type SecurityScheme_Type int32
-
-const (
- SecurityScheme_TYPE_INVALID SecurityScheme_Type = 0
- SecurityScheme_TYPE_BASIC SecurityScheme_Type = 1
- SecurityScheme_TYPE_API_KEY SecurityScheme_Type = 2
- SecurityScheme_TYPE_OAUTH2 SecurityScheme_Type = 3
-)
-
-var SecurityScheme_Type_name = map[int32]string{
- 0: "TYPE_INVALID",
- 1: "TYPE_BASIC",
- 2: "TYPE_API_KEY",
- 3: "TYPE_OAUTH2",
-}
-
-var SecurityScheme_Type_value = map[string]int32{
- "TYPE_INVALID": 0,
- "TYPE_BASIC": 1,
- "TYPE_API_KEY": 2,
- "TYPE_OAUTH2": 3,
-}
-
-func (x SecurityScheme_Type) String() string {
- return proto.EnumName(SecurityScheme_Type_name, int32(x))
-}
-
-func (SecurityScheme_Type) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_ba35ad8af024fb48, []int{11, 0}
-}
-
-// Required. The location of the API key. Valid values are "query" or "header".
-type SecurityScheme_In int32
-
-const (
- SecurityScheme_IN_INVALID SecurityScheme_In = 0
- SecurityScheme_IN_QUERY SecurityScheme_In = 1
- SecurityScheme_IN_HEADER SecurityScheme_In = 2
-)
-
-var SecurityScheme_In_name = map[int32]string{
- 0: "IN_INVALID",
- 1: "IN_QUERY",
- 2: "IN_HEADER",
-}
-
-var SecurityScheme_In_value = map[string]int32{
- "IN_INVALID": 0,
- "IN_QUERY": 1,
- "IN_HEADER": 2,
-}
-
-func (x SecurityScheme_In) String() string {
- return proto.EnumName(SecurityScheme_In_name, int32(x))
-}
-
-func (SecurityScheme_In) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_ba35ad8af024fb48, []int{11, 1}
-}
-
-// Required. The flow used by the OAuth2 security scheme. Valid values are
-// "implicit", "password", "application" or "accessCode".
-type SecurityScheme_Flow int32
-
-const (
- SecurityScheme_FLOW_INVALID SecurityScheme_Flow = 0
- SecurityScheme_FLOW_IMPLICIT SecurityScheme_Flow = 1
- SecurityScheme_FLOW_PASSWORD SecurityScheme_Flow = 2
- SecurityScheme_FLOW_APPLICATION SecurityScheme_Flow = 3
- SecurityScheme_FLOW_ACCESS_CODE SecurityScheme_Flow = 4
-)
-
-var SecurityScheme_Flow_name = map[int32]string{
- 0: "FLOW_INVALID",
- 1: "FLOW_IMPLICIT",
- 2: "FLOW_PASSWORD",
- 3: "FLOW_APPLICATION",
- 4: "FLOW_ACCESS_CODE",
-}
-
-var SecurityScheme_Flow_value = map[string]int32{
- "FLOW_INVALID": 0,
- "FLOW_IMPLICIT": 1,
- "FLOW_PASSWORD": 2,
- "FLOW_APPLICATION": 3,
- "FLOW_ACCESS_CODE": 4,
-}
-
-func (x SecurityScheme_Flow) String() string {
- return proto.EnumName(SecurityScheme_Flow_name, int32(x))
-}
-
-func (SecurityScheme_Flow) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_ba35ad8af024fb48, []int{11, 2}
-}
-
-// `Swagger` is a representation of OpenAPI v2 specification's Swagger object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#swaggerObject
-//
-// TODO(ivucica): document fields
-type Swagger struct {
- Swagger string `protobuf:"bytes,1,opt,name=swagger,proto3" json:"swagger,omitempty"`
- Info *Info `protobuf:"bytes,2,opt,name=info,proto3" json:"info,omitempty"`
- Host string `protobuf:"bytes,3,opt,name=host,proto3" json:"host,omitempty"`
- // `base_path` is the common prefix path used on all API endpoints (ie. /api, /v1, etc.). By adding this,
- // it allows you to remove this portion from the path endpoints in your Swagger file making them easier
- // to read. Note that using `base_path` does not change the endpoint paths that are generated in the resulting
- // Swagger file. If you wish to use `base_path` with relatively generated Swagger paths, the
- // `base_path` prefix must be manually removed from your `google.api.http` paths and your code changed to
- // serve the API from the `base_path`.
- BasePath string `protobuf:"bytes,4,opt,name=base_path,json=basePath,proto3" json:"base_path,omitempty"`
- Schemes []Swagger_SwaggerScheme `protobuf:"varint,5,rep,packed,name=schemes,proto3,enum=grpc.gateway.protoc_gen_swagger.options.Swagger_SwaggerScheme" json:"schemes,omitempty"`
- Consumes []string `protobuf:"bytes,6,rep,name=consumes,proto3" json:"consumes,omitempty"`
- Produces []string `protobuf:"bytes,7,rep,name=produces,proto3" json:"produces,omitempty"`
- Responses map[string]*Response `protobuf:"bytes,10,rep,name=responses,proto3" json:"responses,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
- SecurityDefinitions *SecurityDefinitions `protobuf:"bytes,11,opt,name=security_definitions,json=securityDefinitions,proto3" json:"security_definitions,omitempty"`
- Security []*SecurityRequirement `protobuf:"bytes,12,rep,name=security,proto3" json:"security,omitempty"`
- ExternalDocs *ExternalDocumentation `protobuf:"bytes,14,opt,name=external_docs,json=externalDocs,proto3" json:"external_docs,omitempty"`
- Extensions map[string]*_struct.Value `protobuf:"bytes,15,rep,name=extensions,proto3" json:"extensions,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 *Swagger) Reset() { *m = Swagger{} }
-func (m *Swagger) String() string { return proto.CompactTextString(m) }
-func (*Swagger) ProtoMessage() {}
-func (*Swagger) Descriptor() ([]byte, []int) {
- return fileDescriptor_ba35ad8af024fb48, []int{0}
-}
-
-func (m *Swagger) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Swagger.Unmarshal(m, b)
-}
-func (m *Swagger) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Swagger.Marshal(b, m, deterministic)
-}
-func (m *Swagger) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Swagger.Merge(m, src)
-}
-func (m *Swagger) XXX_Size() int {
- return xxx_messageInfo_Swagger.Size(m)
-}
-func (m *Swagger) XXX_DiscardUnknown() {
- xxx_messageInfo_Swagger.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Swagger proto.InternalMessageInfo
-
-func (m *Swagger) GetSwagger() string {
- if m != nil {
- return m.Swagger
- }
- return ""
-}
-
-func (m *Swagger) GetInfo() *Info {
- if m != nil {
- return m.Info
- }
- return nil
-}
-
-func (m *Swagger) GetHost() string {
- if m != nil {
- return m.Host
- }
- return ""
-}
-
-func (m *Swagger) GetBasePath() string {
- if m != nil {
- return m.BasePath
- }
- return ""
-}
-
-func (m *Swagger) GetSchemes() []Swagger_SwaggerScheme {
- if m != nil {
- return m.Schemes
- }
- return nil
-}
-
-func (m *Swagger) GetConsumes() []string {
- if m != nil {
- return m.Consumes
- }
- return nil
-}
-
-func (m *Swagger) GetProduces() []string {
- if m != nil {
- return m.Produces
- }
- return nil
-}
-
-func (m *Swagger) GetResponses() map[string]*Response {
- if m != nil {
- return m.Responses
- }
- return nil
-}
-
-func (m *Swagger) GetSecurityDefinitions() *SecurityDefinitions {
- if m != nil {
- return m.SecurityDefinitions
- }
- return nil
-}
-
-func (m *Swagger) GetSecurity() []*SecurityRequirement {
- if m != nil {
- return m.Security
- }
- return nil
-}
-
-func (m *Swagger) GetExternalDocs() *ExternalDocumentation {
- if m != nil {
- return m.ExternalDocs
- }
- return nil
-}
-
-func (m *Swagger) GetExtensions() map[string]*_struct.Value {
- if m != nil {
- return m.Extensions
- }
- return nil
-}
-
-// `Operation` is a representation of OpenAPI v2 specification's Operation object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#operationObject
-//
-// TODO(ivucica): document fields
-type Operation struct {
- Tags []string `protobuf:"bytes,1,rep,name=tags,proto3" json:"tags,omitempty"`
- Summary string `protobuf:"bytes,2,opt,name=summary,proto3" json:"summary,omitempty"`
- Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
- ExternalDocs *ExternalDocumentation `protobuf:"bytes,4,opt,name=external_docs,json=externalDocs,proto3" json:"external_docs,omitempty"`
- OperationId string `protobuf:"bytes,5,opt,name=operation_id,json=operationId,proto3" json:"operation_id,omitempty"`
- Consumes []string `protobuf:"bytes,6,rep,name=consumes,proto3" json:"consumes,omitempty"`
- Produces []string `protobuf:"bytes,7,rep,name=produces,proto3" json:"produces,omitempty"`
- Responses map[string]*Response `protobuf:"bytes,9,rep,name=responses,proto3" json:"responses,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
- Schemes []string `protobuf:"bytes,10,rep,name=schemes,proto3" json:"schemes,omitempty"`
- Deprecated bool `protobuf:"varint,11,opt,name=deprecated,proto3" json:"deprecated,omitempty"`
- Security []*SecurityRequirement `protobuf:"bytes,12,rep,name=security,proto3" json:"security,omitempty"`
- Extensions map[string]*_struct.Value `protobuf:"bytes,13,rep,name=extensions,proto3" json:"extensions,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 *Operation) Reset() { *m = Operation{} }
-func (m *Operation) String() string { return proto.CompactTextString(m) }
-func (*Operation) ProtoMessage() {}
-func (*Operation) Descriptor() ([]byte, []int) {
- return fileDescriptor_ba35ad8af024fb48, []int{1}
-}
-
-func (m *Operation) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Operation.Unmarshal(m, b)
-}
-func (m *Operation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Operation.Marshal(b, m, deterministic)
-}
-func (m *Operation) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Operation.Merge(m, src)
-}
-func (m *Operation) XXX_Size() int {
- return xxx_messageInfo_Operation.Size(m)
-}
-func (m *Operation) XXX_DiscardUnknown() {
- xxx_messageInfo_Operation.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Operation proto.InternalMessageInfo
-
-func (m *Operation) GetTags() []string {
- if m != nil {
- return m.Tags
- }
- return nil
-}
-
-func (m *Operation) GetSummary() string {
- if m != nil {
- return m.Summary
- }
- return ""
-}
-
-func (m *Operation) GetDescription() string {
- if m != nil {
- return m.Description
- }
- return ""
-}
-
-func (m *Operation) GetExternalDocs() *ExternalDocumentation {
- if m != nil {
- return m.ExternalDocs
- }
- return nil
-}
-
-func (m *Operation) GetOperationId() string {
- if m != nil {
- return m.OperationId
- }
- return ""
-}
-
-func (m *Operation) GetConsumes() []string {
- if m != nil {
- return m.Consumes
- }
- return nil
-}
-
-func (m *Operation) GetProduces() []string {
- if m != nil {
- return m.Produces
- }
- return nil
-}
-
-func (m *Operation) GetResponses() map[string]*Response {
- if m != nil {
- return m.Responses
- }
- return nil
-}
-
-func (m *Operation) GetSchemes() []string {
- if m != nil {
- return m.Schemes
- }
- return nil
-}
-
-func (m *Operation) GetDeprecated() bool {
- if m != nil {
- return m.Deprecated
- }
- return false
-}
-
-func (m *Operation) GetSecurity() []*SecurityRequirement {
- if m != nil {
- return m.Security
- }
- return nil
-}
-
-func (m *Operation) GetExtensions() map[string]*_struct.Value {
- if m != nil {
- return m.Extensions
- }
- return nil
-}
-
-// `Response` is a representation of OpenAPI v2 specification's Response object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#responseObject
-//
-type Response struct {
- // `Description` is a short description of the response.
- // GFM syntax can be used for rich text representation.
- Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"`
- // `Schema` optionally defines the structure of the response.
- // If `Schema` is not provided, it means there is no content to the response.
- Schema *Schema `protobuf:"bytes,2,opt,name=schema,proto3" json:"schema,omitempty"`
- Extensions map[string]*_struct.Value `protobuf:"bytes,5,rep,name=extensions,proto3" json:"extensions,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_ba35ad8af024fb48, []int{2}
-}
-
-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) GetDescription() string {
- if m != nil {
- return m.Description
- }
- return ""
-}
-
-func (m *Response) GetSchema() *Schema {
- if m != nil {
- return m.Schema
- }
- return nil
-}
-
-func (m *Response) GetExtensions() map[string]*_struct.Value {
- if m != nil {
- return m.Extensions
- }
- return nil
-}
-
-// `Info` is a representation of OpenAPI v2 specification's Info object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#infoObject
-//
-// TODO(ivucica): document fields
-type Info struct {
- Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"`
- Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
- TermsOfService string `protobuf:"bytes,3,opt,name=terms_of_service,json=termsOfService,proto3" json:"terms_of_service,omitempty"`
- Contact *Contact `protobuf:"bytes,4,opt,name=contact,proto3" json:"contact,omitempty"`
- License *License `protobuf:"bytes,5,opt,name=license,proto3" json:"license,omitempty"`
- Version string `protobuf:"bytes,6,opt,name=version,proto3" json:"version,omitempty"`
- Extensions map[string]*_struct.Value `protobuf:"bytes,7,rep,name=extensions,proto3" json:"extensions,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 *Info) Reset() { *m = Info{} }
-func (m *Info) String() string { return proto.CompactTextString(m) }
-func (*Info) ProtoMessage() {}
-func (*Info) Descriptor() ([]byte, []int) {
- return fileDescriptor_ba35ad8af024fb48, []int{3}
-}
-
-func (m *Info) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Info.Unmarshal(m, b)
-}
-func (m *Info) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Info.Marshal(b, m, deterministic)
-}
-func (m *Info) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Info.Merge(m, src)
-}
-func (m *Info) XXX_Size() int {
- return xxx_messageInfo_Info.Size(m)
-}
-func (m *Info) XXX_DiscardUnknown() {
- xxx_messageInfo_Info.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Info proto.InternalMessageInfo
-
-func (m *Info) GetTitle() string {
- if m != nil {
- return m.Title
- }
- return ""
-}
-
-func (m *Info) GetDescription() string {
- if m != nil {
- return m.Description
- }
- return ""
-}
-
-func (m *Info) GetTermsOfService() string {
- if m != nil {
- return m.TermsOfService
- }
- return ""
-}
-
-func (m *Info) GetContact() *Contact {
- if m != nil {
- return m.Contact
- }
- return nil
-}
-
-func (m *Info) GetLicense() *License {
- if m != nil {
- return m.License
- }
- return nil
-}
-
-func (m *Info) GetVersion() string {
- if m != nil {
- return m.Version
- }
- return ""
-}
-
-func (m *Info) GetExtensions() map[string]*_struct.Value {
- if m != nil {
- return m.Extensions
- }
- return nil
-}
-
-// `Contact` is a representation of OpenAPI v2 specification's Contact object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#contactObject
-//
-// TODO(ivucica): document fields
-type Contact struct {
- Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
- Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"`
- Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
-}
-
-func (m *Contact) Reset() { *m = Contact{} }
-func (m *Contact) String() string { return proto.CompactTextString(m) }
-func (*Contact) ProtoMessage() {}
-func (*Contact) Descriptor() ([]byte, []int) {
- return fileDescriptor_ba35ad8af024fb48, []int{4}
-}
-
-func (m *Contact) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Contact.Unmarshal(m, b)
-}
-func (m *Contact) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Contact.Marshal(b, m, deterministic)
-}
-func (m *Contact) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Contact.Merge(m, src)
-}
-func (m *Contact) XXX_Size() int {
- return xxx_messageInfo_Contact.Size(m)
-}
-func (m *Contact) XXX_DiscardUnknown() {
- xxx_messageInfo_Contact.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Contact proto.InternalMessageInfo
-
-func (m *Contact) GetName() string {
- if m != nil {
- return m.Name
- }
- return ""
-}
-
-func (m *Contact) GetUrl() string {
- if m != nil {
- return m.Url
- }
- return ""
-}
-
-func (m *Contact) GetEmail() string {
- if m != nil {
- return m.Email
- }
- return ""
-}
-
-// `License` is a representation of OpenAPI v2 specification's License object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#licenseObject
-//
-type License struct {
- // Required. The license name used for the API.
- Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
- // A URL to the license used for the API.
- Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
-}
-
-func (m *License) Reset() { *m = License{} }
-func (m *License) String() string { return proto.CompactTextString(m) }
-func (*License) ProtoMessage() {}
-func (*License) Descriptor() ([]byte, []int) {
- return fileDescriptor_ba35ad8af024fb48, []int{5}
-}
-
-func (m *License) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_License.Unmarshal(m, b)
-}
-func (m *License) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_License.Marshal(b, m, deterministic)
-}
-func (m *License) XXX_Merge(src proto.Message) {
- xxx_messageInfo_License.Merge(m, src)
-}
-func (m *License) XXX_Size() int {
- return xxx_messageInfo_License.Size(m)
-}
-func (m *License) XXX_DiscardUnknown() {
- xxx_messageInfo_License.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_License proto.InternalMessageInfo
-
-func (m *License) GetName() string {
- if m != nil {
- return m.Name
- }
- return ""
-}
-
-func (m *License) GetUrl() string {
- if m != nil {
- return m.Url
- }
- return ""
-}
-
-// `ExternalDocumentation` is a representation of OpenAPI v2 specification's
-// ExternalDocumentation object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#externalDocumentationObject
-//
-// TODO(ivucica): document fields
-type ExternalDocumentation struct {
- Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"`
- Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
-}
-
-func (m *ExternalDocumentation) Reset() { *m = ExternalDocumentation{} }
-func (m *ExternalDocumentation) String() string { return proto.CompactTextString(m) }
-func (*ExternalDocumentation) ProtoMessage() {}
-func (*ExternalDocumentation) Descriptor() ([]byte, []int) {
- return fileDescriptor_ba35ad8af024fb48, []int{6}
-}
-
-func (m *ExternalDocumentation) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_ExternalDocumentation.Unmarshal(m, b)
-}
-func (m *ExternalDocumentation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_ExternalDocumentation.Marshal(b, m, deterministic)
-}
-func (m *ExternalDocumentation) XXX_Merge(src proto.Message) {
- xxx_messageInfo_ExternalDocumentation.Merge(m, src)
-}
-func (m *ExternalDocumentation) XXX_Size() int {
- return xxx_messageInfo_ExternalDocumentation.Size(m)
-}
-func (m *ExternalDocumentation) XXX_DiscardUnknown() {
- xxx_messageInfo_ExternalDocumentation.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ExternalDocumentation proto.InternalMessageInfo
-
-func (m *ExternalDocumentation) GetDescription() string {
- if m != nil {
- return m.Description
- }
- return ""
-}
-
-func (m *ExternalDocumentation) GetUrl() string {
- if m != nil {
- return m.Url
- }
- return ""
-}
-
-// `Schema` is a representation of OpenAPI v2 specification's Schema object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#schemaObject
-//
-// TODO(ivucica): document fields
-type Schema struct {
- JsonSchema *JSONSchema `protobuf:"bytes,1,opt,name=json_schema,json=jsonSchema,proto3" json:"json_schema,omitempty"`
- Discriminator string `protobuf:"bytes,2,opt,name=discriminator,proto3" json:"discriminator,omitempty"`
- ReadOnly bool `protobuf:"varint,3,opt,name=read_only,json=readOnly,proto3" json:"read_only,omitempty"`
- ExternalDocs *ExternalDocumentation `protobuf:"bytes,5,opt,name=external_docs,json=externalDocs,proto3" json:"external_docs,omitempty"`
- Example *any.Any `protobuf:"bytes,6,opt,name=example,proto3" json:"example,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
-}
-
-func (m *Schema) Reset() { *m = Schema{} }
-func (m *Schema) String() string { return proto.CompactTextString(m) }
-func (*Schema) ProtoMessage() {}
-func (*Schema) Descriptor() ([]byte, []int) {
- return fileDescriptor_ba35ad8af024fb48, []int{7}
-}
-
-func (m *Schema) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Schema.Unmarshal(m, b)
-}
-func (m *Schema) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Schema.Marshal(b, m, deterministic)
-}
-func (m *Schema) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Schema.Merge(m, src)
-}
-func (m *Schema) XXX_Size() int {
- return xxx_messageInfo_Schema.Size(m)
-}
-func (m *Schema) XXX_DiscardUnknown() {
- xxx_messageInfo_Schema.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Schema proto.InternalMessageInfo
-
-func (m *Schema) GetJsonSchema() *JSONSchema {
- if m != nil {
- return m.JsonSchema
- }
- return nil
-}
-
-func (m *Schema) GetDiscriminator() string {
- if m != nil {
- return m.Discriminator
- }
- return ""
-}
-
-func (m *Schema) GetReadOnly() bool {
- if m != nil {
- return m.ReadOnly
- }
- return false
-}
-
-func (m *Schema) GetExternalDocs() *ExternalDocumentation {
- if m != nil {
- return m.ExternalDocs
- }
- return nil
-}
-
-func (m *Schema) GetExample() *any.Any {
- if m != nil {
- return m.Example
- }
- return nil
-}
-
-// `JSONSchema` represents properties from JSON Schema taken, and as used, in
-// the OpenAPI v2 spec.
-//
-// This includes changes made by OpenAPI v2.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#schemaObject
-//
-// See also: https://cswr.github.io/JsonSchema/spec/basic_types/,
-// https://github.com/json-schema-org/json-schema-spec/blob/master/schema.json
-//
-// TODO(ivucica): document fields
-type JSONSchema struct {
- // Ref is used to define an external reference to include in the message.
- // This could be a fully qualified proto message reference, and that type must be imported
- // into the protofile. If no message is identified, the Ref will be used verbatim in
- // the output.
- // For example:
- // `ref: ".google.protobuf.Timestamp"`.
- Ref string `protobuf:"bytes,3,opt,name=ref,proto3" json:"ref,omitempty"`
- Title string `protobuf:"bytes,5,opt,name=title,proto3" json:"title,omitempty"`
- Description string `protobuf:"bytes,6,opt,name=description,proto3" json:"description,omitempty"`
- Default string `protobuf:"bytes,7,opt,name=default,proto3" json:"default,omitempty"`
- ReadOnly bool `protobuf:"varint,8,opt,name=read_only,json=readOnly,proto3" json:"read_only,omitempty"`
- MultipleOf float64 `protobuf:"fixed64,10,opt,name=multiple_of,json=multipleOf,proto3" json:"multiple_of,omitempty"`
- Maximum float64 `protobuf:"fixed64,11,opt,name=maximum,proto3" json:"maximum,omitempty"`
- ExclusiveMaximum bool `protobuf:"varint,12,opt,name=exclusive_maximum,json=exclusiveMaximum,proto3" json:"exclusive_maximum,omitempty"`
- Minimum float64 `protobuf:"fixed64,13,opt,name=minimum,proto3" json:"minimum,omitempty"`
- ExclusiveMinimum bool `protobuf:"varint,14,opt,name=exclusive_minimum,json=exclusiveMinimum,proto3" json:"exclusive_minimum,omitempty"`
- MaxLength uint64 `protobuf:"varint,15,opt,name=max_length,json=maxLength,proto3" json:"max_length,omitempty"`
- MinLength uint64 `protobuf:"varint,16,opt,name=min_length,json=minLength,proto3" json:"min_length,omitempty"`
- Pattern string `protobuf:"bytes,17,opt,name=pattern,proto3" json:"pattern,omitempty"`
- MaxItems uint64 `protobuf:"varint,20,opt,name=max_items,json=maxItems,proto3" json:"max_items,omitempty"`
- MinItems uint64 `protobuf:"varint,21,opt,name=min_items,json=minItems,proto3" json:"min_items,omitempty"`
- UniqueItems bool `protobuf:"varint,22,opt,name=unique_items,json=uniqueItems,proto3" json:"unique_items,omitempty"`
- MaxProperties uint64 `protobuf:"varint,24,opt,name=max_properties,json=maxProperties,proto3" json:"max_properties,omitempty"`
- MinProperties uint64 `protobuf:"varint,25,opt,name=min_properties,json=minProperties,proto3" json:"min_properties,omitempty"`
- Required []string `protobuf:"bytes,26,rep,name=required,proto3" json:"required,omitempty"`
- // Items in 'array' must be unique.
- Array []string `protobuf:"bytes,34,rep,name=array,proto3" json:"array,omitempty"`
- Type []JSONSchema_JSONSchemaSimpleTypes `protobuf:"varint,35,rep,packed,name=type,proto3,enum=grpc.gateway.protoc_gen_swagger.options.JSONSchema_JSONSchemaSimpleTypes" json:"type,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
-}
-
-func (m *JSONSchema) Reset() { *m = JSONSchema{} }
-func (m *JSONSchema) String() string { return proto.CompactTextString(m) }
-func (*JSONSchema) ProtoMessage() {}
-func (*JSONSchema) Descriptor() ([]byte, []int) {
- return fileDescriptor_ba35ad8af024fb48, []int{8}
-}
-
-func (m *JSONSchema) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_JSONSchema.Unmarshal(m, b)
-}
-func (m *JSONSchema) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_JSONSchema.Marshal(b, m, deterministic)
-}
-func (m *JSONSchema) XXX_Merge(src proto.Message) {
- xxx_messageInfo_JSONSchema.Merge(m, src)
-}
-func (m *JSONSchema) XXX_Size() int {
- return xxx_messageInfo_JSONSchema.Size(m)
-}
-func (m *JSONSchema) XXX_DiscardUnknown() {
- xxx_messageInfo_JSONSchema.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_JSONSchema proto.InternalMessageInfo
-
-func (m *JSONSchema) GetRef() string {
- if m != nil {
- return m.Ref
- }
- return ""
-}
-
-func (m *JSONSchema) GetTitle() string {
- if m != nil {
- return m.Title
- }
- return ""
-}
-
-func (m *JSONSchema) GetDescription() string {
- if m != nil {
- return m.Description
- }
- return ""
-}
-
-func (m *JSONSchema) GetDefault() string {
- if m != nil {
- return m.Default
- }
- return ""
-}
-
-func (m *JSONSchema) GetReadOnly() bool {
- if m != nil {
- return m.ReadOnly
- }
- return false
-}
-
-func (m *JSONSchema) GetMultipleOf() float64 {
- if m != nil {
- return m.MultipleOf
- }
- return 0
-}
-
-func (m *JSONSchema) GetMaximum() float64 {
- if m != nil {
- return m.Maximum
- }
- return 0
-}
-
-func (m *JSONSchema) GetExclusiveMaximum() bool {
- if m != nil {
- return m.ExclusiveMaximum
- }
- return false
-}
-
-func (m *JSONSchema) GetMinimum() float64 {
- if m != nil {
- return m.Minimum
- }
- return 0
-}
-
-func (m *JSONSchema) GetExclusiveMinimum() bool {
- if m != nil {
- return m.ExclusiveMinimum
- }
- return false
-}
-
-func (m *JSONSchema) GetMaxLength() uint64 {
- if m != nil {
- return m.MaxLength
- }
- return 0
-}
-
-func (m *JSONSchema) GetMinLength() uint64 {
- if m != nil {
- return m.MinLength
- }
- return 0
-}
-
-func (m *JSONSchema) GetPattern() string {
- if m != nil {
- return m.Pattern
- }
- return ""
-}
-
-func (m *JSONSchema) GetMaxItems() uint64 {
- if m != nil {
- return m.MaxItems
- }
- return 0
-}
-
-func (m *JSONSchema) GetMinItems() uint64 {
- if m != nil {
- return m.MinItems
- }
- return 0
-}
-
-func (m *JSONSchema) GetUniqueItems() bool {
- if m != nil {
- return m.UniqueItems
- }
- return false
-}
-
-func (m *JSONSchema) GetMaxProperties() uint64 {
- if m != nil {
- return m.MaxProperties
- }
- return 0
-}
-
-func (m *JSONSchema) GetMinProperties() uint64 {
- if m != nil {
- return m.MinProperties
- }
- return 0
-}
-
-func (m *JSONSchema) GetRequired() []string {
- if m != nil {
- return m.Required
- }
- return nil
-}
-
-func (m *JSONSchema) GetArray() []string {
- if m != nil {
- return m.Array
- }
- return nil
-}
-
-func (m *JSONSchema) GetType() []JSONSchema_JSONSchemaSimpleTypes {
- if m != nil {
- return m.Type
- }
- return nil
-}
-
-// `Tag` is a representation of OpenAPI v2 specification's Tag object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#tagObject
-//
-// TODO(ivucica): document fields
-type Tag struct {
- // TODO(ivucica): Description should be extracted from comments on the proto
- // service object.
- Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
- ExternalDocs *ExternalDocumentation `protobuf:"bytes,3,opt,name=external_docs,json=externalDocs,proto3" json:"external_docs,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
-}
-
-func (m *Tag) Reset() { *m = Tag{} }
-func (m *Tag) String() string { return proto.CompactTextString(m) }
-func (*Tag) ProtoMessage() {}
-func (*Tag) Descriptor() ([]byte, []int) {
- return fileDescriptor_ba35ad8af024fb48, []int{9}
-}
-
-func (m *Tag) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Tag.Unmarshal(m, b)
-}
-func (m *Tag) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Tag.Marshal(b, m, deterministic)
-}
-func (m *Tag) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Tag.Merge(m, src)
-}
-func (m *Tag) XXX_Size() int {
- return xxx_messageInfo_Tag.Size(m)
-}
-func (m *Tag) XXX_DiscardUnknown() {
- xxx_messageInfo_Tag.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Tag proto.InternalMessageInfo
-
-func (m *Tag) GetDescription() string {
- if m != nil {
- return m.Description
- }
- return ""
-}
-
-func (m *Tag) GetExternalDocs() *ExternalDocumentation {
- if m != nil {
- return m.ExternalDocs
- }
- return nil
-}
-
-// `SecurityDefinitions` is a representation of OpenAPI v2 specification's
-// Security Definitions object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securityDefinitionsObject
-//
-// A declaration of the security schemes available to be used in the
-// specification. This does not enforce the security schemes on the operations
-// and only serves to provide the relevant details for each scheme.
-type SecurityDefinitions struct {
- // A single security scheme definition, mapping a "name" to the scheme it defines.
- Security map[string]*SecurityScheme `protobuf:"bytes,1,rep,name=security,proto3" json:"security,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 *SecurityDefinitions) Reset() { *m = SecurityDefinitions{} }
-func (m *SecurityDefinitions) String() string { return proto.CompactTextString(m) }
-func (*SecurityDefinitions) ProtoMessage() {}
-func (*SecurityDefinitions) Descriptor() ([]byte, []int) {
- return fileDescriptor_ba35ad8af024fb48, []int{10}
-}
-
-func (m *SecurityDefinitions) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_SecurityDefinitions.Unmarshal(m, b)
-}
-func (m *SecurityDefinitions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_SecurityDefinitions.Marshal(b, m, deterministic)
-}
-func (m *SecurityDefinitions) XXX_Merge(src proto.Message) {
- xxx_messageInfo_SecurityDefinitions.Merge(m, src)
-}
-func (m *SecurityDefinitions) XXX_Size() int {
- return xxx_messageInfo_SecurityDefinitions.Size(m)
-}
-func (m *SecurityDefinitions) XXX_DiscardUnknown() {
- xxx_messageInfo_SecurityDefinitions.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_SecurityDefinitions proto.InternalMessageInfo
-
-func (m *SecurityDefinitions) GetSecurity() map[string]*SecurityScheme {
- if m != nil {
- return m.Security
- }
- return nil
-}
-
-// `SecurityScheme` is a representation of OpenAPI v2 specification's
-// Security Scheme object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securitySchemeObject
-//
-// Allows the definition of a security scheme that can be used by the
-// operations. Supported schemes are basic authentication, an API key (either as
-// a header or as a query parameter) and OAuth2's common flows (implicit,
-// password, application and access code).
-type SecurityScheme struct {
- // Required. The type of the security scheme. Valid values are "basic",
- // "apiKey" or "oauth2".
- Type SecurityScheme_Type `protobuf:"varint,1,opt,name=type,proto3,enum=grpc.gateway.protoc_gen_swagger.options.SecurityScheme_Type" json:"type,omitempty"`
- // A short description for security scheme.
- Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
- // Required. The name of the header or query parameter to be used.
- //
- // Valid for apiKey.
- Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
- // Required. The location of the API key. Valid values are "query" or "header".
- //
- // Valid for apiKey.
- In SecurityScheme_In `protobuf:"varint,4,opt,name=in,proto3,enum=grpc.gateway.protoc_gen_swagger.options.SecurityScheme_In" json:"in,omitempty"`
- // Required. The flow used by the OAuth2 security scheme. Valid values are
- // "implicit", "password", "application" or "accessCode".
- //
- // Valid for oauth2.
- Flow SecurityScheme_Flow `protobuf:"varint,5,opt,name=flow,proto3,enum=grpc.gateway.protoc_gen_swagger.options.SecurityScheme_Flow" json:"flow,omitempty"`
- // Required. The authorization URL to be used for this flow. This SHOULD be in
- // the form of a URL.
- //
- // Valid for oauth2/implicit and oauth2/accessCode.
- AuthorizationUrl string `protobuf:"bytes,6,opt,name=authorization_url,json=authorizationUrl,proto3" json:"authorization_url,omitempty"`
- // Required. The token URL to be used for this flow. This SHOULD be in the
- // form of a URL.
- //
- // Valid for oauth2/password, oauth2/application and oauth2/accessCode.
- TokenUrl string `protobuf:"bytes,7,opt,name=token_url,json=tokenUrl,proto3" json:"token_url,omitempty"`
- // Required. The available scopes for the OAuth2 security scheme.
- //
- // Valid for oauth2.
- Scopes *Scopes `protobuf:"bytes,8,opt,name=scopes,proto3" json:"scopes,omitempty"`
- Extensions map[string]*_struct.Value `protobuf:"bytes,9,rep,name=extensions,proto3" json:"extensions,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 *SecurityScheme) Reset() { *m = SecurityScheme{} }
-func (m *SecurityScheme) String() string { return proto.CompactTextString(m) }
-func (*SecurityScheme) ProtoMessage() {}
-func (*SecurityScheme) Descriptor() ([]byte, []int) {
- return fileDescriptor_ba35ad8af024fb48, []int{11}
-}
-
-func (m *SecurityScheme) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_SecurityScheme.Unmarshal(m, b)
-}
-func (m *SecurityScheme) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_SecurityScheme.Marshal(b, m, deterministic)
-}
-func (m *SecurityScheme) XXX_Merge(src proto.Message) {
- xxx_messageInfo_SecurityScheme.Merge(m, src)
-}
-func (m *SecurityScheme) XXX_Size() int {
- return xxx_messageInfo_SecurityScheme.Size(m)
-}
-func (m *SecurityScheme) XXX_DiscardUnknown() {
- xxx_messageInfo_SecurityScheme.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_SecurityScheme proto.InternalMessageInfo
-
-func (m *SecurityScheme) GetType() SecurityScheme_Type {
- if m != nil {
- return m.Type
- }
- return SecurityScheme_TYPE_INVALID
-}
-
-func (m *SecurityScheme) GetDescription() string {
- if m != nil {
- return m.Description
- }
- return ""
-}
-
-func (m *SecurityScheme) GetName() string {
- if m != nil {
- return m.Name
- }
- return ""
-}
-
-func (m *SecurityScheme) GetIn() SecurityScheme_In {
- if m != nil {
- return m.In
- }
- return SecurityScheme_IN_INVALID
-}
-
-func (m *SecurityScheme) GetFlow() SecurityScheme_Flow {
- if m != nil {
- return m.Flow
- }
- return SecurityScheme_FLOW_INVALID
-}
-
-func (m *SecurityScheme) GetAuthorizationUrl() string {
- if m != nil {
- return m.AuthorizationUrl
- }
- return ""
-}
-
-func (m *SecurityScheme) GetTokenUrl() string {
- if m != nil {
- return m.TokenUrl
- }
- return ""
-}
-
-func (m *SecurityScheme) GetScopes() *Scopes {
- if m != nil {
- return m.Scopes
- }
- return nil
-}
-
-func (m *SecurityScheme) GetExtensions() map[string]*_struct.Value {
- if m != nil {
- return m.Extensions
- }
- return nil
-}
-
-// `SecurityRequirement` is a representation of OpenAPI v2 specification's
-// Security Requirement object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securityRequirementObject
-//
-// Lists the required security schemes to execute this operation. The object can
-// have multiple security schemes declared in it which are all required (that
-// is, there is a logical AND between the schemes).
-//
-// The name used for each property MUST correspond to a security scheme
-// declared in the Security Definitions.
-type SecurityRequirement struct {
- // Each name must correspond to a security scheme which is declared in
- // the Security Definitions. If the security scheme is of type "oauth2",
- // then the value is a list of scope names required for the execution.
- // For other security scheme types, the array MUST be empty.
- SecurityRequirement map[string]*SecurityRequirement_SecurityRequirementValue `protobuf:"bytes,1,rep,name=security_requirement,json=securityRequirement,proto3" json:"security_requirement,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 *SecurityRequirement) Reset() { *m = SecurityRequirement{} }
-func (m *SecurityRequirement) String() string { return proto.CompactTextString(m) }
-func (*SecurityRequirement) ProtoMessage() {}
-func (*SecurityRequirement) Descriptor() ([]byte, []int) {
- return fileDescriptor_ba35ad8af024fb48, []int{12}
-}
-
-func (m *SecurityRequirement) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_SecurityRequirement.Unmarshal(m, b)
-}
-func (m *SecurityRequirement) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_SecurityRequirement.Marshal(b, m, deterministic)
-}
-func (m *SecurityRequirement) XXX_Merge(src proto.Message) {
- xxx_messageInfo_SecurityRequirement.Merge(m, src)
-}
-func (m *SecurityRequirement) XXX_Size() int {
- return xxx_messageInfo_SecurityRequirement.Size(m)
-}
-func (m *SecurityRequirement) XXX_DiscardUnknown() {
- xxx_messageInfo_SecurityRequirement.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_SecurityRequirement proto.InternalMessageInfo
-
-func (m *SecurityRequirement) GetSecurityRequirement() map[string]*SecurityRequirement_SecurityRequirementValue {
- if m != nil {
- return m.SecurityRequirement
- }
- return nil
-}
-
-// If the security scheme is of type "oauth2", then the value is a list of
-// scope names required for the execution. For other security scheme types,
-// the array MUST be empty.
-type SecurityRequirement_SecurityRequirementValue struct {
- Scope []string `protobuf:"bytes,1,rep,name=scope,proto3" json:"scope,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
-}
-
-func (m *SecurityRequirement_SecurityRequirementValue) Reset() {
- *m = SecurityRequirement_SecurityRequirementValue{}
-}
-func (m *SecurityRequirement_SecurityRequirementValue) String() string {
- return proto.CompactTextString(m)
-}
-func (*SecurityRequirement_SecurityRequirementValue) ProtoMessage() {}
-func (*SecurityRequirement_SecurityRequirementValue) Descriptor() ([]byte, []int) {
- return fileDescriptor_ba35ad8af024fb48, []int{12, 0}
-}
-
-func (m *SecurityRequirement_SecurityRequirementValue) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_SecurityRequirement_SecurityRequirementValue.Unmarshal(m, b)
-}
-func (m *SecurityRequirement_SecurityRequirementValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_SecurityRequirement_SecurityRequirementValue.Marshal(b, m, deterministic)
-}
-func (m *SecurityRequirement_SecurityRequirementValue) XXX_Merge(src proto.Message) {
- xxx_messageInfo_SecurityRequirement_SecurityRequirementValue.Merge(m, src)
-}
-func (m *SecurityRequirement_SecurityRequirementValue) XXX_Size() int {
- return xxx_messageInfo_SecurityRequirement_SecurityRequirementValue.Size(m)
-}
-func (m *SecurityRequirement_SecurityRequirementValue) XXX_DiscardUnknown() {
- xxx_messageInfo_SecurityRequirement_SecurityRequirementValue.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_SecurityRequirement_SecurityRequirementValue proto.InternalMessageInfo
-
-func (m *SecurityRequirement_SecurityRequirementValue) GetScope() []string {
- if m != nil {
- return m.Scope
- }
- return nil
-}
-
-// `Scopes` is a representation of OpenAPI v2 specification's Scopes object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#scopesObject
-//
-// Lists the available scopes for an OAuth2 security scheme.
-type Scopes struct {
- // Maps between a name of a scope to a short description of it (as the value
- // of the property).
- Scope map[string]string `protobuf:"bytes,1,rep,name=scope,proto3" json:"scope,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 *Scopes) Reset() { *m = Scopes{} }
-func (m *Scopes) String() string { return proto.CompactTextString(m) }
-func (*Scopes) ProtoMessage() {}
-func (*Scopes) Descriptor() ([]byte, []int) {
- return fileDescriptor_ba35ad8af024fb48, []int{13}
-}
-
-func (m *Scopes) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Scopes.Unmarshal(m, b)
-}
-func (m *Scopes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Scopes.Marshal(b, m, deterministic)
-}
-func (m *Scopes) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Scopes.Merge(m, src)
-}
-func (m *Scopes) XXX_Size() int {
- return xxx_messageInfo_Scopes.Size(m)
-}
-func (m *Scopes) XXX_DiscardUnknown() {
- xxx_messageInfo_Scopes.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Scopes proto.InternalMessageInfo
-
-func (m *Scopes) GetScope() map[string]string {
- if m != nil {
- return m.Scope
- }
- return nil
-}
-
-func init() {
- proto.RegisterEnum("grpc.gateway.protoc_gen_swagger.options.Swagger_SwaggerScheme", Swagger_SwaggerScheme_name, Swagger_SwaggerScheme_value)
- proto.RegisterEnum("grpc.gateway.protoc_gen_swagger.options.JSONSchema_JSONSchemaSimpleTypes", JSONSchema_JSONSchemaSimpleTypes_name, JSONSchema_JSONSchemaSimpleTypes_value)
- proto.RegisterEnum("grpc.gateway.protoc_gen_swagger.options.SecurityScheme_Type", SecurityScheme_Type_name, SecurityScheme_Type_value)
- proto.RegisterEnum("grpc.gateway.protoc_gen_swagger.options.SecurityScheme_In", SecurityScheme_In_name, SecurityScheme_In_value)
- proto.RegisterEnum("grpc.gateway.protoc_gen_swagger.options.SecurityScheme_Flow", SecurityScheme_Flow_name, SecurityScheme_Flow_value)
- proto.RegisterType((*Swagger)(nil), "grpc.gateway.protoc_gen_swagger.options.Swagger")
- proto.RegisterMapType((map[string]*_struct.Value)(nil), "grpc.gateway.protoc_gen_swagger.options.Swagger.ExtensionsEntry")
- proto.RegisterMapType((map[string]*Response)(nil), "grpc.gateway.protoc_gen_swagger.options.Swagger.ResponsesEntry")
- proto.RegisterType((*Operation)(nil), "grpc.gateway.protoc_gen_swagger.options.Operation")
- proto.RegisterMapType((map[string]*_struct.Value)(nil), "grpc.gateway.protoc_gen_swagger.options.Operation.ExtensionsEntry")
- proto.RegisterMapType((map[string]*Response)(nil), "grpc.gateway.protoc_gen_swagger.options.Operation.ResponsesEntry")
- proto.RegisterType((*Response)(nil), "grpc.gateway.protoc_gen_swagger.options.Response")
- proto.RegisterMapType((map[string]*_struct.Value)(nil), "grpc.gateway.protoc_gen_swagger.options.Response.ExtensionsEntry")
- proto.RegisterType((*Info)(nil), "grpc.gateway.protoc_gen_swagger.options.Info")
- proto.RegisterMapType((map[string]*_struct.Value)(nil), "grpc.gateway.protoc_gen_swagger.options.Info.ExtensionsEntry")
- proto.RegisterType((*Contact)(nil), "grpc.gateway.protoc_gen_swagger.options.Contact")
- proto.RegisterType((*License)(nil), "grpc.gateway.protoc_gen_swagger.options.License")
- proto.RegisterType((*ExternalDocumentation)(nil), "grpc.gateway.protoc_gen_swagger.options.ExternalDocumentation")
- proto.RegisterType((*Schema)(nil), "grpc.gateway.protoc_gen_swagger.options.Schema")
- proto.RegisterType((*JSONSchema)(nil), "grpc.gateway.protoc_gen_swagger.options.JSONSchema")
- proto.RegisterType((*Tag)(nil), "grpc.gateway.protoc_gen_swagger.options.Tag")
- proto.RegisterType((*SecurityDefinitions)(nil), "grpc.gateway.protoc_gen_swagger.options.SecurityDefinitions")
- proto.RegisterMapType((map[string]*SecurityScheme)(nil), "grpc.gateway.protoc_gen_swagger.options.SecurityDefinitions.SecurityEntry")
- proto.RegisterType((*SecurityScheme)(nil), "grpc.gateway.protoc_gen_swagger.options.SecurityScheme")
- proto.RegisterMapType((map[string]*_struct.Value)(nil), "grpc.gateway.protoc_gen_swagger.options.SecurityScheme.ExtensionsEntry")
- proto.RegisterType((*SecurityRequirement)(nil), "grpc.gateway.protoc_gen_swagger.options.SecurityRequirement")
- proto.RegisterMapType((map[string]*SecurityRequirement_SecurityRequirementValue)(nil), "grpc.gateway.protoc_gen_swagger.options.SecurityRequirement.SecurityRequirementEntry")
- proto.RegisterType((*SecurityRequirement_SecurityRequirementValue)(nil), "grpc.gateway.protoc_gen_swagger.options.SecurityRequirement.SecurityRequirementValue")
- proto.RegisterType((*Scopes)(nil), "grpc.gateway.protoc_gen_swagger.options.Scopes")
- proto.RegisterMapType((map[string]string)(nil), "grpc.gateway.protoc_gen_swagger.options.Scopes.ScopeEntry")
-}
-
-func init() {
- proto.RegisterFile("protoc-gen-swagger/options/openapiv2.proto", fileDescriptor_ba35ad8af024fb48)
-}
-
-var fileDescriptor_ba35ad8af024fb48 = []byte{
- // 1884 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x58, 0x5b, 0x73, 0xdb, 0xc6,
- 0xf5, 0x0f, 0x48, 0x90, 0x04, 0x0f, 0x45, 0x7a, 0xbd, 0x96, 0xf3, 0x47, 0x18, 0xdb, 0x7f, 0x85,
- 0x4d, 0xa7, 0x1a, 0xbb, 0xa6, 0x12, 0xe5, 0xa1, 0x99, 0x4c, 0x6f, 0x94, 0xc4, 0xc8, 0x80, 0x65,
- 0x92, 0x05, 0xa9, 0x28, 0xee, 0x8c, 0x07, 0x85, 0xc0, 0x25, 0x85, 0x18, 0x17, 0x06, 0x17, 0x49,
- 0xec, 0x27, 0xe8, 0x73, 0xa7, 0xaf, 0xf9, 0x1e, 0x9d, 0x69, 0x9f, 0xfa, 0x09, 0xfa, 0x59, 0xda,
- 0xe9, 0x7b, 0x67, 0x2f, 0x20, 0x41, 0x91, 0xf1, 0x90, 0x72, 0x3c, 0x79, 0xe8, 0x13, 0xf7, 0xdc,
- 0x7e, 0xbb, 0x7b, 0xce, 0x9e, 0x0b, 0x08, 0x8f, 0x27, 0x61, 0x10, 0x07, 0xf6, 0xd3, 0x31, 0xf1,
- 0x9f, 0x46, 0x57, 0xd6, 0x78, 0x4c, 0xc2, 0xbd, 0x60, 0x12, 0x3b, 0x81, 0x1f, 0xed, 0x05, 0x13,
- 0xe2, 0x5b, 0x13, 0xe7, 0x72, 0xbf, 0xc9, 0x94, 0xf0, 0xcf, 0xc6, 0xe1, 0xc4, 0x6e, 0x8e, 0xad,
- 0x98, 0x5c, 0x59, 0x53, 0xce, 0xb3, 0xcd, 0x31, 0xf1, 0x4d, 0x61, 0xd8, 0x14, 0x86, 0xf5, 0x0f,
- 0xc6, 0x41, 0x30, 0x76, 0xc9, 0x1e, 0x53, 0x39, 0x4f, 0x46, 0x7b, 0x96, 0x2f, 0xf4, 0xeb, 0x0f,
- 0x6e, 0x8a, 0xa2, 0x38, 0x4c, 0xec, 0x98, 0x4b, 0x1b, 0x7f, 0x55, 0xa0, 0xd4, 0xe7, 0x60, 0x58,
- 0x85, 0x92, 0xc0, 0x55, 0xa5, 0x1d, 0x69, 0xb7, 0x6c, 0xa4, 0x24, 0x6e, 0x81, 0xec, 0xf8, 0xa3,
- 0x40, 0xcd, 0xed, 0x48, 0xbb, 0x95, 0xfd, 0xa7, 0xcd, 0x35, 0x8f, 0xd5, 0xd4, 0xfc, 0x51, 0x60,
- 0x30, 0x53, 0x8c, 0x41, 0xbe, 0x08, 0xa2, 0x58, 0xcd, 0x33, 0x64, 0xb6, 0xc6, 0x1f, 0x42, 0xf9,
- 0xdc, 0x8a, 0x88, 0x39, 0xb1, 0xe2, 0x0b, 0x55, 0x66, 0x02, 0x85, 0x32, 0x7a, 0x56, 0x7c, 0x81,
- 0xbf, 0x86, 0x52, 0x64, 0x5f, 0x10, 0x8f, 0x44, 0x6a, 0x61, 0x27, 0xbf, 0x5b, 0xdb, 0xff, 0xf5,
- 0xda, 0xdb, 0x8a, 0x0b, 0xa5, 0xbf, 0x7d, 0x06, 0x63, 0xa4, 0x70, 0xb8, 0x0e, 0x8a, 0x1d, 0xf8,
- 0x51, 0x42, 0xa1, 0x8b, 0x3b, 0x79, 0xba, 0x6b, 0x4a, 0x53, 0xd9, 0x24, 0x0c, 0x86, 0x89, 0x4d,
- 0x22, 0xb5, 0xc4, 0x65, 0x29, 0x8d, 0x5f, 0x41, 0x39, 0x24, 0xd1, 0x24, 0xf0, 0x23, 0x12, 0xa9,
- 0xb0, 0x93, 0xdf, 0xad, 0xec, 0xff, 0x66, 0xe3, 0x33, 0x19, 0x29, 0x42, 0xdb, 0x8f, 0xc3, 0xa9,
- 0x31, 0x47, 0xc4, 0x01, 0x6c, 0x47, 0xc4, 0x4e, 0x42, 0x27, 0x9e, 0x9a, 0x43, 0x32, 0x72, 0x7c,
- 0x87, 0x59, 0xaa, 0x15, 0xe6, 0xf4, 0x5f, 0xae, 0xbf, 0x93, 0x00, 0x39, 0x9a, 0x63, 0x18, 0xf7,
- 0xa2, 0x65, 0x26, 0xfe, 0x1a, 0x94, 0x94, 0xad, 0x6e, 0xb1, 0xeb, 0x6c, 0xbe, 0x89, 0x41, 0xbe,
- 0x4d, 0x9c, 0x90, 0x78, 0xc4, 0x8f, 0x8d, 0x19, 0x1a, 0xb6, 0xa1, 0x4a, 0xae, 0x63, 0x12, 0xfa,
- 0x96, 0x6b, 0x0e, 0x03, 0x3b, 0x52, 0x6b, 0xec, 0x0e, 0xeb, 0x47, 0xb0, 0x2d, 0xac, 0x8f, 0x02,
- 0x3b, 0xa1, 0xd8, 0x16, 0x65, 0x1b, 0x5b, 0x64, 0xce, 0x8e, 0xf0, 0x1f, 0x00, 0x28, 0xed, 0x47,
- 0xcc, 0x4b, 0x77, 0xd8, 0x05, 0x7e, 0xbb, 0x71, 0x3c, 0xda, 0x33, 0x08, 0x1e, 0x90, 0x0c, 0x66,
- 0x3d, 0x80, 0xda, 0x62, 0xb8, 0x30, 0x82, 0xfc, 0x6b, 0x32, 0x15, 0xe9, 0x41, 0x97, 0xf8, 0x18,
- 0x0a, 0x97, 0x96, 0x9b, 0x10, 0x91, 0x1b, 0x9f, 0xae, 0x7d, 0x80, 0x14, 0xd9, 0xe0, 0xf6, 0x5f,
- 0xe4, 0x3e, 0x97, 0xea, 0xa7, 0x70, 0xe7, 0xc6, 0x79, 0x56, 0xec, 0xf8, 0xf3, 0xc5, 0x1d, 0xdf,
- 0x6f, 0xf2, 0x04, 0x6f, 0xa6, 0x09, 0xde, 0xfc, 0x8a, 0x4a, 0x33, 0xb0, 0x8d, 0x03, 0xa8, 0x2e,
- 0xa4, 0x02, 0xae, 0x40, 0xe9, 0xb4, 0xf3, 0xbc, 0xd3, 0x3d, 0xeb, 0xa0, 0xf7, 0xb0, 0x02, 0xf2,
- 0xb3, 0xc1, 0xa0, 0x87, 0x24, 0x5c, 0x86, 0x02, 0x5d, 0xf5, 0x51, 0x0e, 0x17, 0x21, 0x77, 0xd6,
- 0x47, 0x79, 0x5c, 0x82, 0xfc, 0x59, 0xbf, 0x8f, 0x64, 0x5d, 0x56, 0x14, 0x54, 0xd6, 0x65, 0xa5,
- 0x8c, 0x40, 0x97, 0x95, 0x2a, 0xaa, 0x35, 0xfe, 0x51, 0x84, 0x72, 0x77, 0x42, 0x42, 0x16, 0x1b,
- 0x9a, 0xdf, 0xb1, 0x35, 0x8e, 0x54, 0x89, 0x25, 0x0d, 0x5b, 0xb3, 0x82, 0x92, 0x78, 0x9e, 0x15,
- 0x4e, 0xd9, 0x59, 0x69, 0x41, 0xe1, 0x24, 0xde, 0x81, 0xca, 0x90, 0x44, 0x76, 0xe8, 0x30, 0x67,
- 0x88, 0xa2, 0x90, 0x65, 0x2d, 0x3f, 0x21, 0xf9, 0x1d, 0x3c, 0xa1, 0x8f, 0x60, 0x2b, 0x48, 0x6f,
- 0x60, 0x3a, 0x43, 0xb5, 0xc0, 0xcf, 0x31, 0xe3, 0x69, 0xc3, 0x5b, 0x17, 0x0b, 0x33, 0x5b, 0x2c,
- 0xca, 0xec, 0x71, 0xb6, 0xd6, 0x3e, 0xfb, 0xcc, 0xad, 0x6f, 0x28, 0x17, 0xea, 0xbc, 0x3e, 0x02,
- 0xdb, 0x7b, 0x56, 0xdf, 0x1e, 0x01, 0x0c, 0xc9, 0x24, 0x24, 0xb6, 0x15, 0x93, 0x21, 0x2b, 0x1f,
- 0x8a, 0x91, 0xe1, 0xbc, 0xc3, 0xbc, 0x3f, 0x5f, 0x48, 0xc9, 0x2a, 0xc3, 0x3e, 0xb8, 0xc5, 0xad,
- 0xff, 0x07, 0x92, 0x92, 0x27, 0x54, 0xe3, 0x6f, 0x39, 0x50, 0xd2, 0x4d, 0x6f, 0x66, 0x85, 0xb4,
- 0x9c, 0x15, 0xc7, 0x50, 0x64, 0x51, 0xb6, 0xc4, 0x3e, 0x7b, 0xeb, 0x07, 0x8e, 0x99, 0x19, 0xc2,
- 0x1c, 0x5b, 0x0b, 0x91, 0x2a, 0x6c, 0xf8, 0x3e, 0xd3, 0x13, 0xbf, 0x31, 0x50, 0xef, 0xcc, 0x6f,
- 0x79, 0x56, 0x8e, 0x64, 0x54, 0x68, 0xfc, 0x33, 0x0f, 0x32, 0x9d, 0x31, 0xf0, 0x36, 0x14, 0x62,
- 0x27, 0x76, 0x89, 0x80, 0xe6, 0xc4, 0x4d, 0x7f, 0xe6, 0x96, 0xfd, 0xb9, 0x0b, 0x28, 0x26, 0xa1,
- 0x17, 0x99, 0xc1, 0xc8, 0x8c, 0x48, 0x78, 0xe9, 0xd8, 0x44, 0x14, 0xa3, 0x1a, 0xe3, 0x77, 0x47,
- 0x7d, 0xce, 0xc5, 0x3a, 0x94, 0xec, 0xc0, 0x8f, 0x2d, 0x3b, 0x16, 0x95, 0xe8, 0x93, 0xb5, 0xbd,
- 0x75, 0xc8, 0xed, 0x8c, 0x14, 0x80, 0x62, 0xb9, 0x8e, 0x4d, 0xfc, 0x88, 0xb0, 0x8a, 0xb3, 0x09,
- 0xd6, 0x09, 0xb7, 0x33, 0x52, 0x00, 0x5a, 0x06, 0x2e, 0x49, 0x48, 0x7d, 0xac, 0x16, 0x79, 0x8d,
- 0x15, 0x24, 0x7e, 0xb5, 0x10, 0xe2, 0x12, 0x0b, 0xf1, 0xaf, 0x36, 0x1a, 0xdd, 0x7e, 0x84, 0xf0,
- 0x36, 0xda, 0x50, 0x12, 0xfe, 0xa2, 0x2d, 0xc5, 0xb7, 0xbc, 0x34, 0xa6, 0x6c, 0x4d, 0xb7, 0x48,
- 0x42, 0x57, 0x84, 0x92, 0x2e, 0x69, 0xe8, 0x89, 0x67, 0x39, 0xae, 0x88, 0x1b, 0x27, 0x1a, 0x7b,
- 0x50, 0x12, 0xae, 0x5a, 0x0f, 0xa6, 0xf1, 0x1c, 0xee, 0xaf, 0xec, 0x18, 0x6b, 0x24, 0xe5, 0x32,
- 0xd8, 0xdf, 0x73, 0x50, 0xe4, 0x09, 0x87, 0x07, 0x50, 0xf9, 0x26, 0x0a, 0x7c, 0x53, 0xa4, 0xad,
- 0xc4, 0xfc, 0xf0, 0xd9, 0xda, 0x61, 0xd0, 0xfb, 0xdd, 0x8e, 0x48, 0x5d, 0xa0, 0x38, 0x02, 0xf5,
- 0x63, 0xa8, 0x0e, 0x1d, 0x7a, 0x02, 0xcf, 0xf1, 0xad, 0x38, 0x08, 0xc5, 0xe6, 0x8b, 0x4c, 0x3a,
- 0x5f, 0x87, 0xc4, 0x1a, 0x9a, 0x81, 0xef, 0x4e, 0x99, 0x7b, 0x14, 0x43, 0xa1, 0x8c, 0xae, 0xef,
- 0xae, 0x98, 0xd1, 0x0a, 0xef, 0xa0, 0xc1, 0x36, 0xa1, 0x44, 0xae, 0x2d, 0x6f, 0xe2, 0x12, 0xf6,
- 0x3a, 0x2b, 0xfb, 0xdb, 0x4b, 0x2f, 0xa0, 0xe5, 0x4f, 0x8d, 0x54, 0x49, 0xa4, 0xf5, 0x77, 0x25,
- 0x80, 0xf9, 0xc5, 0xa9, 0x7f, 0x43, 0x32, 0x12, 0xf1, 0xa5, 0xcb, 0x79, 0xba, 0x17, 0xde, 0x90,
- 0xee, 0xc5, 0xe5, 0x48, 0xa9, 0x50, 0x1a, 0x92, 0x91, 0x95, 0xb8, 0xb1, 0x5a, 0xe2, 0xc9, 0x22,
- 0xc8, 0x45, 0x57, 0x29, 0x37, 0x5c, 0xf5, 0xff, 0x50, 0xf1, 0x12, 0x37, 0x76, 0x26, 0x2e, 0x31,
- 0x83, 0x91, 0x0a, 0x3b, 0xd2, 0xae, 0x64, 0x40, 0xca, 0xea, 0x8e, 0x28, 0xae, 0x67, 0x5d, 0x3b,
- 0x5e, 0xe2, 0xb1, 0x76, 0x2b, 0x19, 0x29, 0x89, 0x9f, 0xc0, 0x5d, 0x72, 0x6d, 0xbb, 0x49, 0xe4,
- 0x5c, 0x12, 0x33, 0xd5, 0xd9, 0x62, 0xf8, 0x68, 0x26, 0x78, 0x21, 0x94, 0x29, 0x8c, 0xe3, 0x33,
- 0x95, 0xaa, 0x80, 0xe1, 0xe4, 0x0d, 0x18, 0xa1, 0x53, 0xbb, 0x09, 0x23, 0x94, 0x1f, 0x02, 0x78,
- 0xd6, 0xb5, 0xe9, 0x12, 0x7f, 0x1c, 0x5f, 0xa8, 0x77, 0x76, 0xa4, 0x5d, 0xd9, 0x28, 0x7b, 0xd6,
- 0xf5, 0x09, 0x63, 0x30, 0xb1, 0xe3, 0xa7, 0x62, 0x24, 0xc4, 0x8e, 0x2f, 0xc4, 0x2a, 0x94, 0x26,
- 0x56, 0x4c, 0x63, 0xa8, 0xde, 0xe5, 0x3e, 0x12, 0x24, 0xf5, 0x11, 0xc5, 0x75, 0x62, 0xe2, 0x45,
- 0xea, 0x36, 0xb3, 0x53, 0x3c, 0xeb, 0x5a, 0xa3, 0x34, 0x13, 0x3a, 0xbe, 0x10, 0xde, 0x17, 0x42,
- 0xc7, 0xe7, 0xc2, 0x8f, 0x60, 0x2b, 0xf1, 0x9d, 0x6f, 0x13, 0x22, 0xe4, 0xef, 0xb3, 0x93, 0x57,
- 0x38, 0x8f, 0xab, 0xfc, 0x14, 0x6a, 0x14, 0x7c, 0x12, 0xd2, 0xe1, 0x2b, 0x76, 0x48, 0xa4, 0xaa,
- 0x0c, 0xa4, 0xea, 0x59, 0xd7, 0xbd, 0x19, 0x93, 0xa9, 0x39, 0x7e, 0x56, 0xed, 0x03, 0xa1, 0xe6,
- 0xf8, 0x19, 0xb5, 0x3a, 0x28, 0x21, 0x9f, 0x50, 0x86, 0x6a, 0x9d, 0x4f, 0x66, 0x29, 0x4d, 0x1f,
- 0x8f, 0x15, 0x86, 0xd6, 0x54, 0x6d, 0x30, 0x01, 0x27, 0xf0, 0x2b, 0x90, 0xe3, 0xe9, 0x84, 0xa8,
- 0x3f, 0x61, 0xdf, 0x9a, 0xda, 0x2d, 0x12, 0x34, 0xb3, 0xec, 0x3b, 0xf4, 0x35, 0x0f, 0xa6, 0x13,
- 0x12, 0x19, 0x0c, 0xb6, 0x71, 0x05, 0xf7, 0x57, 0x8a, 0x17, 0x47, 0xf1, 0x32, 0x14, 0x5a, 0x86,
- 0xd1, 0x7a, 0x89, 0x24, 0xca, 0x3f, 0xe8, 0x76, 0x4f, 0xda, 0xad, 0x0e, 0xca, 0x51, 0x42, 0xeb,
- 0x0c, 0xda, 0xc7, 0x6d, 0x03, 0xe5, 0xe9, 0xbc, 0xde, 0x39, 0x3d, 0x39, 0x41, 0x32, 0x06, 0x28,
- 0x76, 0x4e, 0x5f, 0x1c, 0xb4, 0x0d, 0x54, 0xa0, 0xeb, 0xee, 0x81, 0xde, 0x3e, 0x1c, 0xa0, 0x22,
- 0x5d, 0xf7, 0x07, 0x86, 0xd6, 0x39, 0x46, 0x25, 0x5d, 0x56, 0x24, 0x94, 0xd3, 0x65, 0x25, 0x87,
- 0xf2, 0x3c, 0xbb, 0x66, 0x33, 0x3c, 0x46, 0xf7, 0x74, 0x59, 0xb9, 0x87, 0xb6, 0x75, 0x59, 0xf9,
- 0x3f, 0xa4, 0xea, 0xb2, 0xf2, 0x21, 0x7a, 0xa0, 0xcb, 0xca, 0x03, 0xf4, 0x50, 0x97, 0x95, 0x87,
- 0xe8, 0x91, 0x2e, 0x2b, 0x8f, 0x50, 0x43, 0x97, 0x95, 0x8f, 0xd1, 0x63, 0x5d, 0x56, 0x1e, 0xa3,
- 0x27, 0xba, 0xac, 0x3c, 0x41, 0xcd, 0xc6, 0x9f, 0x25, 0xc8, 0x0f, 0xac, 0xf1, 0x1a, 0xfd, 0x75,
- 0xa9, 0xc8, 0xe4, 0x7f, 0xf8, 0x22, 0xc3, 0xaf, 0xd8, 0xf8, 0xb7, 0x04, 0xf7, 0x56, 0x7c, 0xfa,
- 0xe2, 0x51, 0x66, 0xda, 0x95, 0x58, 0x13, 0xd4, 0xdf, 0xe6, 0x53, 0x7a, 0xc6, 0xe3, 0x1d, 0x71,
- 0x86, 0x5d, 0x8f, 0xa1, 0xba, 0x20, 0x5a, 0xd1, 0x0d, 0x5f, 0x2c, 0x76, 0xc3, 0x5f, 0x6c, 0x7c,
- 0x0e, 0xf1, 0x4f, 0x46, 0xa6, 0x5d, 0xfe, 0xa7, 0x08, 0xb5, 0x45, 0x29, 0xee, 0x89, 0x97, 0x4c,
- 0x37, 0xae, 0xdd, 0x62, 0xb4, 0xe7, 0x30, 0x4d, 0xfa, 0x3c, 0xf9, 0xe3, 0x5d, 0x23, 0xce, 0x69,
- 0x8f, 0xcd, 0x67, 0x7a, 0xac, 0x0e, 0x39, 0xc7, 0x67, 0xc3, 0x52, 0x6d, 0xff, 0x8b, 0xdb, 0x9e,
- 0x42, 0xf3, 0x8d, 0x9c, 0xe3, 0xd3, 0x3b, 0x8d, 0xdc, 0xe0, 0x8a, 0xd5, 0xfb, 0xb7, 0xb8, 0xd3,
- 0x97, 0x6e, 0x70, 0x65, 0x30, 0x24, 0x5a, 0x51, 0xad, 0x24, 0xbe, 0x08, 0x42, 0xe7, 0x8f, 0xfc,
- 0xf3, 0x8f, 0xb6, 0x70, 0xde, 0x32, 0xd0, 0x82, 0xe0, 0x34, 0x74, 0x69, 0x71, 0x8b, 0x83, 0xd7,
- 0x84, 0x2b, 0xf1, 0xce, 0xa1, 0x30, 0x06, 0x15, 0xb2, 0x99, 0x3c, 0x98, 0x90, 0x88, 0xf5, 0x8d,
- 0xcd, 0x66, 0x72, 0x6a, 0x66, 0x08, 0x73, 0x3c, 0x5e, 0x18, 0xd8, 0xf8, 0x37, 0xe3, 0xf1, 0x6d,
- 0xaf, 0xfa, 0x23, 0x8c, 0x6e, 0xcf, 0x41, 0xa6, 0x8f, 0x06, 0x23, 0xd8, 0x1a, 0xbc, 0xec, 0xb5,
- 0x4d, 0xad, 0xf3, 0x55, 0xeb, 0x44, 0x3b, 0x42, 0xef, 0xe1, 0x1a, 0x00, 0xe3, 0x1c, 0xb4, 0xfa,
- 0xda, 0x21, 0x92, 0x66, 0x1a, 0xad, 0x9e, 0x66, 0x3e, 0x6f, 0xbf, 0x44, 0x39, 0x7c, 0x07, 0x2a,
- 0x8c, 0xd3, 0x6d, 0x9d, 0x0e, 0x9e, 0xed, 0xa3, 0x7c, 0xe3, 0x53, 0xc8, 0x69, 0x3e, 0x35, 0xd4,
- 0x3a, 0x19, 0xa0, 0x2d, 0x50, 0xb4, 0x8e, 0xf9, 0xbb, 0xd3, 0xb6, 0x41, 0x6b, 0x64, 0x15, 0xca,
- 0x5a, 0xc7, 0x7c, 0xd6, 0x6e, 0x1d, 0xb5, 0x0d, 0x94, 0x6b, 0x7c, 0x03, 0x32, 0x0d, 0x30, 0x45,
- 0xff, 0xf2, 0xa4, 0x7b, 0x96, 0x31, 0xbb, 0x0b, 0x55, 0xce, 0x79, 0xd1, 0x3b, 0xd1, 0x0e, 0xb5,
- 0x01, 0x92, 0x66, 0xac, 0x5e, 0xab, 0xdf, 0x3f, 0xeb, 0x1a, 0x47, 0x28, 0x87, 0xb7, 0x01, 0x31,
- 0x56, 0xab, 0x47, 0xb5, 0x5a, 0x03, 0xad, 0xdb, 0x41, 0xf9, 0x39, 0xf7, 0xf0, 0xb0, 0xdd, 0xef,
- 0x9b, 0x87, 0xdd, 0xa3, 0x36, 0x92, 0x1b, 0xff, 0xca, 0xcd, 0xab, 0x4d, 0xe6, 0x5b, 0x18, 0xff,
- 0x49, 0xca, 0xfc, 0x8b, 0x17, 0xce, 0x05, 0xa2, 0xf4, 0x9c, 0xbe, 0xcd, 0x87, 0xf6, 0x2a, 0x1e,
- 0x0f, 0xee, 0xec, 0xef, 0xbd, 0x8c, 0xa4, 0xfe, 0x09, 0xa8, 0x2b, 0x0c, 0x58, 0xd4, 0x68, 0x0f,
- 0x64, 0x8f, 0x4e, 0xfc, 0x5d, 0xc3, 0x89, 0xfa, 0x77, 0xd2, 0x4a, 0x93, 0xef, 0x7b, 0x21, 0xaf,
- 0x17, 0x5f, 0xc8, 0x0f, 0x7e, 0xb7, 0xa5, 0x07, 0xf6, 0x17, 0x89, 0x8e, 0xd5, 0x2c, 0x57, 0x7a,
- 0xd9, 0x0b, 0x54, 0x36, 0xa9, 0x2f, 0xcc, 0x9e, 0xff, 0x70, 0xe7, 0x89, 0xcb, 0x7f, 0x0e, 0x30,
- 0x67, 0xae, 0xb8, 0xed, 0x76, 0xf6, 0xb6, 0xe5, 0xcc, 0xb1, 0x0e, 0x0e, 0x7f, 0xdf, 0x1a, 0x3b,
- 0xf1, 0x45, 0x72, 0xde, 0xb4, 0x03, 0x6f, 0x8f, 0x1e, 0xe4, 0x29, 0xb1, 0x83, 0x68, 0x1a, 0xc5,
- 0x44, 0x90, 0xe2, 0x5c, 0x7b, 0xdf, 0xff, 0xd7, 0xff, 0x79, 0x91, 0xc9, 0x3e, 0xfb, 0x6f, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x29, 0x5a, 0xd3, 0x93, 0x1f, 0x18, 0x00, 0x00,
-}
diff --git a/gateway/protoc-gen-swagger/options/openapiv2.proto b/gateway/protoc-gen-swagger/options/openapiv2.proto
deleted file mode 100644
index 8b49024..0000000
--- a/gateway/protoc-gen-swagger/options/openapiv2.proto
+++ /dev/null
@@ -1,379 +0,0 @@
-syntax = "proto3";
-
-package grpc.gateway.protoc_gen_swagger.options;
-
-option go_package = "github.com/binchencoder/ease-gateway/gateway/protoc-gen-swagger/options";
-
-import "google/protobuf/any.proto";
-import "google/protobuf/struct.proto";
-
-// `Swagger` is a representation of OpenAPI v2 specification's Swagger object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#swaggerObject
-//
-// TODO(ivucica): document fields
-message Swagger {
- string swagger = 1;
- Info info = 2;
- string host = 3;
- // `base_path` is the common prefix path used on all API endpoints (ie. /api, /v1, etc.). By adding this,
- // it allows you to remove this portion from the path endpoints in your Swagger file making them easier
- // to read. Note that using `base_path` does not change the endpoint paths that are generated in the resulting
- // Swagger file. If you wish to use `base_path` with relatively generated Swagger paths, the
- // `base_path` prefix must be manually removed from your `google.api.http` paths and your code changed to
- // serve the API from the `base_path`.
- string base_path = 4;
- enum SwaggerScheme {
- UNKNOWN = 0;
- HTTP = 1;
- HTTPS = 2;
- WS = 3;
- WSS = 4;
- }
- repeated SwaggerScheme schemes = 5;
- repeated string consumes = 6;
- repeated string produces = 7;
- // field 8 is reserved for 'paths'.
- reserved 8;
- // field 9 is reserved for 'definitions', which at this time are already
- // exposed as and customizable as proto messages.
- reserved 9;
- map responses = 10;
- SecurityDefinitions security_definitions = 11;
- repeated SecurityRequirement security = 12;
- // field 13 is reserved for 'tags', which are supposed to be exposed as and
- // customizable as proto services. TODO(ivucica): add processing of proto
- // service objects into OpenAPI v2 Tag objects.
- reserved 13;
- ExternalDocumentation external_docs = 14;
- map extensions = 15;
-}
-
-// `Operation` is a representation of OpenAPI v2 specification's Operation object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#operationObject
-//
-// TODO(ivucica): document fields
-message Operation {
- repeated string tags = 1;
- string summary = 2;
- string description = 3;
- ExternalDocumentation external_docs = 4;
- string operation_id = 5;
- repeated string consumes = 6;
- repeated string produces = 7;
- // field 8 is reserved for 'parameters'.
- reserved 8;
- map responses = 9;
- repeated string schemes = 10;
- bool deprecated = 11;
- repeated SecurityRequirement security = 12;
- map extensions = 13;
-}
-
-// `Response` is a representation of OpenAPI v2 specification's Response object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#responseObject
-//
-message Response {
- // `Description` is a short description of the response.
- // GFM syntax can be used for rich text representation.
- string description = 1;
- // `Schema` optionally defines the structure of the response.
- // If `Schema` is not provided, it means there is no content to the response.
- Schema schema = 2;
- // field 3 is reserved for 'headers'.
- reserved 3;
- // field 3 is reserved for 'example'.
- reserved 4;
- map extensions = 5;
-}
-
-// `Info` is a representation of OpenAPI v2 specification's Info object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#infoObject
-//
-// TODO(ivucica): document fields
-message Info {
- string title = 1;
- string description = 2;
- string terms_of_service = 3;
- Contact contact = 4;
- License license = 5;
- string version = 6;
- map extensions = 7;
-}
-
-// `Contact` is a representation of OpenAPI v2 specification's Contact object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#contactObject
-//
-// TODO(ivucica): document fields
-message Contact {
- string name = 1;
- string url = 2;
- string email = 3;
-}
-
-// `License` is a representation of OpenAPI v2 specification's License object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#licenseObject
-//
-message License {
- // Required. The license name used for the API.
- string name = 1;
- // A URL to the license used for the API.
- string url = 2;
-}
-
-// `ExternalDocumentation` is a representation of OpenAPI v2 specification's
-// ExternalDocumentation object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#externalDocumentationObject
-//
-// TODO(ivucica): document fields
-message ExternalDocumentation {
- string description = 1;
- string url = 2;
-}
-
-// `Schema` is a representation of OpenAPI v2 specification's Schema object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#schemaObject
-//
-// TODO(ivucica): document fields
-message Schema {
- JSONSchema json_schema = 1;
- string discriminator = 2;
- bool read_only = 3;
- // field 4 is reserved for 'xml'.
- reserved 4;
- ExternalDocumentation external_docs = 5;
- google.protobuf.Any example = 6;
-}
-
-// `JSONSchema` represents properties from JSON Schema taken, and as used, in
-// the OpenAPI v2 spec.
-//
-// This includes changes made by OpenAPI v2.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#schemaObject
-//
-// See also: https://cswr.github.io/JsonSchema/spec/basic_types/,
-// https://github.com/json-schema-org/json-schema-spec/blob/master/schema.json
-//
-// TODO(ivucica): document fields
-message JSONSchema {
- // field 1 is reserved for '$id', omitted from OpenAPI v2.
- reserved 1;
- // field 2 is reserved for '$schema', omitted from OpenAPI v2.
- reserved 2;
- // Ref is used to define an external reference to include in the message.
- // This could be a fully qualified proto message reference, and that type must be imported
- // into the protofile. If no message is identified, the Ref will be used verbatim in
- // the output.
- // For example:
- // `ref: ".google.protobuf.Timestamp"`.
- string ref = 3;
- // field 4 is reserved for '$comment', omitted from OpenAPI v2.
- reserved 4;
- string title = 5;
- string description = 6;
- string default = 7;
- bool read_only = 8;
- // field 9 is reserved for 'examples', which is omitted from OpenAPI v2 in favor of 'example' field.
- reserved 9;
- double multiple_of = 10;
- double maximum = 11;
- bool exclusive_maximum = 12;
- double minimum = 13;
- bool exclusive_minimum = 14;
- uint64 max_length = 15;
- uint64 min_length = 16;
- string pattern = 17;
- // field 18 is reserved for 'additionalItems', omitted from OpenAPI v2.
- reserved 18;
- // field 19 is reserved for 'items', but in OpenAPI-specific way. TODO(ivucica): add 'items'?
- reserved 19;
- uint64 max_items = 20;
- uint64 min_items = 21;
- bool unique_items = 22;
- // field 23 is reserved for 'contains', omitted from OpenAPI v2.
- reserved 23;
- uint64 max_properties = 24;
- uint64 min_properties = 25;
- repeated string required = 26;
- // field 27 is reserved for 'additionalProperties', but in OpenAPI-specific way. TODO(ivucica): add 'additionalProperties'?
- reserved 27;
- // field 28 is reserved for 'definitions', omitted from OpenAPI v2.
- reserved 28;
- // field 29 is reserved for 'properties', but in OpenAPI-specific way. TODO(ivucica): add 'additionalProperties'?
- reserved 29;
- // following fields are reserved, as the properties have been omitted from OpenAPI v2:
- // patternProperties, dependencies, propertyNames, const
- reserved 30 to 33;
- // Items in 'array' must be unique.
- repeated string array = 34;
-
- enum JSONSchemaSimpleTypes {
- UNKNOWN = 0;
- ARRAY = 1;
- BOOLEAN = 2;
- INTEGER = 3;
- NULL = 4;
- NUMBER = 5;
- OBJECT = 6;
- STRING = 7;
- }
-
- repeated JSONSchemaSimpleTypes type = 35;
- // following fields are reserved, as the properties have been omitted from OpenAPI v2:
- // format, contentMediaType, contentEncoding, if, then, else
- reserved 36 to 41;
- // field 42 is reserved for 'allOf', but in OpenAPI-specific way. TODO(ivucica): add 'allOf'?
- reserved 42;
- // following fields are reserved, as the properties have been omitted from OpenAPI v2:
- // anyOf, oneOf, not
- reserved 43 to 45;
-}
-
-// `Tag` is a representation of OpenAPI v2 specification's Tag object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#tagObject
-//
-// TODO(ivucica): document fields
-message Tag {
- // field 1 is reserved for 'name'. In our generator, this is (to be) extracted
- // from the name of proto service, and thus not exposed to the user, as
- // changing tag object's name would break the link to the references to the
- // tag in individual operation specifications.
- //
- // TODO(ivucica): Add 'name' property. Use it to allow override of the name of
- // global Tag object, then use that name to reference the tag throughout the
- // Swagger file.
- reserved 1;
- // TODO(ivucica): Description should be extracted from comments on the proto
- // service object.
- string description = 2;
- ExternalDocumentation external_docs = 3;
-}
-
-// `SecurityDefinitions` is a representation of OpenAPI v2 specification's
-// Security Definitions object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securityDefinitionsObject
-//
-// A declaration of the security schemes available to be used in the
-// specification. This does not enforce the security schemes on the operations
-// and only serves to provide the relevant details for each scheme.
-message SecurityDefinitions {
- // A single security scheme definition, mapping a "name" to the scheme it defines.
- map security = 1;
-}
-
-// `SecurityScheme` is a representation of OpenAPI v2 specification's
-// Security Scheme object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securitySchemeObject
-//
-// Allows the definition of a security scheme that can be used by the
-// operations. Supported schemes are basic authentication, an API key (either as
-// a header or as a query parameter) and OAuth2's common flows (implicit,
-// password, application and access code).
-message SecurityScheme {
- // Required. The type of the security scheme. Valid values are "basic",
- // "apiKey" or "oauth2".
- enum Type {
- TYPE_INVALID = 0;
- TYPE_BASIC = 1;
- TYPE_API_KEY = 2;
- TYPE_OAUTH2 = 3;
- }
-
- // Required. The location of the API key. Valid values are "query" or "header".
- enum In {
- IN_INVALID = 0;
- IN_QUERY = 1;
- IN_HEADER = 2;
- }
-
- // Required. The flow used by the OAuth2 security scheme. Valid values are
- // "implicit", "password", "application" or "accessCode".
- enum Flow {
- FLOW_INVALID = 0;
- FLOW_IMPLICIT = 1;
- FLOW_PASSWORD = 2;
- FLOW_APPLICATION = 3;
- FLOW_ACCESS_CODE = 4;
- }
-
- // Required. The type of the security scheme. Valid values are "basic",
- // "apiKey" or "oauth2".
- Type type = 1;
- // A short description for security scheme.
- string description = 2;
- // Required. The name of the header or query parameter to be used.
- //
- // Valid for apiKey.
- string name = 3;
- // Required. The location of the API key. Valid values are "query" or "header".
- //
- // Valid for apiKey.
- In in = 4;
- // Required. The flow used by the OAuth2 security scheme. Valid values are
- // "implicit", "password", "application" or "accessCode".
- //
- // Valid for oauth2.
- Flow flow = 5;
- // Required. The authorization URL to be used for this flow. This SHOULD be in
- // the form of a URL.
- //
- // Valid for oauth2/implicit and oauth2/accessCode.
- string authorization_url = 6;
- // Required. The token URL to be used for this flow. This SHOULD be in the
- // form of a URL.
- //
- // Valid for oauth2/password, oauth2/application and oauth2/accessCode.
- string token_url = 7;
- // Required. The available scopes for the OAuth2 security scheme.
- //
- // Valid for oauth2.
- Scopes scopes = 8;
- map extensions = 9;
-}
-
-// `SecurityRequirement` is a representation of OpenAPI v2 specification's
-// Security Requirement object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securityRequirementObject
-//
-// Lists the required security schemes to execute this operation. The object can
-// have multiple security schemes declared in it which are all required (that
-// is, there is a logical AND between the schemes).
-//
-// The name used for each property MUST correspond to a security scheme
-// declared in the Security Definitions.
-message SecurityRequirement {
- // If the security scheme is of type "oauth2", then the value is a list of
- // scope names required for the execution. For other security scheme types,
- // the array MUST be empty.
- message SecurityRequirementValue {
- repeated string scope = 1;
- }
- // Each name must correspond to a security scheme which is declared in
- // the Security Definitions. If the security scheme is of type "oauth2",
- // then the value is a list of scope names required for the execution.
- // For other security scheme types, the array MUST be empty.
- map security_requirement = 1;
-}
-
-// `Scopes` is a representation of OpenAPI v2 specification's Scopes object.
-//
-// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#scopesObject
-//
-// Lists the available scopes for an OAuth2 security scheme.
-message Scopes {
- // Maps between a name of a scope to a short description of it (as the value
- // of the property).
- map scope = 1;
-}
diff --git a/gateway/runtime/BUILD.bazel b/gateway/runtime/BUILD.bazel
index 632174a..8365d14 100644
--- a/gateway/runtime/BUILD.bazel
+++ b/gateway/runtime/BUILD.bazel
@@ -3,82 +3,90 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
package(default_visibility = ["//visibility:public"])
go_library(
- name = "go_default_library",
+ name = "runtime",
srcs = glob(
["*.go"],
exclude = ["*_test.go"],
),
- importpath = "github.com/binchencoder/ease-gateway/gateway/runtime",
- visibility = ["//visibility:public"],
+ importpath = "github.com/binchencoder/janus-gateway/gateway/runtime",
deps = [
- "//httpoptions:go_default_library",
+ "@com_github_grpc_ecosystem_grpc_gateway//internal/httprule",
+ "@com_github_grpc_ecosystem_grpc_gateway//utilities",
+ "//gateway/internal:go_default_library",
+ "//httpoptions",
"@com_github_binchencoder_gateway_proto//data:go_default_library",
"@com_github_binchencoder_gateway_proto//frontend:go_default_library",
"@com_github_binchencoder_letsgo//grpc:go_default_library",
"@com_github_binchencoder_letsgo//hashring:go_default_library",
"@com_github_binchencoder_skylb_api//proto:go_default_library",
- "@com_github_golang_protobuf//descriptor:go_default_library_gen",
- "@com_github_golang_protobuf//jsonpb:go_default_library_gen",
- "@com_github_golang_protobuf//proto:go_default_library",
- "@com_github_grpc_ecosystem_grpc_gateway//internal:go_default_library",
- "@com_github_grpc_ecosystem_grpc_gateway//utilities:go_default_library",
+ "@com_github_golang_protobuf//ptypes:go_default_library_gen",
"@com_github_pborman_uuid//:go_default_library",
+ "@com_github_golang_protobuf//jsonpb:go_default_library_gen",
"@go_googleapis//google/api:httpbody_go_proto",
- "@io_bazel_rules_go//proto/wkt:any_go_proto",
- "@io_bazel_rules_go//proto/wkt:descriptor_go_proto",
- "@io_bazel_rules_go//proto/wkt:duration_go_proto",
"@io_bazel_rules_go//proto/wkt:field_mask_go_proto",
- "@io_bazel_rules_go//proto/wkt:timestamp_go_proto",
- "@io_bazel_rules_go//proto/wkt:wrappers_go_proto",
- "@org_golang_google_grpc//codes:go_default_library",
- "@org_golang_google_grpc//grpclog:go_default_library",
- "@org_golang_google_grpc//metadata:go_default_library",
- "@org_golang_google_grpc//status:go_default_library",
- "@org_golang_google_grpc//:go_default_library",
+ "@org_golang_google_grpc//:go_default_library",
+ "@org_golang_google_grpc//codes",
+ "@org_golang_google_grpc//grpclog",
+ "@org_golang_google_grpc//health/grpc_health_v1",
+ "@org_golang_google_grpc//metadata",
+ "@org_golang_google_grpc//status",
+ "@org_golang_google_protobuf//encoding/protojson",
+ "@org_golang_google_protobuf//proto",
+ "@org_golang_google_protobuf//reflect/protoreflect",
+ "@org_golang_google_protobuf//reflect/protoregistry",
+ "@org_golang_google_protobuf//types/known/durationpb",
+ "@org_golang_google_protobuf//types/known/timestamppb",
+ "@org_golang_google_protobuf//types/known/wrapperspb",
"@org_golang_x_net//context:go_default_library",
],
)
go_test(
- name = "go_default_test",
+ name = "runtime_test",
size = "small",
srcs = [
"balancer_test.go",
"context_test.go",
"errors_test.go",
- "fieldmask_test.go",
"handler_test.go",
"hook_test.go",
"marshal_httpbodyproto_test.go",
"marshaler_registry_test.go",
"mux_test.go",
- "pattern_test.go",
- "query_test.go",
- ],
- embed = [
- ":go_default_library",
],
+ embed = [":runtime"],
deps = [
- "//examples/proto:go_default_library",
- "//httpoptions:go_default_library",
+ "//examples/internal/proto/examplepb",
+ "//gateway/internal:go_default_library",
+ "//gateway/runtime/internal/examplepb",
+ "@com_github_grpc_ecosystem_grpc_gateway//utilities",
+ "//httpoptions",
"@com_github_binchencoder_letsgo//hashring:go_default_library",
"@com_github_binchencoder_skylb_api//proto:go_default_library",
- "@com_github_golang_protobuf//proto:go_default_library",
- "@com_github_golang_protobuf//ptypes:go_default_library_gen",
- "@com_github_grpc_ecosystem_grpc_gateway//internal:go_default_library",
- "@com_github_grpc_ecosystem_grpc_gateway//utilities:go_default_library",
+ "@com_github_google_go_cmp//cmp",
+ "@com_github_google_go_cmp//cmp/cmpopts",
"@go_googleapis//google/api:httpbody_go_proto",
"@go_googleapis//google/rpc:errdetails_go_proto",
- "@io_bazel_rules_go//proto/wkt:duration_go_proto",
- "@io_bazel_rules_go//proto/wkt:empty_go_proto",
+ "@go_googleapis//google/rpc:status_go_proto",
"@io_bazel_rules_go//proto/wkt:field_mask_go_proto",
- "@io_bazel_rules_go//proto/wkt:struct_go_proto",
- "@io_bazel_rules_go//proto/wkt:timestamp_go_proto",
- "@io_bazel_rules_go//proto/wkt:wrappers_go_proto",
"@org_golang_google_grpc//:go_default_library",
- "@org_golang_google_grpc//codes:go_default_library",
- "@org_golang_google_grpc//metadata:go_default_library",
- "@org_golang_google_grpc//status:go_default_library",
- "@org_golang_x_net//context:go_default_library",
+ "@org_golang_google_grpc//codes",
+ "@org_golang_google_grpc//health/grpc_health_v1",
+ "@org_golang_google_grpc//metadata",
+ "@org_golang_google_grpc//status",
+ "@org_golang_google_protobuf//encoding/protojson",
+ "@org_golang_google_protobuf//proto",
+ "@org_golang_google_protobuf//testing/protocmp",
+ "@org_golang_google_protobuf//types/known/durationpb",
+ "@org_golang_google_protobuf//types/known/emptypb",
+ "@org_golang_google_protobuf//types/known/structpb",
+ "@org_golang_google_protobuf//types/known/timestamppb",
+ "@org_golang_google_protobuf//types/known/wrapperspb",
],
)
+
+alias(
+ name = "go_default_library",
+ actual = ":runtime",
+ visibility = ["//visibility:public"],
+)
diff --git a/gateway/runtime/balancer.go b/gateway/runtime/balancer.go
index 29bf5de..bef183d 100644
--- a/gateway/runtime/balancer.go
+++ b/gateway/runtime/balancer.go
@@ -2,15 +2,11 @@ package runtime
import (
"context"
- "fmt"
- "reflect"
- "strings"
- "github.com/golang/protobuf/proto"
"github.com/pborman/uuid"
- "google.golang.org/grpc/grpclog"
+ "google.golang.org/protobuf/proto"
- options "github.com/binchencoder/ease-gateway/httpoptions"
+ options "github.com/binchencoder/janus-gateway/httpoptions"
"github.com/binchencoder/letsgo/grpc"
"github.com/binchencoder/letsgo/hashring"
)
@@ -37,7 +33,8 @@ func PreLoadBalance(ctx context.Context, balancer, hashHeyType string, req proto
return ctx
} else {
// Hash key is a proto field.
- hashKey := fmt.Sprintf("%v", getProtoFiledValue(req, hashHeyType))
+ // hashKey := fmt.Sprintf("%v", getProtoFiledValue(req, hashHeyType))
+ hashKey := ""
ctx = hashring.WithHashKey(ctx, hashKey)
}
}
@@ -45,37 +42,37 @@ func PreLoadBalance(ctx context.Context, balancer, hashHeyType string, req proto
return ctx
}
-func getProtoFiledValue(msg proto.Message, fieldPathStr string) reflect.Value {
- fieldPath := strings.Split(fieldPathStr, ".")
- v := reflect.ValueOf(msg).Elem()
- for _, fieldName := range fieldPath {
- f, _, err := fieldByProtoName(v, fieldName)
- if err != nil {
- grpclog.Printf("field not found in %T: %s, %v", msg, strings.Join(fieldPath, "."), err)
- return reflect.Value{}
- }
- if !f.IsValid() {
- grpclog.Printf("field not found in %T: %s", msg, strings.Join(fieldPath, "."))
- return reflect.Value{}
- }
+// func getProtoFiledValue(msg proto.Message, fieldPathStr string) reflect.Value {
+// fieldPath := strings.Split(fieldPathStr, ".")
+// v := reflect.ValueOf(msg).Elem()
+// for _, fieldName := range fieldPath {
+// f, _, err := fieldByProtoName(v, fieldName)
+// if err != nil {
+// grpclog.Printf("field not found in %T: %s, %v", msg, strings.Join(fieldPath, "."), err)
+// return reflect.Value{}
+// }
+// if !f.IsValid() {
+// grpclog.Printf("field not found in %T: %s", msg, strings.Join(fieldPath, "."))
+// return reflect.Value{}
+// }
- switch f.Kind() {
- case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, reflect.String, reflect.Uint32, reflect.Uint64:
- v = f
- case reflect.Ptr:
- if f.IsNil() {
- grpclog.Printf("field is nil in %T: %s", msg, strings.Join(fieldPath, "."))
- return reflect.Value{}
- }
- v = f.Elem()
- continue
- case reflect.Struct:
- v = f
- continue
- default:
- grpclog.Printf("unexpected type %s in %T", f.Type(), msg)
- return reflect.Value{}
- }
- }
- return v
-}
+// switch f.Kind() {
+// case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, reflect.String, reflect.Uint32, reflect.Uint64:
+// v = f
+// case reflect.Ptr:
+// if f.IsNil() {
+// grpclog.Printf("field is nil in %T: %s", msg, strings.Join(fieldPath, "."))
+// return reflect.Value{}
+// }
+// v = f.Elem()
+// continue
+// case reflect.Struct:
+// v = f
+// continue
+// default:
+// grpclog.Printf("unexpected type %s in %T", f.Type(), msg)
+// return reflect.Value{}
+// }
+// }
+// return v
+// }
diff --git a/gateway/runtime/balancer_test.go b/gateway/runtime/balancer_test.go
index 8b6e4f9..462e64d 100644
--- a/gateway/runtime/balancer_test.go
+++ b/gateway/runtime/balancer_test.go
@@ -4,84 +4,54 @@ import (
"context"
"testing"
- "github.com/golang/protobuf/proto"
+ pb "github.com/binchencoder/janus-gateway/gateway/runtime/internal/examplepb"
+ "google.golang.org/protobuf/proto"
- options "github.com/binchencoder/ease-gateway/httpoptions"
+ options "github.com/binchencoder/janus-gateway/httpoptions"
"github.com/binchencoder/letsgo/hashring"
)
const DefaultHashKey = "8daad76a-dbb6-4f95-855d-7cfceb89afa1"
type msgA struct {
- StringValue string `protobuf:"bytes,1,opt,name=string_value" json:"string_value,omitempty"`
+ pb proto.Message
}
-func (ma *msgA) Reset() { *ma = msgA{} }
-func (ma *msgA) String() string { return proto.CompactTextString(ma) }
-func (*msgA) ProtoMessage() {}
-
-type msgB struct {
- Nested *msgA `protobuf:"bytes,1,opt,name=nested" json:"nested,omitempty"`
-}
-
-func (mb *msgB) Reset() { *mb = msgB{} }
-func (mb *msgB) String() string { return proto.CompactTextString(mb) }
-func (*msgB) ProtoMessage() {}
-
-func (mb *msgB) GetNested() *msgA {
- if mb != nil {
- return mb.Nested
- }
- return nil
-}
-
-type msgC struct {
- Nested *msgB `protobuf:"bytes,1,opt,name=nested" json:"nested,omitempty"`
-}
-
-func (mc *msgC) Reset() { *mc = msgC{} }
-func (mc *msgC) String() string { return proto.CompactTextString(mc) }
-func (*msgC) ProtoMessage() {}
-
-func (mc *msgC) GetNested() *msgB {
- if mc != nil {
- return mc.Nested
- }
- return nil
-}
-
-func TestGetProtoFiledValue(t *testing.T) {
- a := msgA{
- StringValue: "foo",
- }
- v := getProtoFiledValue(&a, "string_value")
- if v.String() != "foo" {
- t.Errorf("Expect string %s but got %s", "foo", v.String())
- }
-
- b := msgB{
- Nested: &a,
- }
- v = getProtoFiledValue(&b, "nested.string_value")
- if v.String() != "foo" {
- t.Errorf("Expect string %s but got %s", "foo", v.String())
- }
-
- c := msgC{
- Nested: &b,
- }
- v = getProtoFiledValue(&c, "nested.nested.string_value")
- if v.String() != "foo" {
- t.Errorf("Expect string %s but got %s", "foo", v.String())
- }
-}
+// func TestGetProtoFiledValue(t *testing.T) {
+// a := msgA{
+// StringValue: "foo",
+// }
+// v := getProtoFiledValue(&a, "string_value")
+// if v.String() != "foo" {
+// t.Errorf("Expect string %s but got %s", "foo", v.String())
+// }
+
+// b := msgB{
+// Nested: &a,
+// }
+// v = getProtoFiledValue(&b, "nested.string_value")
+// if v.String() != "foo" {
+// t.Errorf("Expect string %s but got %s", "foo", v.String())
+// }
+
+// c := msgC{
+// Nested: &b,
+// }
+// v = getProtoFiledValue(&c, "nested.nested.string_value")
+// if v.String() != "foo" {
+// t.Errorf("Expect string %s but got %s", "foo", v.String())
+// }
+// }
func TestPreLoadBalance(t *testing.T) {
// Generate UUID.
req := msgA{
- StringValue: DefaultHashKey,
+ pb: &pb.Proto3Message{
+ StringValue: DefaultHashKey,
+ },
}
- ctx := PreLoadBalance(context.Background(), options.LoadBalancer_CONSISTENT.String(), hashKeyUUID, &req)
+
+ ctx := PreLoadBalance(context.Background(), options.LoadBalancer_CONSISTENT.String(), hashKeyUUID, req.pb)
key := hashring.GetHashKeyOrEmpty(ctx)
if len(key) != 36 {
t.Errorf("Expect getting hash key with length 36s but got %s", key)
@@ -89,9 +59,11 @@ func TestPreLoadBalance(t *testing.T) {
// Proto field.
req = msgA{
- StringValue: DefaultHashKey,
+ pb: &pb.Proto3Message{
+ StringValue: DefaultHashKey,
+ },
}
- ctx = PreLoadBalance(context.Background(), options.LoadBalancer_CONSISTENT.String(), "string_value", &req)
+ ctx = PreLoadBalance(context.Background(), options.LoadBalancer_CONSISTENT.String(), "string_value", req.pb)
key = hashring.GetHashKeyOrEmpty(ctx)
if key != DefaultHashKey {
t.Errorf("Expect getting hash key %s but got %s", DefaultHashKey, key)
diff --git a/gateway/runtime/context.go b/gateway/runtime/context.go
index f808382..b5d1e6c 100644
--- a/gateway/runtime/context.go
+++ b/gateway/runtime/context.go
@@ -9,10 +9,10 @@ import (
"net/textproto"
"strconv"
"strings"
+ "sync"
"time"
"google.golang.org/grpc/codes"
- "google.golang.org/grpc/grpclog"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
)
@@ -41,6 +41,25 @@ var (
DefaultContextTimeout = 0 * time.Second
)
+// malformedHTTPHeaders lists the headers that the gRPC server may reject outright as malformed.
+// See https://github.com/grpc/grpc-go/pull/4803#issuecomment-986093310 for more context.
+var malformedHTTPHeaders = map[string]struct{}{
+ "connection": {},
+}
+
+type (
+ rpcMethodKey struct{}
+ httpPathPatternKey struct{}
+
+ AnnotateContextOption func(ctx context.Context) context.Context
+)
+
+func WithHTTPPathPattern(pattern string) AnnotateContextOption {
+ return func(ctx context.Context) context.Context {
+ return withHTTPPathPattern(ctx, pattern)
+ }
+}
+
func decodeBinHeader(v string) ([]byte, error) {
if len(v)%4 == 0 {
// Input was padded, or padding was not necessary.
@@ -56,8 +75,8 @@ At a minimum, the RemoteAddr is included in the fashion of "X-Forwarded-For",
except that the forwarded destination is not another HTTP service but rather
a gRPC service.
*/
-func AnnotateContext(ctx context.Context, mux *ServeMux, req *http.Request) (context.Context, error) {
- ctx, md, err := annotateContext(ctx, mux, req)
+func AnnotateContext(ctx context.Context, mux *ServeMux, req *http.Request, rpcMethodName string, options ...AnnotateContextOption) (context.Context, error) {
+ ctx, md, err := annotateContext(ctx, mux, req, rpcMethodName, options...)
if err != nil {
return nil, err
}
@@ -70,8 +89,8 @@ func AnnotateContext(ctx context.Context, mux *ServeMux, req *http.Request) (con
// AnnotateIncomingContext adds context information such as metadata from the request.
// Attach metadata as incoming context.
-func AnnotateIncomingContext(ctx context.Context, mux *ServeMux, req *http.Request) (context.Context, error) {
- ctx, md, err := annotateContext(ctx, mux, req)
+func AnnotateIncomingContext(ctx context.Context, mux *ServeMux, req *http.Request, rpcMethodName string, options ...AnnotateContextOption) (context.Context, error) {
+ ctx, md, err := annotateContext(ctx, mux, req, rpcMethodName, options...)
if err != nil {
return nil, err
}
@@ -82,7 +101,11 @@ func AnnotateIncomingContext(ctx context.Context, mux *ServeMux, req *http.Reque
return metadata.NewIncomingContext(ctx, md), nil
}
-func annotateContext(ctx context.Context, mux *ServeMux, req *http.Request) (context.Context, metadata.MD, error) {
+func annotateContext(ctx context.Context, mux *ServeMux, req *http.Request, rpcMethodName string, options ...AnnotateContextOption) (context.Context, metadata.MD, error) {
+ ctx = withRPCMethod(ctx, rpcMethodName)
+ for _, o := range options {
+ ctx = o(ctx)
+ }
var pairs []string
timeout := DefaultContextTimeout
if tm := req.Header.Get(metadataGrpcTimeout); tm != "" {
@@ -94,8 +117,8 @@ func annotateContext(ctx context.Context, mux *ServeMux, req *http.Request) (con
}
for key, vals := range req.Header {
+ key = textproto.CanonicalMIMEHeaderKey(key)
for _, val := range vals {
- key = textproto.CanonicalMIMEHeaderKey(key)
// For backwards-compatibility, pass through 'authorization' header with no prefix.
if key == "Authorization" {
pairs = append(pairs, "authorization", val)
@@ -128,12 +151,11 @@ func annotateContext(ctx context.Context, mux *ServeMux, req *http.Request) (con
} else {
pairs = append(pairs, strings.ToLower(xForwardedFor), fmt.Sprintf("%s, %s", fwd, remoteIP))
}
- } else {
- grpclog.Infof("invalid remote addr: %s", addr)
}
}
if timeout != 0 {
+ //nolint:govet // The context outlives this function
ctx, _ = context.WithTimeout(ctx, timeout)
}
if len(pairs) == 0 {
@@ -165,6 +187,63 @@ func ServerMetadataFromContext(ctx context.Context) (md ServerMetadata, ok bool)
return
}
+// ServerTransportStream implements grpc.ServerTransportStream.
+// It should only be used by the generated files to support grpc.SendHeader
+// outside of gRPC server use.
+type ServerTransportStream struct {
+ mu sync.Mutex
+ header metadata.MD
+ trailer metadata.MD
+}
+
+// Method returns the method for the stream.
+func (s *ServerTransportStream) Method() string {
+ return ""
+}
+
+// Header returns the header metadata of the stream.
+func (s *ServerTransportStream) Header() metadata.MD {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ return s.header.Copy()
+}
+
+// SetHeader sets the header metadata.
+func (s *ServerTransportStream) SetHeader(md metadata.MD) error {
+ if md.Len() == 0 {
+ return nil
+ }
+
+ s.mu.Lock()
+ s.header = metadata.Join(s.header, md)
+ s.mu.Unlock()
+ return nil
+}
+
+// SendHeader sets the header metadata.
+func (s *ServerTransportStream) SendHeader(md metadata.MD) error {
+ return s.SetHeader(md)
+}
+
+// Trailer returns the cached trailer metadata.
+func (s *ServerTransportStream) Trailer() metadata.MD {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ return s.trailer.Copy()
+}
+
+// SetTrailer sets the trailer metadata.
+func (s *ServerTransportStream) SetTrailer(md metadata.MD) error {
+ if md.Len() == 0 {
+ return nil
+ }
+
+ s.mu.Lock()
+ s.trailer = metadata.Join(s.trailer, md)
+ s.mu.Unlock()
+ return nil
+}
+
func timeoutDecode(s string) (time.Duration, error) {
size := len(s)
if size < 2 {
@@ -201,7 +280,7 @@ func timeoutUnitToDuration(u uint8) (d time.Duration, ok bool) {
}
// isPermanentHTTPHeader checks whether hdr belongs to the list of
-// permenant request headers maintained by IANA.
+// permanent request headers maintained by IANA.
// http://www.iana.org/assignments/message-headers/message-headers.xml
func isPermanentHTTPHeader(hdr string) bool {
switch hdr {
@@ -234,3 +313,46 @@ func isPermanentHTTPHeader(hdr string) bool {
}
return false
}
+
+// isMalformedHTTPHeader checks whether header belongs to the list of
+// "malformed headers" and would be rejected by the gRPC server.
+func isMalformedHTTPHeader(header string) bool {
+ _, isMalformed := malformedHTTPHeaders[strings.ToLower(header)]
+ return isMalformed
+}
+
+// RPCMethod returns the method string for the server context. The returned
+// string is in the format of "/package.service/method".
+func RPCMethod(ctx context.Context) (string, bool) {
+ m := ctx.Value(rpcMethodKey{})
+ if m == nil {
+ return "", false
+ }
+ ms, ok := m.(string)
+ if !ok {
+ return "", false
+ }
+ return ms, true
+}
+
+func withRPCMethod(ctx context.Context, rpcMethodName string) context.Context {
+ return context.WithValue(ctx, rpcMethodKey{}, rpcMethodName)
+}
+
+// HTTPPathPattern returns the HTTP path pattern string relating to the HTTP handler, if one exists.
+// The format of the returned string is defined by the google.api.http path template type.
+func HTTPPathPattern(ctx context.Context) (string, bool) {
+ m := ctx.Value(httpPathPatternKey{})
+ if m == nil {
+ return "", false
+ }
+ ms, ok := m.(string)
+ if !ok {
+ return "", false
+ }
+ return ms, true
+}
+
+func withHTTPPathPattern(ctx context.Context, httpPathPattern string) context.Context {
+ return context.WithValue(ctx, httpPathPatternKey{}, httpPathPattern)
+}
diff --git a/gateway/runtime/context_test.go b/gateway/runtime/context_test.go
index b092938..9fa740e 100644
--- a/gateway/runtime/context_test.go
+++ b/gateway/runtime/context_test.go
@@ -8,7 +8,8 @@ import (
"testing"
"time"
- "github.com/binchencoder/ease-gateway/gateway/runtime"
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
+ "github.com/binchencoder/janus-gateway/gateway/runtime"
"google.golang.org/grpc/metadata"
)
@@ -18,13 +19,14 @@ const (
func TestAnnotateContext_WorksWithEmpty(t *testing.T) {
ctx := context.Background()
-
- request, err := http.NewRequest("GET", "http://www.example.com", nil)
+ expectedRPCName := "/example.Example/Example"
+ expectedHTTPPathPattern := "/v1"
+ request, err := http.NewRequest("GET", "http://www.example.com/v1", nil)
if err != nil {
t.Fatalf("http.NewRequest(%q, %q, nil) failed with %v; want success", "GET", "http://www.example.com", err)
}
request.Header.Add("Some-Irrelevant-Header", "some value")
- annotated, err := runtime.AnnotateContext(ctx, runtime.NewServeMux(), request)
+ annotated, err := runtime.AnnotateContext(ctx, runtime.NewServeMux(), request, expectedRPCName, runtime.WithHTTPPathPattern(expectedHTTPPathPattern))
if err != nil {
t.Errorf("runtime.AnnotateContext(ctx, %#v) failed with %v; want success", request, err)
return
@@ -37,7 +39,9 @@ func TestAnnotateContext_WorksWithEmpty(t *testing.T) {
func TestAnnotateContext_ForwardsGrpcMetadata(t *testing.T) {
ctx := context.Background()
- request, err := http.NewRequest("GET", "http://www.example.com", nil)
+ expectedRPCName := "/example.Example/Example"
+ expectedHTTPPathPattern := "/v1"
+ request, err := http.NewRequest("GET", "http://www.example.com/v1", nil)
if err != nil {
t.Fatalf("http.NewRequest(%q, %q, nil) failed with %v; want success", "GET", "http://www.example.com", err)
}
@@ -46,7 +50,7 @@ func TestAnnotateContext_ForwardsGrpcMetadata(t *testing.T) {
request.Header.Add("Grpc-Metadata-Foo-BAZ", "Value2")
request.Header.Add("Grpc-Metadata-foo-bAz", "Value3")
request.Header.Add("Authorization", "Token 1234567890")
- annotated, err := runtime.AnnotateContext(ctx, runtime.NewServeMux(), request)
+ annotated, err := runtime.AnnotateContext(ctx, runtime.NewServeMux(), request, expectedRPCName, runtime.WithHTTPPathPattern(expectedHTTPPathPattern))
if err != nil {
t.Errorf("runtime.AnnotateContext(ctx, %#v) failed with %v; want success", request, err)
return
@@ -67,10 +71,22 @@ func TestAnnotateContext_ForwardsGrpcMetadata(t *testing.T) {
if got, want := md["authorization"], []string{"Token 1234567890"}; !reflect.DeepEqual(got, want) {
t.Errorf(`md["authorization"] = %q want %q`, got, want)
}
+ if m, ok := runtime.RPCMethod(annotated); !ok {
+ t.Errorf("runtime.RPCMethod(annotated) failed with no value; want %s", expectedRPCName)
+ } else if m != expectedRPCName {
+ t.Errorf("runtime.RPCMethod(annotated) failed with %s; want %s", m, expectedRPCName)
+ }
+
+ if m, ok := runtime.HTTPPathPattern(annotated); !ok {
+ t.Errorf("runtime.HTTPPathPattern(annotated) failed with no value; want %s", expectedHTTPPathPattern)
+ } else if m != expectedHTTPPathPattern {
+ t.Errorf("runtime.HTTPPathPattern(annotated) failed with %s; want %s", m, expectedHTTPPathPattern)
+ }
}
func TestAnnotateContext_ForwardGrpcBinaryMetadata(t *testing.T) {
ctx := context.Background()
+ expectedRPCName := "/example.Example/Example"
request, err := http.NewRequest("GET", "http://www.example.com", nil)
if err != nil {
t.Fatalf("http.NewRequest(%q, %q, nil) failed with %v; want success", "GET", "http://www.example.com", err)
@@ -79,7 +95,7 @@ func TestAnnotateContext_ForwardGrpcBinaryMetadata(t *testing.T) {
binData := []byte("\x00test-binary-data")
request.Header.Add("Grpc-Metadata-Test-Bin", base64.StdEncoding.EncodeToString(binData))
- annotated, err := runtime.AnnotateContext(ctx, runtime.NewServeMux(), request)
+ annotated, err := runtime.AnnotateContext(ctx, runtime.NewServeMux(), request, expectedRPCName)
if err != nil {
t.Errorf("runtime.AnnotateContext(ctx, %#v) failed with %v; want success", request, err)
return
@@ -91,10 +107,16 @@ func TestAnnotateContext_ForwardGrpcBinaryMetadata(t *testing.T) {
if got, want := md["test-bin"], []string{string(binData)}; !reflect.DeepEqual(got, want) {
t.Errorf(`md["test-bin"] = %q want %q`, got, want)
}
+ if m, ok := runtime.RPCMethod(annotated); !ok {
+ t.Errorf("runtime.RPCMethod(annotated) failed with no value; want %s", expectedRPCName)
+ } else if m != expectedRPCName {
+ t.Errorf("runtime.RPCMethod(annotated) failed with %s; want %s", m, expectedRPCName)
+ }
}
func TestAnnotateContext_XForwardedFor(t *testing.T) {
ctx := context.Background()
+ expectedRPCName := "/example.Example/Example"
request, err := http.NewRequest("GET", "http://bar.foo.example.com", nil)
if err != nil {
t.Fatalf("http.NewRequest(%q, %q, nil) failed with %v; want success", "GET", "http://bar.foo.example.com", err)
@@ -102,7 +124,7 @@ func TestAnnotateContext_XForwardedFor(t *testing.T) {
request.Header.Add("X-Forwarded-For", "192.0.2.100") // client
request.RemoteAddr = "192.0.2.200:12345" // proxy
- annotated, err := runtime.AnnotateContext(ctx, runtime.NewServeMux(), request)
+ annotated, err := runtime.AnnotateContext(ctx, runtime.NewServeMux(), request, expectedRPCName)
if err != nil {
t.Errorf("runtime.AnnotateContext(ctx, %#v) failed with %v; want success", request, err)
return
@@ -118,15 +140,21 @@ func TestAnnotateContext_XForwardedFor(t *testing.T) {
if got, want := md["x-forwarded-for"], []string{"192.0.2.100, 192.0.2.200"}; !reflect.DeepEqual(got, want) {
t.Errorf(`md["x-forwarded-for"] = %v want %v`, got, want)
}
+ if m, ok := runtime.RPCMethod(annotated); !ok {
+ t.Errorf("runtime.RPCMethod(annotated) failed with no value; want %s", expectedRPCName)
+ } else if m != expectedRPCName {
+ t.Errorf("runtime.RPCMethod(annotated) failed with %s; want %s", m, expectedRPCName)
+ }
}
func TestAnnotateContext_SupportsTimeouts(t *testing.T) {
ctx := context.Background()
+ expectedRPCName := "/example.Example/Example"
request, err := http.NewRequest("GET", "http://example.com", nil)
if err != nil {
t.Fatalf(`http.NewRequest("GET", "http://example.com", nil failed with %v; want success`, err)
}
- annotated, err := runtime.AnnotateContext(ctx, runtime.NewServeMux(), request)
+ annotated, err := runtime.AnnotateContext(ctx, runtime.NewServeMux(), request, expectedRPCName)
if err != nil {
t.Errorf("runtime.AnnotateContext(ctx, %#v) failed with %v; want success", request, err)
return
@@ -138,7 +166,7 @@ func TestAnnotateContext_SupportsTimeouts(t *testing.T) {
const acceptableError = 50 * time.Millisecond
runtime.DefaultContextTimeout = 10 * time.Second
- annotated, err = runtime.AnnotateContext(ctx, runtime.NewServeMux(), request)
+ annotated, err = runtime.AnnotateContext(ctx, runtime.NewServeMux(), request, expectedRPCName)
if err != nil {
t.Errorf("runtime.AnnotateContext(ctx, %#v) failed with %v; want success", request, err)
return
@@ -147,8 +175,8 @@ func TestAnnotateContext_SupportsTimeouts(t *testing.T) {
if !ok {
t.Errorf("annotated.Deadline() = _, false; want _, true")
}
- if got, want := deadline.Sub(time.Now()), runtime.DefaultContextTimeout; got-want > acceptableError || got-want < -acceptableError {
- t.Errorf("deadline.Sub(time.Now()) = %v; want %v; with error %v", got, want, acceptableError)
+ if got, want := time.Until(deadline), runtime.DefaultContextTimeout; got-want > acceptableError || got-want < -acceptableError {
+ t.Errorf("time.Until(deadline) = %v; want %v; with error %v", got, want, acceptableError)
}
for _, spec := range []struct {
@@ -181,7 +209,7 @@ func TestAnnotateContext_SupportsTimeouts(t *testing.T) {
},
} {
request.Header.Set("Grpc-Timeout", spec.timeout)
- annotated, err = runtime.AnnotateContext(ctx, runtime.NewServeMux(), request)
+ annotated, err = runtime.AnnotateContext(ctx, runtime.NewServeMux(), request, expectedRPCName)
if err != nil {
t.Errorf("runtime.AnnotateContext(ctx, %#v) failed with %v; want success", request, err)
return
@@ -190,8 +218,13 @@ func TestAnnotateContext_SupportsTimeouts(t *testing.T) {
if !ok {
t.Errorf("annotated.Deadline() = _, false; want _, true; timeout = %q", spec.timeout)
}
- if got, want := deadline.Sub(time.Now()), spec.want; got-want > acceptableError || got-want < -acceptableError {
- t.Errorf("deadline.Sub(time.Now()) = %v; want %v; with error %v; timeout= %q", got, want, acceptableError, spec.timeout)
+ if got, want := time.Until(deadline), spec.want; got-want > acceptableError || got-want < -acceptableError {
+ t.Errorf("time.Until(deadline) = %v; want %v; with error %v; timeout= %q", got, want, acceptableError, spec.timeout)
+ }
+ if m, ok := runtime.RPCMethod(annotated); !ok {
+ t.Errorf("runtime.RPCMethod(annotated) failed with no value; want %s", expectedRPCName)
+ } else if m != expectedRPCName {
+ t.Errorf("runtime.RPCMethod(annotated) failed with %s; want %s", m, expectedRPCName)
}
}
}
@@ -199,11 +232,12 @@ func TestAnnotateContext_SupportsCustomAnnotators(t *testing.T) {
md1 := func(context.Context, *http.Request) metadata.MD { return metadata.New(map[string]string{"foo": "bar"}) }
md2 := func(context.Context, *http.Request) metadata.MD { return metadata.New(map[string]string{"baz": "qux"}) }
expected := metadata.New(map[string]string{"foo": "bar", "baz": "qux"})
+ expectedRPCName := "/example.Example/Example"
request, err := http.NewRequest("GET", "http://example.com", nil)
if err != nil {
t.Fatalf(`http.NewRequest("GET", "http://example.com", nil failed with %v; want success`, err)
}
- annotated, err := runtime.AnnotateContext(context.Background(), runtime.NewServeMux(runtime.WithMetadata(md1), runtime.WithMetadata(md2)), request)
+ annotated, err := runtime.AnnotateContext(context.Background(), runtime.NewServeMux(runtime.WithMetadata(md1), runtime.WithMetadata(md2)), request, expectedRPCName)
if err != nil {
t.Errorf("runtime.AnnotateContext(ctx, %#v) failed with %v; want success", request, err)
return
@@ -214,17 +248,23 @@ func TestAnnotateContext_SupportsCustomAnnotators(t *testing.T) {
t.Errorf("metadata.MD[%s] = %v; want %v", key, a, e)
}
}
+ if m, ok := runtime.RPCMethod(annotated); !ok {
+ t.Errorf("runtime.RPCMethod(annotated) failed with no value; want %s", expectedRPCName)
+ } else if m != expectedRPCName {
+ t.Errorf("runtime.RPCMethod(annotated) failed with %s; want %s", m, expectedRPCName)
+ }
}
func TestAnnotateIncomingContext_WorksWithEmpty(t *testing.T) {
ctx := context.Background()
-
- request, err := http.NewRequest("GET", "http://www.example.com", nil)
+ expectedRPCName := "/example.Example/Example"
+ expectedHTTPPathPattern := "/v1"
+ request, err := http.NewRequest("GET", "http://www.example.com/v1", nil)
if err != nil {
t.Fatalf("http.NewRequest(%q, %q, nil) failed with %v; want success", "GET", "http://www.example.com", err)
}
request.Header.Add("Some-Irrelevant-Header", "some value")
- annotated, err := runtime.AnnotateIncomingContext(ctx, runtime.NewServeMux(), request)
+ annotated, err := runtime.AnnotateIncomingContext(ctx, runtime.NewServeMux(), request, expectedRPCName, runtime.WithHTTPPathPattern(expectedHTTPPathPattern))
if err != nil {
t.Errorf("runtime.AnnotateIncomingContext(ctx, %#v) failed with %v; want success", request, err)
return
@@ -233,11 +273,18 @@ func TestAnnotateIncomingContext_WorksWithEmpty(t *testing.T) {
if !ok || len(md) != emptyForwardMetaCount {
t.Errorf("Expected %d metadata items in context; got %v", emptyForwardMetaCount, md)
}
+ if m, ok := runtime.RPCMethod(annotated); !ok {
+ t.Errorf("runtime.RPCMethod(annotated) failed with no value; want %s", expectedRPCName)
+ } else if m != expectedRPCName {
+ t.Errorf("runtime.RPCMethod(annotated) failed with %s; want %s", m, expectedRPCName)
+ }
}
func TestAnnotateIncomingContext_ForwardsGrpcMetadata(t *testing.T) {
ctx := context.Background()
- request, err := http.NewRequest("GET", "http://www.example.com", nil)
+ expectedRPCName := "/example.Example/Example"
+ expectedHTTPPathPattern := "/v1"
+ request, err := http.NewRequest("GET", "http://www.example.com/v1", nil)
if err != nil {
t.Fatalf("http.NewRequest(%q, %q, nil) failed with %v; want success", "GET", "http://www.example.com", err)
}
@@ -246,7 +293,7 @@ func TestAnnotateIncomingContext_ForwardsGrpcMetadata(t *testing.T) {
request.Header.Add("Grpc-Metadata-Foo-BAZ", "Value2")
request.Header.Add("Grpc-Metadata-foo-bAz", "Value3")
request.Header.Add("Authorization", "Token 1234567890")
- annotated, err := runtime.AnnotateIncomingContext(ctx, runtime.NewServeMux(), request)
+ annotated, err := runtime.AnnotateIncomingContext(ctx, runtime.NewServeMux(), request, expectedRPCName, runtime.WithHTTPPathPattern(expectedHTTPPathPattern))
if err != nil {
t.Errorf("runtime.AnnotateIncomingContext(ctx, %#v) failed with %v; want success", request, err)
return
@@ -267,10 +314,21 @@ func TestAnnotateIncomingContext_ForwardsGrpcMetadata(t *testing.T) {
if got, want := md["authorization"], []string{"Token 1234567890"}; !reflect.DeepEqual(got, want) {
t.Errorf(`md["authorization"] = %q want %q`, got, want)
}
+ if m, ok := runtime.RPCMethod(annotated); !ok {
+ t.Errorf("runtime.RPCMethod(annotated) failed with no value; want %s", expectedRPCName)
+ } else if m != expectedRPCName {
+ t.Errorf("runtime.RPCMethod(annotated) failed with %s; want %s", m, expectedRPCName)
+ }
+ if m, ok := runtime.HTTPPathPattern(annotated); !ok {
+ t.Errorf("runtime.HTTPPathPattern(annotated) failed with no value; want %s", expectedHTTPPathPattern)
+ } else if m != expectedHTTPPathPattern {
+ t.Errorf("runtime.HTTPPathPattern(annotated) failed with %s; want %s", m, expectedHTTPPathPattern)
+ }
}
func TestAnnotateIncomingContext_ForwardGrpcBinaryMetadata(t *testing.T) {
ctx := context.Background()
+ expectedRPCName := "/example.Example/Example"
request, err := http.NewRequest("GET", "http://www.example.com", nil)
if err != nil {
t.Fatalf("http.NewRequest(%q, %q, nil) failed with %v; want success", "GET", "http://www.example.com", err)
@@ -279,7 +337,7 @@ func TestAnnotateIncomingContext_ForwardGrpcBinaryMetadata(t *testing.T) {
binData := []byte("\x00test-binary-data")
request.Header.Add("Grpc-Metadata-Test-Bin", base64.StdEncoding.EncodeToString(binData))
- annotated, err := runtime.AnnotateIncomingContext(ctx, runtime.NewServeMux(), request)
+ annotated, err := runtime.AnnotateIncomingContext(ctx, runtime.NewServeMux(), request, expectedRPCName)
if err != nil {
t.Errorf("runtime.AnnotateIncomingContext(ctx, %#v) failed with %v; want success", request, err)
return
@@ -291,10 +349,16 @@ func TestAnnotateIncomingContext_ForwardGrpcBinaryMetadata(t *testing.T) {
if got, want := md["test-bin"], []string{string(binData)}; !reflect.DeepEqual(got, want) {
t.Errorf(`md["test-bin"] = %q want %q`, got, want)
}
+ if m, ok := runtime.RPCMethod(annotated); !ok {
+ t.Errorf("runtime.RPCMethod(annotated) failed with no value; want %s", expectedRPCName)
+ } else if m != expectedRPCName {
+ t.Errorf("runtime.RPCMethod(annotated) failed with %s; want %s", m, expectedRPCName)
+ }
}
func TestAnnotateIncomingContext_XForwardedFor(t *testing.T) {
ctx := context.Background()
+ expectedRPCName := "/example.Example/Example"
request, err := http.NewRequest("GET", "http://bar.foo.example.com", nil)
if err != nil {
t.Fatalf("http.NewRequest(%q, %q, nil) failed with %v; want success", "GET", "http://bar.foo.example.com", err)
@@ -302,7 +366,7 @@ func TestAnnotateIncomingContext_XForwardedFor(t *testing.T) {
request.Header.Add("X-Forwarded-For", "192.0.2.100") // client
request.RemoteAddr = "192.0.2.200:12345" // proxy
- annotated, err := runtime.AnnotateIncomingContext(ctx, runtime.NewServeMux(), request)
+ annotated, err := runtime.AnnotateIncomingContext(ctx, runtime.NewServeMux(), request, expectedRPCName)
if err != nil {
t.Errorf("runtime.AnnotateIncomingContext(ctx, %#v) failed with %v; want success", request, err)
return
@@ -318,18 +382,23 @@ func TestAnnotateIncomingContext_XForwardedFor(t *testing.T) {
if got, want := md["x-forwarded-for"], []string{"192.0.2.100, 192.0.2.200"}; !reflect.DeepEqual(got, want) {
t.Errorf(`md["x-forwarded-for"] = %v want %v`, got, want)
}
+ if m, ok := runtime.RPCMethod(annotated); !ok {
+ t.Errorf("runtime.RPCMethod(annotated) failed with no value; want %s", expectedRPCName)
+ } else if m != expectedRPCName {
+ t.Errorf("runtime.RPCMethod(annotated) failed with %s; want %s", m, expectedRPCName)
+ }
}
func TestAnnotateIncomingContext_SupportsTimeouts(t *testing.T) {
// While run all test, TestAnnotateContext_SupportsTimeouts() will change the DefaultContextTimeout, so reset it to zero.
runtime.DefaultContextTimeout = 0 * time.Second
-
+ expectedRPCName := "/example.Example/Example"
ctx := context.Background()
request, err := http.NewRequest("GET", "http://example.com", nil)
if err != nil {
t.Fatalf(`http.NewRequest("GET", "http://example.com", nil failed with %v; want success`, err)
}
- annotated, err := runtime.AnnotateIncomingContext(ctx, runtime.NewServeMux(), request)
+ annotated, err := runtime.AnnotateIncomingContext(ctx, runtime.NewServeMux(), request, expectedRPCName)
if err != nil {
t.Errorf("runtime.AnnotateIncomingContext(ctx, %#v) failed with %v; want success", request, err)
return
@@ -341,7 +410,7 @@ func TestAnnotateIncomingContext_SupportsTimeouts(t *testing.T) {
const acceptableError = 50 * time.Millisecond
runtime.DefaultContextTimeout = 10 * time.Second
- annotated, err = runtime.AnnotateIncomingContext(ctx, runtime.NewServeMux(), request)
+ annotated, err = runtime.AnnotateIncomingContext(ctx, runtime.NewServeMux(), request, expectedRPCName)
if err != nil {
t.Errorf("runtime.AnnotateIncomingContext(ctx, %#v) failed with %v; want success", request, err)
return
@@ -350,8 +419,8 @@ func TestAnnotateIncomingContext_SupportsTimeouts(t *testing.T) {
if !ok {
t.Errorf("annotated.Deadline() = _, false; want _, true")
}
- if got, want := deadline.Sub(time.Now()), runtime.DefaultContextTimeout; got-want > acceptableError || got-want < -acceptableError {
- t.Errorf("deadline.Sub(time.Now()) = %v; want %v; with error %v", got, want, acceptableError)
+ if got, want := time.Until(deadline), runtime.DefaultContextTimeout; got-want > acceptableError || got-want < -acceptableError {
+ t.Errorf("time.Until(deadline) = %v; want %v; with error %v", got, want, acceptableError)
}
for _, spec := range []struct {
@@ -384,7 +453,7 @@ func TestAnnotateIncomingContext_SupportsTimeouts(t *testing.T) {
},
} {
request.Header.Set("Grpc-Timeout", spec.timeout)
- annotated, err = runtime.AnnotateIncomingContext(ctx, runtime.NewServeMux(), request)
+ annotated, err = runtime.AnnotateIncomingContext(ctx, runtime.NewServeMux(), request, expectedRPCName)
if err != nil {
t.Errorf("runtime.AnnotateIncomingContext(ctx, %#v) failed with %v; want success", request, err)
return
@@ -393,8 +462,13 @@ func TestAnnotateIncomingContext_SupportsTimeouts(t *testing.T) {
if !ok {
t.Errorf("annotated.Deadline() = _, false; want _, true; timeout = %q", spec.timeout)
}
- if got, want := deadline.Sub(time.Now()), spec.want; got-want > acceptableError || got-want < -acceptableError {
- t.Errorf("deadline.Sub(time.Now()) = %v; want %v; with error %v; timeout= %q", got, want, acceptableError, spec.timeout)
+ if got, want := time.Until(deadline), spec.want; got-want > acceptableError || got-want < -acceptableError {
+ t.Errorf("time.Until(deadline) = %v; want %v; with error %v; timeout= %q", got, want, acceptableError, spec.timeout)
+ }
+ if m, ok := runtime.RPCMethod(annotated); !ok {
+ t.Errorf("runtime.RPCMethod(annotated) failed with no value; want %s", expectedRPCName)
+ } else if m != expectedRPCName {
+ t.Errorf("runtime.RPCMethod(annotated) failed with %s; want %s", m, expectedRPCName)
}
}
}
@@ -402,11 +476,12 @@ func TestAnnotateIncomingContext_SupportsCustomAnnotators(t *testing.T) {
md1 := func(context.Context, *http.Request) metadata.MD { return metadata.New(map[string]string{"foo": "bar"}) }
md2 := func(context.Context, *http.Request) metadata.MD { return metadata.New(map[string]string{"baz": "qux"}) }
expected := metadata.New(map[string]string{"foo": "bar", "baz": "qux"})
+ expectedRPCName := "/example.Example/Example"
request, err := http.NewRequest("GET", "http://example.com", nil)
if err != nil {
t.Fatalf(`http.NewRequest("GET", "http://example.com", nil failed with %v; want success`, err)
}
- annotated, err := runtime.AnnotateIncomingContext(context.Background(), runtime.NewServeMux(runtime.WithMetadata(md1), runtime.WithMetadata(md2)), request)
+ annotated, err := runtime.AnnotateIncomingContext(context.Background(), runtime.NewServeMux(runtime.WithMetadata(md1), runtime.WithMetadata(md2)), request, expectedRPCName)
if err != nil {
t.Errorf("runtime.AnnotateIncomingContext(ctx, %#v) failed with %v; want success", request, err)
return
@@ -417,4 +492,9 @@ func TestAnnotateIncomingContext_SupportsCustomAnnotators(t *testing.T) {
t.Errorf("metadata.MD[%s] = %v; want %v", key, a, e)
}
}
+ if m, ok := runtime.RPCMethod(annotated); !ok {
+ t.Errorf("runtime.RPCMethod(annotated) failed with no value; want %s", expectedRPCName)
+ } else if m != expectedRPCName {
+ t.Errorf("runtime.RPCMethod(annotated) failed with %s; want %s", m, expectedRPCName)
+ }
}
diff --git a/gateway/runtime/convert.go b/gateway/runtime/convert.go
index 2c27934..cfa5407 100644
--- a/gateway/runtime/convert.go
+++ b/gateway/runtime/convert.go
@@ -6,10 +6,10 @@ import (
"strconv"
"strings"
- "github.com/golang/protobuf/jsonpb"
- "github.com/golang/protobuf/ptypes/duration"
- "github.com/golang/protobuf/ptypes/timestamp"
- "github.com/golang/protobuf/ptypes/wrappers"
+ "google.golang.org/protobuf/encoding/protojson"
+ "google.golang.org/protobuf/types/known/durationpb"
+ "google.golang.org/protobuf/types/known/timestamppb"
+ "google.golang.org/protobuf/types/known/wrapperspb"
)
// String just returns the given string.
@@ -205,9 +205,11 @@ func BytesSlice(val, sep string) ([][]byte, error) {
}
// Timestamp converts the given RFC3339 formatted string into a timestamp.Timestamp.
-func Timestamp(val string) (*timestamp.Timestamp, error) {
- var r timestamp.Timestamp
- err := jsonpb.UnmarshalString(val, &r)
+func Timestamp(val string) (*timestamppb.Timestamp, error) {
+ var r timestamppb.Timestamp
+ val = strconv.Quote(strings.Trim(val, `"`))
+ unmarshaler := &protojson.UnmarshalOptions{}
+ err := unmarshaler.Unmarshal([]byte(val), &r)
if err != nil {
return nil, err
}
@@ -215,9 +217,11 @@ func Timestamp(val string) (*timestamp.Timestamp, error) {
}
// Duration converts the given string into a timestamp.Duration.
-func Duration(val string) (*duration.Duration, error) {
- var r duration.Duration
- err := jsonpb.UnmarshalString(val, &r)
+func Duration(val string) (*durationpb.Duration, error) {
+ var r durationpb.Duration
+ val = strconv.Quote(strings.Trim(val, `"`))
+ unmarshaler := &protojson.UnmarshalOptions{}
+ err := unmarshaler.Unmarshal([]byte(val), &r)
if err != nil {
return nil, err
}
@@ -261,58 +265,58 @@ func EnumSlice(val, sep string, enumValMap map[string]int32) ([]int32, error) {
}
/*
- Support fot google.protobuf.wrappers on top of primitive types
+ Support for google.protobuf.wrappers on top of primitive types
*/
// StringValue well-known type support as wrapper around string type
-func StringValue(val string) (*wrappers.StringValue, error) {
- return &wrappers.StringValue{Value: val}, nil
+func StringValue(val string) (*wrapperspb.StringValue, error) {
+ return &wrapperspb.StringValue{Value: val}, nil
}
// FloatValue well-known type support as wrapper around float32 type
-func FloatValue(val string) (*wrappers.FloatValue, error) {
+func FloatValue(val string) (*wrapperspb.FloatValue, error) {
parsedVal, err := Float32(val)
- return &wrappers.FloatValue{Value: parsedVal}, err
+ return &wrapperspb.FloatValue{Value: parsedVal}, err
}
// DoubleValue well-known type support as wrapper around float64 type
-func DoubleValue(val string) (*wrappers.DoubleValue, error) {
+func DoubleValue(val string) (*wrapperspb.DoubleValue, error) {
parsedVal, err := Float64(val)
- return &wrappers.DoubleValue{Value: parsedVal}, err
+ return &wrapperspb.DoubleValue{Value: parsedVal}, err
}
// BoolValue well-known type support as wrapper around bool type
-func BoolValue(val string) (*wrappers.BoolValue, error) {
+func BoolValue(val string) (*wrapperspb.BoolValue, error) {
parsedVal, err := Bool(val)
- return &wrappers.BoolValue{Value: parsedVal}, err
+ return &wrapperspb.BoolValue{Value: parsedVal}, err
}
// Int32Value well-known type support as wrapper around int32 type
-func Int32Value(val string) (*wrappers.Int32Value, error) {
+func Int32Value(val string) (*wrapperspb.Int32Value, error) {
parsedVal, err := Int32(val)
- return &wrappers.Int32Value{Value: parsedVal}, err
+ return &wrapperspb.Int32Value{Value: parsedVal}, err
}
// UInt32Value well-known type support as wrapper around uint32 type
-func UInt32Value(val string) (*wrappers.UInt32Value, error) {
+func UInt32Value(val string) (*wrapperspb.UInt32Value, error) {
parsedVal, err := Uint32(val)
- return &wrappers.UInt32Value{Value: parsedVal}, err
+ return &wrapperspb.UInt32Value{Value: parsedVal}, err
}
// Int64Value well-known type support as wrapper around int64 type
-func Int64Value(val string) (*wrappers.Int64Value, error) {
+func Int64Value(val string) (*wrapperspb.Int64Value, error) {
parsedVal, err := Int64(val)
- return &wrappers.Int64Value{Value: parsedVal}, err
+ return &wrapperspb.Int64Value{Value: parsedVal}, err
}
// UInt64Value well-known type support as wrapper around uint64 type
-func UInt64Value(val string) (*wrappers.UInt64Value, error) {
+func UInt64Value(val string) (*wrapperspb.UInt64Value, error) {
parsedVal, err := Uint64(val)
- return &wrappers.UInt64Value{Value: parsedVal}, err
+ return &wrapperspb.UInt64Value{Value: parsedVal}, err
}
// BytesValue well-known type support as wrapper around bytes[] type
-func BytesValue(val string) (*wrappers.BytesValue, error) {
+func BytesValue(val string) (*wrapperspb.BytesValue, error) {
parsedVal, err := Bytes(val)
- return &wrappers.BytesValue{Value: parsedVal}, err
+ return &wrapperspb.BytesValue{Value: parsedVal}, err
}
diff --git a/gateway/runtime/convert_test.go b/gateway/runtime/convert_test.go
new file mode 100644
index 0000000..5e971ba
--- /dev/null
+++ b/gateway/runtime/convert_test.go
@@ -0,0 +1,141 @@
+package runtime_test
+
+import (
+ "testing"
+
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
+ "github.com/binchencoder/janus-gateway/gateway/runtime"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/types/known/durationpb"
+ "google.golang.org/protobuf/types/known/timestamppb"
+)
+
+func TestConvertTimestamp(t *testing.T) {
+ specs := []struct {
+ name string
+ input string
+ output *timestamppb.Timestamp
+ wanterr bool
+ }{
+ {
+ name: "a valid RFC3339 timestamp",
+ input: `"2016-05-10T10:19:13.123Z"`,
+ output: ×tamppb.Timestamp{
+ Seconds: 1462875553,
+ Nanos: 123000000,
+ },
+ wanterr: false,
+ },
+ {
+ name: "a valid RFC3339 timestamp without double quotation",
+ input: "2016-05-10T10:19:13.123Z",
+ output: ×tamppb.Timestamp{
+ Seconds: 1462875553,
+ Nanos: 123000000,
+ },
+ wanterr: false,
+ },
+ {
+ name: "invalid timestamp",
+ input: `"05-10-2016T10:19:13.123Z"`,
+ output: nil,
+ wanterr: true,
+ },
+ {
+ name: "JSON number",
+ input: "123",
+ output: nil,
+ wanterr: true,
+ },
+ {
+ name: "JSON bool",
+ input: "true",
+ output: nil,
+ wanterr: true,
+ },
+ }
+
+ for _, spec := range specs {
+ t.Run(spec.name, func(t *testing.T) {
+ ts, err := runtime.Timestamp(spec.input)
+ switch {
+ case err != nil && !spec.wanterr:
+ t.Errorf("got unexpected error\n%#v", err)
+ case err == nil && spec.wanterr:
+ t.Errorf("did not error when expecte")
+ case !proto.Equal(ts, spec.output):
+ t.Errorf(
+ "when testing %s; got\n%#v\nexpected\n%#v",
+ spec.name,
+ ts,
+ spec.output,
+ )
+ }
+ })
+ }
+}
+
+func TestConvertDuration(t *testing.T) {
+ specs := []struct {
+ name string
+ input string
+ output *durationpb.Duration
+ wanterr bool
+ }{
+ {
+ name: "a valid duration",
+ input: `"123.456s"`,
+ output: &durationpb.Duration{
+ Seconds: 123,
+ Nanos: 456000000,
+ },
+ wanterr: false,
+ },
+ {
+ name: "a valid duration without double quotation",
+ input: "123.456s",
+ output: &durationpb.Duration{
+ Seconds: 123,
+ Nanos: 456000000,
+ },
+ wanterr: false,
+ },
+ {
+ name: "invalid duration",
+ input: `"123years"`,
+ output: nil,
+ wanterr: true,
+ },
+ {
+ name: "JSON number",
+ input: "123",
+ output: nil,
+ wanterr: true,
+ },
+ {
+ name: "JSON bool",
+ input: "true",
+ output: nil,
+ wanterr: true,
+ },
+ }
+
+ for _, spec := range specs {
+ t.Run(spec.name, func(t *testing.T) {
+ ts, err := runtime.Duration(spec.input)
+ switch {
+ case err != nil && !spec.wanterr:
+ t.Errorf("got unexpected error\n%#v", err)
+ case err == nil && spec.wanterr:
+ t.Errorf("did not error when expecte")
+ case !proto.Equal(ts, spec.output):
+ t.Errorf(
+ "when testing %s; got\n%#v\nexpected\n%#v",
+ spec.name,
+ ts,
+ spec.output,
+ )
+ }
+ })
+ }
+}
diff --git a/gateway/runtime/errors.go b/gateway/runtime/errors.go
index 8198fc2..1499301 100644
--- a/gateway/runtime/errors.go
+++ b/gateway/runtime/errors.go
@@ -2,20 +2,40 @@ package runtime
import (
"context"
+ "errors"
"io"
"net/http"
"github.com/golang/protobuf/jsonpb"
- "github.com/golang/protobuf/proto"
- "github.com/golang/protobuf/ptypes/any"
- "google.golang.org/grpc"
+
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/status"
+ "github.com/binchencoder/janus-gateway/gateway/internal"
fpb "github.com/binchencoder/gateway-proto/frontend"
)
+// ErrorHandlerFunc is the signature used to configure error handling.
+type ErrorHandlerFunc func(context.Context, *ServeMux, Marshaler, http.ResponseWriter, *http.Request, error)
+
+// StreamErrorHandlerFunc is the signature used to configure stream error handling.
+type StreamErrorHandlerFunc func(context.Context, error) *status.Status
+
+// RoutingErrorHandlerFunc is the signature used to configure error handling for routing errors.
+type RoutingErrorHandlerFunc func(context.Context, *ServeMux, Marshaler, http.ResponseWriter, *http.Request, int)
+
+// HTTPStatusError is the error to use when needing to provide a different HTTP status code for an error
+// passed to the DefaultRoutingErrorHandler.
+type HTTPStatusError struct {
+ HTTPStatus int
+ Err error
+}
+
+func (e *HTTPStatusError) Error() string {
+ return e.Err.Error()
+}
+
// HTTPStatusFromCode converts a gRPC error code into the corresponding HTTP response status.
// See: https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
func HTTPStatusFromCode(code codes.Code) int {
@@ -61,66 +81,52 @@ func HTTPStatusFromCode(code codes.Code) int {
return http.StatusInternalServerError
}
-var (
- // HTTPError replies to the request with the error.
- // You can set a custom function to this variable to customize error format.
- HTTPError = DefaultHTTPError
- // OtherErrorHandler handles the following error used by the gateway: StatusMethodNotAllowed StatusNotFound and StatusBadRequest
- OtherErrorHandler = DefaultOtherErrorHandler
-)
-
-type errorBody struct {
- Error *fpb.Error `protobuf:"bytes,1,name=error" json:"error"`
- // This is to make the error more compatible with users that expect errors to be Status objects:
- // https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto
- // It should be the exact same message as the Error field.
- Code int32 `protobuf:"varint,1,name=code" json:"code"`
- Message string `protobuf:"bytes,2,name=message" json:"message"`
- Details []*any.Any `protobuf:"bytes,3,rep,name=details" json:"details,omitempty"`
+// HTTPError uses the mux-configured error handler.
+func HTTPError(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, r *http.Request, err error) {
+ mux.errorHandler(ctx, mux, marshaler, w, r, err)
}
-// Make this also conform to proto.Message for builtin JSONPb Marshaler
-func (e *errorBody) Reset() { *e = errorBody{} }
-func (e *errorBody) String() string { return proto.CompactTextString(e) }
-func (*errorBody) ProtoMessage() {}
-
-// DefaultHTTPError is the default implementation of HTTPError.
-// If "err" is an error from gRPC system, the function replies with the status code mapped by HTTPStatusFromCode.
+// DefaultHTTPErrorHandler is the default error handler.
+// If "err" is a gRPC Status, the function replies with the status code mapped by HTTPStatusFromCode.
+// If "err" is a HTTPStatusError, the function replies with the status code provide by that struct. This is
+// intended to allow passing through of specific statuses via the function set via WithRoutingErrorHandler
+// for the ServeMux constructor to handle edge cases which the standard mappings in HTTPStatusFromCode
+// are insufficient for.
// If otherwise, it replies with http.StatusInternalServerError.
//
-// The response body returned by this function is a JSON object,
-// which contains a member whose key is "error" and whose value is err.Error().
-func DefaultHTTPError(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, _ *http.Request, err error) {
- const fallback = `{"error": "failed to marshal error message"}`
-
- s, ok := status.FromError(err)
- if !ok {
- s = status.New(codes.Unknown, err.Error())
+// The response body written by this function is a Status message marshaled by the Marshaler.
+func DefaultHTTPErrorHandler(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, r *http.Request, err error) {
+ // return Internal when Marshal failed
+ const fallback = `{"code": 13, "message": "failed to marshal error message"}`
+
+ var customStatus *HTTPStatusError
+ if errors.As(err, &customStatus) {
+ err = customStatus.Err
}
+ s := status.Convert(err)
+ pb := s.Proto()
+
w.Header().Del("Trailer")
+ w.Header().Del("Transfer-Encoding")
- contentType := marshaler.ContentType()
- // Check marshaler on run time in order to keep backwards compatability
- // An interface param needs to be added to the ContentType() function on
- // the Marshal interface to be able to remove this check
- if httpBodyMarshaler, ok := marshaler.(*HTTPBodyMarshaler); ok {
- pb := s.Proto()
- contentType = httpBodyMarshaler.ContentTypeFromMessage(pb)
- }
+ contentType := marshaler.ContentType(pb)
w.Header().Set("Content-Type", contentType)
+ if s.Code() == codes.Unauthenticated {
+ w.Header().Set("WWW-Authenticate", s.Message())
+ }
e := fpb.Error{}
- desc := grpc.ErrorDesc(err)
+ desc := s.Message()
if erru := jsonpb.UnmarshalString(desc, &e); erru != nil {
e.Code = fpb.ErrorCode_UNDEFINED
e.Params = []string{desc}
}
- body := &errorBody{
+ body := &internal.Error{
Error: &e,
Message: s.Message(),
Code: int32(s.Code()),
- Details: s.Proto().GetDetails(),
+ Details: pb.GetDetails(),
}
buf, merr := marshaler.Marshal(body)
@@ -139,18 +145,53 @@ func DefaultHTTPError(ctx context.Context, mux *ServeMux, marshaler Marshaler, w
}
handleForwardResponseServerMetadata(w, mux, md)
- handleForwardResponseTrailerHeader(w, md)
+
+ // RFC 7230 https://tools.ietf.org/html/rfc7230#section-4.1.2
+ // Unless the request includes a TE header field indicating "trailers"
+ // is acceptable, as described in Section 4.3, a server SHOULD NOT
+ // generate trailer fields that it believes are necessary for the user
+ // agent to receive.
+ doForwardTrailers := requestAcceptsTrailers(r)
+
+ if doForwardTrailers {
+ handleForwardResponseTrailerHeader(w, md)
+ w.Header().Set("Transfer-Encoding", "chunked")
+ }
+
st := HTTPStatusFromCode(s.Code())
+ if customStatus != nil {
+ st = customStatus.HTTPStatus
+ }
+
w.WriteHeader(st)
if _, err := w.Write(buf); err != nil {
grpclog.Infof("Failed to write response: %v", err)
}
- handleForwardResponseTrailer(w, md)
+ if doForwardTrailers {
+ handleForwardResponseTrailer(w, md)
+ }
+}
+
+func DefaultStreamErrorHandler(_ context.Context, err error) *status.Status {
+ return status.Convert(err)
}
-// DefaultOtherErrorHandler is the default implementation of OtherErrorHandler.
-// It simply writes a string representation of the given error into "w".
-func DefaultOtherErrorHandler(w http.ResponseWriter, _ *http.Request, msg string, code int) {
- http.Error(w, msg, code)
+// DefaultRoutingErrorHandler is our default handler for routing errors.
+// By default http error codes mapped on the following error codes:
+// NotFound -> grpc.NotFound
+// StatusBadRequest -> grpc.InvalidArgument
+// MethodNotAllowed -> grpc.Unimplemented
+// Other -> grpc.Internal, method is not expecting to be called for anything else
+func DefaultRoutingErrorHandler(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, r *http.Request, httpStatus int) {
+ sterr := status.Error(codes.Internal, "Unexpected routing error")
+ switch httpStatus {
+ case http.StatusBadRequest:
+ sterr = status.Error(codes.InvalidArgument, http.StatusText(httpStatus))
+ case http.StatusMethodNotAllowed:
+ sterr = status.Error(codes.Unimplemented, http.StatusText(httpStatus))
+ case http.StatusNotFound:
+ sterr = status.Error(codes.NotFound, http.StatusText(httpStatus))
+ }
+ mux.errorHandler(ctx, mux, marshaler, w, r, sterr)
}
diff --git a/gateway/runtime/errors_test.go b/gateway/runtime/errors_test.go
index 4026b14..498b304 100644
--- a/gateway/runtime/errors_test.go
+++ b/gateway/runtime/errors_test.go
@@ -2,15 +2,17 @@ package runtime_test
import (
"context"
- "encoding/json"
"fmt"
"net/http"
"net/http/httptest"
+ "strconv"
"strings"
"testing"
- "github.com/binchencoder/ease-gateway/gateway/runtime"
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
+ "github.com/binchencoder/janus-gateway/gateway/runtime"
"google.golang.org/genproto/googleapis/rpc/errdetails"
+ statuspb "google.golang.org/genproto/googleapis/rpc/status"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
@@ -22,66 +24,87 @@ func TestDefaultHTTPError(t *testing.T) {
&errdetails.PreconditionFailure{},
)
- for _, spec := range []struct {
- err error
- status int
- msg string
- details string
+ for i, spec := range []struct {
+ err error
+ status int
+ msg string
+ marshaler runtime.Marshaler
+ contentType string
+ details string
}{
{
- err: fmt.Errorf("example error"),
- status: http.StatusInternalServerError,
- msg: "example error",
+ err: fmt.Errorf("example error"),
+ status: http.StatusInternalServerError,
+ marshaler: &runtime.JSONPb{},
+ contentType: "application/json",
+ msg: "example error",
},
{
- err: status.Error(codes.NotFound, "no such resource"),
- status: http.StatusNotFound,
- msg: "no such resource",
+ err: status.Error(codes.NotFound, "no such resource"),
+ status: http.StatusNotFound,
+ marshaler: &runtime.JSONPb{},
+ contentType: "application/json",
+ msg: "no such resource",
},
{
- err: statusWithDetails.Err(),
- status: http.StatusBadRequest,
- msg: "failed precondition",
- details: "type.googleapis.com/google.rpc.PreconditionFailure",
+ err: statusWithDetails.Err(),
+ status: http.StatusBadRequest,
+ marshaler: &runtime.JSONPb{},
+ contentType: "application/json",
+ msg: "failed precondition",
+ details: "type.googleapis.com/google.rpc.PreconditionFailure",
+ },
+ {
+ err: fmt.Errorf("example error"),
+ status: http.StatusInternalServerError,
+ marshaler: &CustomMarshaler{&runtime.JSONPb{}},
+ contentType: "Custom-Content-Type",
+ msg: "example error",
+ },
+ {
+ err: &runtime.HTTPStatusError{
+ HTTPStatus: http.StatusMethodNotAllowed,
+ Err: status.Error(codes.Unimplemented, http.StatusText(http.StatusMethodNotAllowed)),
+ },
+ status: http.StatusMethodNotAllowed,
+ marshaler: &runtime.JSONPb{},
+ contentType: "application/json",
+ msg: "Method Not Allowed",
},
} {
- w := httptest.NewRecorder()
- req, _ := http.NewRequest("", "", nil) // Pass in an empty request to match the signature
- runtime.DefaultHTTPError(ctx, &runtime.ServeMux{}, &runtime.JSONPb{}, w, req, spec.err)
-
- if got, want := w.Header().Get("Content-Type"), "application/json"; got != want {
- t.Errorf(`w.Header().Get("Content-Type") = %q; want %q; on spec.err=%v`, got, want, spec.err)
- }
- if got, want := w.Code, spec.status; got != want {
- t.Errorf("w.Code = %d; want %d", got, want)
- }
+ t.Run(strconv.Itoa(i), func(t *testing.T) {
+ w := httptest.NewRecorder()
+ req, _ := http.NewRequest("", "", nil) // Pass in an empty request to match the signature
+ mux := runtime.NewServeMux()
+ marshaler := &runtime.JSONPb{}
+ runtime.HTTPError(ctx, mux, marshaler, w, req, spec.err)
- body := make(map[string]interface{})
- if err := json.Unmarshal(w.Body.Bytes(), &body); err != nil {
- t.Errorf("json.Unmarshal(%q, &body) failed with %v; want success", w.Body.Bytes(), err)
- continue
- }
-
- if got, want := body["error"].(string), spec.msg; !strings.Contains(got, want) {
- t.Errorf(`body["error"] = %q; want %q; on spec.err=%v`, got, want, spec.err)
- }
- if got, want := body["message"].(string), spec.msg; !strings.Contains(got, want) {
- t.Errorf(`body["message"] = %q; want %q; on spec.err=%v`, got, want, spec.err)
- }
+ if got, want := w.Header().Get("Content-Type"), "application/json"; got != want {
+ t.Errorf(`w.Header().Get("Content-Type") = %q; want %q; on spec.err=%v`, got, want, spec.err)
+ }
+ if got, want := w.Code, spec.status; got != want {
+ t.Errorf("w.Code = %d; want %d", got, want)
+ }
- if spec.details != "" {
- details, ok := body["details"].([]interface{})
- if !ok {
- t.Errorf(`body["details"] = %T; want %T`, body["details"], []interface{}{})
- continue
+ var st statuspb.Status
+ if err := marshaler.Unmarshal(w.Body.Bytes(), &st); err != nil {
+ t.Errorf("marshaler.Unmarshal(%q, &body) failed with %v; want success", w.Body.Bytes(), err)
+ return
}
- if len(details) != 1 {
- t.Errorf(`len(body["details"]) = %v; want 1`, len(details))
- continue
+
+ if got, want := st.Message, spec.msg; !strings.Contains(got, want) {
+ t.Errorf(`st.Message = %q; want %q; on spec.err=%v`, got, want, spec.err)
}
- if details[0].(map[string]interface{})["@type"] != spec.details {
- t.Errorf(`details.@type = %s; want %s`, details[0].(map[string]interface{})["@type"], spec.details)
+
+ if spec.details != "" {
+ if len(st.Details) != 1 {
+ t.Errorf(`len(st.Details) = %v; want 1`, len(st.Details))
+ return
+ }
+ if st.Details[0].TypeUrl != spec.details {
+ t.Errorf(`details.type_url = %s; want %s`, st.Details[0].TypeUrl, spec.details)
+ }
}
- }
+ })
}
}
diff --git a/gateway/runtime/fieldmask.go b/gateway/runtime/fieldmask.go
index 341aad5..0138ed2 100644
--- a/gateway/runtime/fieldmask.go
+++ b/gateway/runtime/fieldmask.go
@@ -2,42 +2,29 @@ package runtime
import (
"encoding/json"
+ "fmt"
"io"
- "strings"
+ "sort"
- descriptor2 "github.com/golang/protobuf/descriptor"
- "github.com/golang/protobuf/protoc-gen-go/descriptor"
"google.golang.org/genproto/protobuf/field_mask"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/reflect/protoreflect"
)
-func translateName(name string, md *descriptor.DescriptorProto) (string, *descriptor.DescriptorProto) {
- // TODO - should really gate this with a test that the marshaller has used json names
- if md != nil {
- for _, f := range md.Field {
- if f.JsonName != nil && f.Name != nil && *f.JsonName == name {
- var subType *descriptor.DescriptorProto
-
- // If the field has a TypeName then we retrieve the nested type for translating the embedded message names.
- if f.TypeName != nil {
- typeSplit := strings.Split(*f.TypeName, ".")
- typeName := typeSplit[len(typeSplit)-1]
- for _, t := range md.NestedType {
- if typeName == *t.Name {
- subType = t
- }
- }
- }
- return *f.Name, subType
- }
- }
+func getFieldByName(fields protoreflect.FieldDescriptors, name string) protoreflect.FieldDescriptor {
+ fd := fields.ByName(protoreflect.Name(name))
+ if fd != nil {
+ return fd
}
- return name, nil
+
+ return fields.ByJSONName(name)
}
// FieldMaskFromRequestBody creates a FieldMask printing all complete paths from the JSON body.
-func FieldMaskFromRequestBody(r io.Reader, md *descriptor.DescriptorProto) (*field_mask.FieldMask, error) {
+func FieldMaskFromRequestBody(r io.Reader, msg proto.Message) (*field_mask.FieldMask, error) {
fm := &field_mask.FieldMask{}
var root interface{}
+
if err := json.NewDecoder(r).Decode(&root); err != nil {
if err == io.EOF {
return fm, nil
@@ -45,38 +32,134 @@ func FieldMaskFromRequestBody(r io.Reader, md *descriptor.DescriptorProto) (*fie
return nil, err
}
- queue := []fieldMaskPathItem{{node: root, md: md}}
+ queue := []fieldMaskPathItem{{node: root, msg: msg.ProtoReflect()}}
for len(queue) > 0 {
// dequeue an item
item := queue[0]
queue = queue[1:]
- if m, ok := item.node.(map[string]interface{}); ok {
+ m, ok := item.node.(map[string]interface{})
+ switch {
+ case ok:
// if the item is an object, then enqueue all of its children
for k, v := range m {
- protoName, subMd := translateName(k, item.md)
- if subMsg, ok := v.(descriptor2.Message); ok {
- _, subMd = descriptor2.ForMessage(subMsg)
+ if item.msg == nil {
+ return nil, fmt.Errorf("JSON structure did not match request type")
+ }
+
+ fd := getFieldByName(item.msg.Descriptor().Fields(), k)
+ if fd == nil {
+ return nil, fmt.Errorf("could not find field %q in %q", k, item.msg.Descriptor().FullName())
+ }
+
+ if isDynamicProtoMessage(fd.Message()) {
+ for _, p := range buildPathsBlindly(k, v) {
+ newPath := p
+ if item.path != "" {
+ newPath = item.path + "." + newPath
+ }
+ queue = append(queue, fieldMaskPathItem{path: newPath})
+ }
+ continue
+ }
+
+ if isProtobufAnyMessage(fd.Message()) {
+ _, hasTypeField := v.(map[string]interface{})["@type"]
+ if hasTypeField {
+ queue = append(queue, fieldMaskPathItem{path: k})
+ continue
+ } else {
+ return nil, fmt.Errorf("could not find field @type in %q in message %q", k, item.msg.Descriptor().FullName())
+ }
+
+ }
+
+ child := fieldMaskPathItem{
+ node: v,
+ }
+ if item.path == "" {
+ child.path = string(fd.FullName().Name())
+ } else {
+ child.path = item.path + "." + string(fd.FullName().Name())
+ }
+
+ switch {
+ case fd.IsList(), fd.IsMap():
+ // As per: https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/field_mask.proto#L85-L86
+ // Do not recurse into repeated fields. The repeated field goes on the end of the path and we stop.
+ fm.Paths = append(fm.Paths, child.path)
+ case fd.Message() != nil:
+ child.msg = item.msg.Get(fd).Message()
+ fallthrough
+ default:
+ queue = append(queue, child)
}
- queue = append(queue, fieldMaskPathItem{path: append(item.path, protoName), node: v, md: subMd})
}
- } else if len(item.path) > 0 {
+ case len(item.path) > 0:
// otherwise, it's a leaf node so print its path
- fm.Paths = append(fm.Paths, strings.Join(item.path, "."))
+ fm.Paths = append(fm.Paths, item.path)
}
}
+ // Sort for deterministic output in the presence
+ // of repeated fields.
+ sort.Strings(fm.Paths)
+
return fm, nil
}
+func isProtobufAnyMessage(md protoreflect.MessageDescriptor) bool {
+ return md != nil && (md.FullName() == "google.protobuf.Any")
+}
+
+func isDynamicProtoMessage(md protoreflect.MessageDescriptor) bool {
+ return md != nil && (md.FullName() == "google.protobuf.Struct" || md.FullName() == "google.protobuf.Value")
+}
+
+// buildPathsBlindly does not attempt to match proto field names to the
+// json value keys. Instead it relies completely on the structure of
+// the unmarshalled json contained within in.
+// Returns a slice containing all subpaths with the root at the
+// passed in name and json value.
+func buildPathsBlindly(name string, in interface{}) []string {
+ m, ok := in.(map[string]interface{})
+ if !ok {
+ return []string{name}
+ }
+
+ var paths []string
+ queue := []fieldMaskPathItem{{path: name, node: m}}
+ for len(queue) > 0 {
+ cur := queue[0]
+ queue = queue[1:]
+
+ m, ok := cur.node.(map[string]interface{})
+ if !ok {
+ // This should never happen since we should always check that we only add
+ // nodes of type map[string]interface{} to the queue.
+ continue
+ }
+ for k, v := range m {
+ if mi, ok := v.(map[string]interface{}); ok {
+ queue = append(queue, fieldMaskPathItem{path: cur.path + "." + k, node: mi})
+ } else {
+ // This is not a struct, so there are no more levels to descend.
+ curPath := cur.path + "." + k
+ paths = append(paths, curPath)
+ }
+ }
+ }
+ return paths
+}
+
// fieldMaskPathItem stores a in-progress deconstruction of a path for a fieldmask
type fieldMaskPathItem struct {
- // the list of prior fields leading up to node
- path []string
+ // the list of prior fields leading up to node connected by dots
+ path string
// a generic decoded json object the current item to inspect for further path extraction
node interface{}
- // descriptor for parent message
- md *descriptor.DescriptorProto
+ // parent message
+ msg protoreflect.Message
}
diff --git a/gateway/runtime/fieldmask_test.go b/gateway/runtime/fieldmask_test.go
deleted file mode 100644
index 7a5ddaa..0000000
--- a/gateway/runtime/fieldmask_test.go
+++ /dev/null
@@ -1,151 +0,0 @@
-package runtime
-
-import (
- "bytes"
- "fmt"
- "testing"
-
- "google.golang.org/genproto/protobuf/field_mask"
-)
-
-func fieldMasksEqual(fm1, fm2 *field_mask.FieldMask) bool {
- if fm1 == nil && fm2 == nil {
- return true
- }
- if fm1 == nil || fm2 == nil {
- return false
- }
- if len(fm1.GetPaths()) != len(fm2.GetPaths()) {
- return false
- }
-
- paths := make(map[string]bool)
- for _, path := range fm1.GetPaths() {
- paths[path] = true
- }
- for _, path := range fm2.GetPaths() {
- if _, ok := paths[path]; !ok {
- return false
- }
- }
-
- return true
-}
-
-func newFieldMask(paths ...string) *field_mask.FieldMask {
- return &field_mask.FieldMask{Paths: paths}
-}
-
-func fieldMaskString(fm *field_mask.FieldMask) string {
- if fm == nil {
- return ""
- }
- return fmt.Sprintf("%v", fm.GetPaths())
-}
-
-func TestFieldMaskFromRequestBody(t *testing.T) {
- for _, tc := range []struct {
- name string
- input string
- expected *field_mask.FieldMask
- expectedErr error
- }{
- {name: "empty", expected: newFieldMask()},
- {name: "simple", input: `{"foo":1, "bar":"baz"}`, expected: newFieldMask("foo", "bar")},
- {name: "nested", input: `{"foo": {"bar":1, "baz": 2}, "qux": 3}`, expected: newFieldMask("foo.bar", "foo.baz", "qux")},
- {name: "canonical", input: `{"f": {"b": {"d": 1, "x": 2}, "c": 1}}`, expected: newFieldMask("f.b.d", "f.b.x", "f.c")},
- } {
- t.Run(tc.name, func(t *testing.T) {
- actual, err := FieldMaskFromRequestBody(bytes.NewReader([]byte(tc.input)), nil)
- if !fieldMasksEqual(actual, tc.expected) {
- t.Errorf("want %v; got %v", fieldMaskString(tc.expected), fieldMaskString(actual))
- }
- if err != tc.expectedErr {
- t.Errorf("want %v; got %v", tc.expectedErr, err)
- }
- })
- }
-}
-
-// avoid compiler optimising benchmark away
-var result *field_mask.FieldMask
-
-func BenchmarkABEFieldMaskFromRequestBody(b *testing.B) {
- input := `{` +
- `"single_nested": {"name": "bar",` +
- ` "amount": 10,` +
- ` "ok": "TRUE"},` +
- `"uuid": "6EC2446F-7E89-4127-B3E6-5C05E6BECBA7",` +
- `"nested": [{"name": "bar",` +
- ` "amount": 10},` +
- ` {"name": "baz",` +
- ` "amount": 20}],` +
- `"float_value": 1.5,` +
- `"double_value": 2.5,` +
- `"int64_value": 4294967296,` +
- `"uint64_value": 9223372036854775807,` +
- `"int32_value": -2147483648,` +
- `"fixed64_value": 9223372036854775807,` +
- `"fixed32_value": 4294967295,` +
- `"bool_value": true,` +
- `"string_value": "strprefix/foo",` +
- `"bytes_value": "132456",` +
- `"uint32_value": 4294967295,` +
- `"enum_value": "ONE",` +
- `"path_enum_value": "DEF",` +
- `"nested_path_enum_value": "JKL",` +
- `"sfixed32_value": 2147483647,` +
- `"sfixed64_value": -4611686018427387904,` +
- `"sint32_value": 2147483647,` +
- `"sint64_value": 4611686018427387903,` +
- `"repeated_string_value": ["a", "b", "c"],` +
- `"oneof_value": {"oneof_string":"x"},` +
- `"map_value": {"a": "ONE",` +
- ` "b": "ZERO"},` +
- `"mapped_string_value": {"a": "x",` +
- ` "b": "y"},` +
- `"mapped_nested_value": {"a": {"name": "x", "amount": 1},` +
- ` "b": {"name": "y", "amount": 2}},` +
- `"nonConventionalNameValue": "camelCase",` +
- `"timestamp_value": "2016-05-10T10:19:13.123Z",` +
- `"repeated_enum_value": ["ONE", "ZERO"],` +
- `"repeated_enum_annotation": ["ONE", "ZERO"],` +
- `"enum_value_annotation": "ONE",` +
- `"repeated_string_annotation": ["a", "b"],` +
- `"repeated_nested_annotation": [{"name": "hoge",` +
- ` "amount": 10},` +
- ` {"name": "fuga",` +
- ` "amount": 20}],` +
- `"nested_annotation": {"name": "hoge",` +
- ` "amount": 10},` +
- `"int64_override_type": 12345` +
- `}`
- var r *field_mask.FieldMask
- var err error
- for i := 0; i < b.N; i++ {
- r, err = FieldMaskFromRequestBody(bytes.NewReader([]byte(input)), nil)
- }
- if err != nil {
- b.Error(err)
- }
- result = r
-}
-
-func BenchmarkNonStandardFieldMaskFromRequestBody(b *testing.B) {
- input := `{` +
- `"id": "foo",` +
- `"Num": 2,` +
- `"line_num": 3,` +
- `"langIdent": "bar",` +
- `"STATUS": "baz"` +
- `}`
- var r *field_mask.FieldMask
- var err error
- for i := 0; i < b.N; i++ {
- r, err = FieldMaskFromRequestBody(bytes.NewReader([]byte(input)), nil)
- }
- if err != nil {
- b.Error(err)
- }
- result = r
-}
diff --git a/gateway/runtime/handler.go b/gateway/runtime/handler.go
index 2af9006..d1e21df 100644
--- a/gateway/runtime/handler.go
+++ b/gateway/runtime/handler.go
@@ -1,20 +1,20 @@
package runtime
import (
- "errors"
+ "context"
"fmt"
"io"
"net/http"
"net/textproto"
+ "strings"
- "context"
- "github.com/golang/protobuf/proto"
- "github.com/grpc-ecosystem/grpc-gateway/internal"
+ "google.golang.org/genproto/googleapis/api/httpbody"
+ "google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
+ "google.golang.org/grpc/status"
+ "google.golang.org/protobuf/proto"
)
-var errEmptyResponse = errors.New("empty response")
-
// ForwardResponseStream forwards the stream from gRPC server to REST client.
func ForwardResponseStream(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, req *http.Request, recv func() (proto.Message, error), opts ...func(context.Context, http.ResponseWriter, proto.Message) error) {
f, ok := w.(http.Flusher)
@@ -33,7 +33,6 @@ func ForwardResponseStream(ctx context.Context, mux *ServeMux, marshaler Marshal
handleForwardResponseServerMetadata(w, mux, md)
w.Header().Set("Transfer-Encoding", "chunked")
- w.Header().Set("Content-Type", marshaler.ContentType())
if err := handleForwardResponseOptions(ctx, w, nil, opts); err != nil {
HTTPError(ctx, mux, marshaler, w, req, err)
return
@@ -61,7 +60,26 @@ func ForwardResponseStream(ctx context.Context, mux *ServeMux, marshaler Marshal
return
}
- buf, err := marshaler.Marshal(streamChunk(ctx, resp, mux.streamErrorHandler))
+ if !wroteHeader {
+ w.Header().Set("Content-Type", marshaler.ContentType(resp))
+ }
+
+ var buf []byte
+ httpBody, isHTTPBody := resp.(*httpbody.HttpBody)
+ switch {
+ case resp == nil:
+ buf, err = marshaler.Marshal(errorChunk(status.New(codes.Internal, "empty response")))
+ case isHTTPBody:
+ buf = httpBody.GetData()
+ default:
+ result := map[string]interface{}{"result": resp}
+ if rb, ok := resp.(responseBody); ok {
+ result["result"] = rb.XXX_ResponseBody()
+ }
+
+ buf, err = marshaler.Marshal(result)
+ }
+
if err != nil {
grpclog.Infof("Failed to marshal response chunk: %v", err)
handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err)
@@ -120,15 +138,22 @@ func ForwardResponseMessage(ctx context.Context, mux *ServeMux, marshaler Marsha
}
handleForwardResponseServerMetadata(w, mux, md)
- handleForwardResponseTrailerHeader(w, md)
- contentType := marshaler.ContentType()
- // Check marshaler on run time in order to keep backwards compatability
- // An interface param needs to be added to the ContentType() function on
- // the Marshal interface to be able to remove this check
- if httpBodyMarshaler, ok := marshaler.(*HTTPBodyMarshaler); ok {
- contentType = httpBodyMarshaler.ContentTypeFromMessage(resp)
+ // RFC 7230 https://tools.ietf.org/html/rfc7230#section-4.1.2
+ // Unless the request includes a TE header field indicating "trailers"
+ // is acceptable, as described in Section 4.3, a server SHOULD NOT
+ // generate trailer fields that it believes are necessary for the user
+ // agent to receive.
+ doForwardTrailers := requestAcceptsTrailers(req)
+
+ if doForwardTrailers {
+ handleForwardResponseTrailerHeader(w, md)
+ w.Header().Set("Transfer-Encoding", "chunked")
}
+
+ handleForwardResponseTrailerHeader(w, md)
+
+ contentType := marshaler.ContentType(resp)
w.Header().Set("Content-Type", contentType)
if err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil {
@@ -152,7 +177,14 @@ func ForwardResponseMessage(ctx context.Context, mux *ServeMux, marshaler Marsha
grpclog.Infof("Failed to write response: %v", err)
}
- handleForwardResponseTrailer(w, md)
+ if doForwardTrailers {
+ handleForwardResponseTrailer(w, md)
+ }
+}
+
+func requestAcceptsTrailers(req *http.Request) bool {
+ te := req.Header.Get("TE")
+ return strings.Contains(strings.ToLower(te), "trailers")
}
func handleForwardResponseOptions(ctx context.Context, w http.ResponseWriter, resp proto.Message, opts []func(context.Context, http.ResponseWriter, proto.Message) error) error {
@@ -169,11 +201,13 @@ func handleForwardResponseOptions(ctx context.Context, w http.ResponseWriter, re
}
func handleForwardResponseStreamError(ctx context.Context, wroteHeader bool, marshaler Marshaler, w http.ResponseWriter, req *http.Request, mux *ServeMux, err error) {
- serr := streamError(ctx, mux.streamErrorHandler, err)
+ st := mux.streamErrorHandler(ctx, err)
+ msg := errorChunk(st)
if !wroteHeader {
- w.WriteHeader(int(serr.HttpCode))
+ w.Header().Set("Content-Type", marshaler.ContentType(msg))
+ w.WriteHeader(HTTPStatusFromCode(st.Code()))
}
- buf, merr := marshaler.Marshal(errorChunk(serr))
+ buf, merr := marshaler.Marshal(msg)
if merr != nil {
grpclog.Infof("Failed to marshal an error: %v", merr)
return
@@ -184,26 +218,6 @@ func handleForwardResponseStreamError(ctx context.Context, wroteHeader bool, mar
}
}
-// streamChunk returns a chunk in a response stream for the given result. The
-// given errHandler is used to render an error chunk if result is nil.
-func streamChunk(ctx context.Context, result proto.Message, errHandler StreamErrorHandlerFunc) map[string]proto.Message {
- if result == nil {
- return errorChunk(streamError(ctx, errHandler, errEmptyResponse))
- }
- return map[string]proto.Message{"result": result}
-}
-
-// streamError returns the payload for the final message in a response stream
-// that represents the given err.
-func streamError(ctx context.Context, errHandler StreamErrorHandlerFunc, err error) *StreamError {
- serr := errHandler(ctx, err)
- if serr != nil {
- return serr
- }
- // TODO: log about misbehaving stream error handler?
- return DefaultHTTPStreamErrorHandler(ctx, err)
-}
-
-func errorChunk(err *StreamError) map[string]proto.Message {
- return map[string]proto.Message{"error": (*internal.StreamError)(err)}
+func errorChunk(st *status.Status) map[string]proto.Message {
+ return map[string]proto.Message{"error": st.Proto()}
}
diff --git a/gateway/runtime/handler_test.go b/gateway/runtime/handler_test.go
index a1dc65a..e3c74a7 100644
--- a/gateway/runtime/handler_test.go
+++ b/gateway/runtime/handler_test.go
@@ -1,31 +1,42 @@
package runtime_test
import (
+ "context"
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"
- "context"
- "github.com/golang/protobuf/proto"
- pb "github.com/binchencoder/ease-gateway/examples/proto"
- "github.com/grpc-ecosystem/grpc-gateway/internal"
- "github.com/binchencoder/ease-gateway/gateway/runtime"
- "google.golang.org/grpc"
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
+ "github.com/binchencoder/janus-gateway/gateway/runtime"
+ // pb "github.com/grpc-ecosystem/grpc-gateway/v2/runtime/internal/examplepb"
+ pb "github.com/binchencoder/janus-gateway/examples/internal/proto/examplepb"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
+ "google.golang.org/protobuf/proto"
)
+type fakeReponseBodyWrapper struct {
+ proto.Message
+}
+
+// XXX_ResponseBody returns id of SimpleMessage
+func (r fakeReponseBodyWrapper) XXX_ResponseBody() interface{} {
+ resp := r.Message.(*pb.SimpleMessage)
+ return resp.Id
+}
+
func TestForwardResponseStream(t *testing.T) {
type msg struct {
pb proto.Message
err error
}
tests := []struct {
- name string
- msgs []msg
- statusCode int
+ name string
+ msgs []msg
+ statusCode int
+ responseBody bool
}{{
name: "encoding",
msgs: []msg{
@@ -38,15 +49,31 @@ func TestForwardResponseStream(t *testing.T) {
statusCode: http.StatusOK,
}, {
name: "error",
- msgs: []msg{{nil, grpc.Errorf(codes.OutOfRange, "400")}},
+ msgs: []msg{{nil, status.Errorf(codes.OutOfRange, "400")}},
statusCode: http.StatusBadRequest,
}, {
name: "stream_error",
msgs: []msg{
{&pb.SimpleMessage{Id: "One"}, nil},
- {nil, grpc.Errorf(codes.OutOfRange, "400")},
+ {nil, status.Errorf(codes.OutOfRange, "400")},
},
statusCode: http.StatusOK,
+ }, {
+ name: "response body stream case",
+ msgs: []msg{
+ {fakeReponseBodyWrapper{&pb.SimpleMessage{Id: "One"}}, nil},
+ {fakeReponseBodyWrapper{&pb.SimpleMessage{Id: "Two"}}, nil},
+ },
+ responseBody: true,
+ statusCode: http.StatusOK,
+ }, {
+ name: "response body stream error case",
+ msgs: []msg{
+ {fakeReponseBodyWrapper{&pb.SimpleMessage{Id: "One"}}, nil},
+ {nil, status.Errorf(codes.OutOfRange, "400")},
+ },
+ responseBody: true,
+ statusCode: http.StatusOK,
}}
newTestRecv := func(t *testing.T, msgs []msg) func() (proto.Message, error) {
@@ -84,6 +111,9 @@ func TestForwardResponseStream(t *testing.T) {
t.Errorf("Failed to read response body with %v", err)
}
w.Body.Close()
+ if len(body) > 0 && w.Header.Get("Content-Type") != "application/json" {
+ t.Errorf("Content-Type %s want application/json", w.Header.Get("Content-Type"))
+ }
var want []byte
for i, msg := range tt.msgs {
@@ -92,16 +122,9 @@ func TestForwardResponseStream(t *testing.T) {
// Skip non-stream errors
t.Skip("checking error encodings")
}
- st, _ := status.FromError(msg.err)
- httpCode := runtime.HTTPStatusFromCode(st.Code())
+ st := status.Convert(msg.err)
b, err := marshaler.Marshal(map[string]proto.Message{
- "error": &internal.StreamError{
- GrpcCode: int32(st.Code()),
- HttpCode: int32(httpCode),
- Message: st.Message(),
- HttpStatus: http.StatusText(httpCode),
- Details: st.Proto().GetDetails(),
- },
+ "error": st.Proto(),
})
if err != nil {
t.Errorf("marshaler.Marshal() failed %v", err)
@@ -113,7 +136,22 @@ func TestForwardResponseStream(t *testing.T) {
return
}
- b, err := marshaler.Marshal(map[string]proto.Message{"result": msg.pb})
+
+ var b []byte
+
+ if tt.responseBody {
+ // responseBody interface is in runtime package and test is in runtime_test package. hence can't use responseBody directly
+ // So type casting to fakeReponseBodyWrapper struct to verify the data.
+ rb, ok := msg.pb.(fakeReponseBodyWrapper)
+ if !ok {
+ t.Errorf("stream responseBody failed %v", err)
+ }
+
+ b, err = marshaler.Marshal(map[string]interface{}{"result": rb.XXX_ResponseBody()})
+ } else {
+ b, err = marshaler.Marshal(map[string]interface{}{"result": msg.pb})
+ }
+
if err != nil {
t.Errorf("marshaler.Marshal() failed %v", err)
}
@@ -137,7 +175,7 @@ func (c *CustomMarshaler) Marshal(v interface{}) ([]byte, error) { return c
func (c *CustomMarshaler) Unmarshal(data []byte, v interface{}) error { return c.m.Unmarshal(data, v) }
func (c *CustomMarshaler) NewDecoder(r io.Reader) runtime.Decoder { return c.m.NewDecoder(r) }
func (c *CustomMarshaler) NewEncoder(w io.Writer) runtime.Encoder { return c.m.NewEncoder(w) }
-func (c *CustomMarshaler) ContentType() string { return c.m.ContentType() }
+func (c *CustomMarshaler) ContentType(v interface{}) string { return "Custom-Content-Type" }
func TestForwardResponseStreamCustomMarshaler(t *testing.T) {
type msg struct {
@@ -160,13 +198,13 @@ func TestForwardResponseStreamCustomMarshaler(t *testing.T) {
statusCode: http.StatusOK,
}, {
name: "error",
- msgs: []msg{{nil, grpc.Errorf(codes.OutOfRange, "400")}},
+ msgs: []msg{{nil, status.Errorf(codes.OutOfRange, "400")}},
statusCode: http.StatusBadRequest,
}, {
name: "stream_error",
msgs: []msg{
{&pb.SimpleMessage{Id: "One"}, nil},
- {nil, grpc.Errorf(codes.OutOfRange, "400")},
+ {nil, status.Errorf(codes.OutOfRange, "400")},
},
statusCode: http.StatusOK,
}}
@@ -206,6 +244,9 @@ func TestForwardResponseStreamCustomMarshaler(t *testing.T) {
t.Errorf("Failed to read response body with %v", err)
}
w.Body.Close()
+ if len(body) > 0 && w.Header.Get("Content-Type") != "Custom-Content-Type" {
+ t.Errorf("Content-Type %s want Custom-Content-Type", w.Header.Get("Content-Type"))
+ }
var want []byte
for _, msg := range tt.msgs {
@@ -226,3 +267,56 @@ func TestForwardResponseStreamCustomMarshaler(t *testing.T) {
})
}
}
+
+func TestForwardResponseMessage(t *testing.T) {
+ msg := &pb.SimpleMessage{Id: "One"}
+ tests := []struct {
+ name string
+ marshaler runtime.Marshaler
+ contentType string
+ }{{
+ name: "standard marshaler",
+ marshaler: &runtime.JSONPb{},
+ contentType: "application/json",
+ }, {
+ name: "httpbody marshaler",
+ marshaler: &runtime.HTTPBodyMarshaler{&runtime.JSONPb{}},
+ contentType: "application/json",
+ }, {
+ name: "custom marshaler",
+ marshaler: &CustomMarshaler{&runtime.JSONPb{}},
+ contentType: "Custom-Content-Type",
+ }}
+
+ ctx := runtime.NewServerMetadataContext(context.Background(), runtime.ServerMetadata{})
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ req := httptest.NewRequest("GET", "http://example.com/foo", nil)
+ resp := httptest.NewRecorder()
+
+ runtime.ForwardResponseMessage(ctx, runtime.NewServeMux(), tt.marshaler, resp, req, msg)
+
+ w := resp.Result()
+ if w.StatusCode != http.StatusOK {
+ t.Errorf("StatusCode %d want %d", w.StatusCode, http.StatusOK)
+ }
+ if h := w.Header.Get("Content-Type"); h != tt.contentType {
+ t.Errorf("Content-Type %v want %v", h, tt.contentType)
+ }
+ body, err := ioutil.ReadAll(w.Body)
+ if err != nil {
+ t.Errorf("Failed to read response body with %v", err)
+ }
+ w.Body.Close()
+
+ want, err := tt.marshaler.Marshal(msg)
+ if err != nil {
+ t.Errorf("marshaler.Marshal() failed %v", err)
+ }
+
+ if string(body) != string(want) {
+ t.Errorf("ForwardResponseMessage() = \"%s\" want \"%s\"", body, want)
+ }
+ })
+ }
+}
diff --git a/gateway/runtime/hook.go b/gateway/runtime/hook.go
index 8db1721..784018f 100644
--- a/gateway/runtime/hook.go
+++ b/gateway/runtime/hook.go
@@ -3,8 +3,8 @@ package runtime
import (
"net/http"
- "github.com/golang/protobuf/proto"
"golang.org/x/net/context"
+ "google.golang.org/protobuf/proto"
pb "github.com/binchencoder/skylb-api/proto"
)
diff --git a/gateway/runtime/hook_test.go b/gateway/runtime/hook_test.go
index 4040e28..9541752 100755
--- a/gateway/runtime/hook_test.go
+++ b/gateway/runtime/hook_test.go
@@ -4,8 +4,8 @@ import (
"net/http"
"testing"
- "github.com/golang/protobuf/proto"
"golang.org/x/net/context"
+ "google.golang.org/protobuf/proto"
)
type GatewayServiceHookFake struct {
diff --git a/gateway/runtime/internal/examplepb/BUILD.bazel b/gateway/runtime/internal/examplepb/BUILD.bazel
new file mode 100644
index 0000000..84ae71c
--- /dev/null
+++ b/gateway/runtime/internal/examplepb/BUILD.bazel
@@ -0,0 +1,47 @@
+load("@rules_proto//proto:defs.bzl", "proto_library")
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
+
+# gazelle:exclude non_standard_names_grpc.pb.go
+
+package(default_visibility = ["//visibility:public"])
+
+proto_library(
+ name = "examplepb_proto",
+ srcs = [
+ "proto3.proto",
+ ],
+ deps = [
+ "@com_google_protobuf//:any_proto",
+ "@com_google_protobuf//:duration_proto",
+ "@com_google_protobuf//:empty_proto",
+ "@com_google_protobuf//:field_mask_proto",
+ "@com_google_protobuf//:struct_proto",
+ "@com_google_protobuf//:timestamp_proto",
+ "@com_google_protobuf//:wrappers_proto",
+ "@go_googleapis//google/api:annotations_proto",
+ ],
+)
+
+go_proto_library(
+ name = "examplepb_go_proto",
+ compilers = [
+ "//:go_apiv2",
+ "//:go_grpc",
+ ],
+ importpath = "github.com/binchencoder/janus-gateway/gateway/runtime/internal/examplepb",
+ proto = ":examplepb_proto",
+ deps = ["@go_googleapis//google/api:annotations_go_proto"],
+)
+
+go_library(
+ name = "examplepb",
+ embed = [":examplepb_go_proto"],
+ importpath = "github.com/binchencoder/janus-gateway/gateway/runtime/internal/examplepb",
+)
+
+alias(
+ name = "go_default_library",
+ actual = ":examplepb",
+ visibility = ["//runtime:__subpackages__"],
+)
diff --git a/gateway/runtime/internal/examplepb/proto3.pb.go b/gateway/runtime/internal/examplepb/proto3.pb.go
new file mode 100755
index 0000000..3aa2d7e
--- /dev/null
+++ b/gateway/runtime/internal/examplepb/proto3.pb.go
@@ -0,0 +1,918 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.27.1
+// protoc v3.19.4
+// source: gateway/runtime/internal/examplepb/proto3.proto
+
+package examplepb
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ durationpb "google.golang.org/protobuf/types/known/durationpb"
+ fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb"
+ timestamppb "google.golang.org/protobuf/types/known/timestamppb"
+ wrapperspb "google.golang.org/protobuf/types/known/wrapperspb"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type EnumValue int32
+
+const (
+ EnumValue_X EnumValue = 0
+ EnumValue_Y EnumValue = 1
+ EnumValue_Z EnumValue = 2
+)
+
+// Enum value maps for EnumValue.
+var (
+ EnumValue_name = map[int32]string{
+ 0: "X",
+ 1: "Y",
+ 2: "Z",
+ }
+ EnumValue_value = map[string]int32{
+ "X": 0,
+ "Y": 1,
+ "Z": 2,
+ }
+)
+
+func (x EnumValue) Enum() *EnumValue {
+ p := new(EnumValue)
+ *p = x
+ return p
+}
+
+func (x EnumValue) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (EnumValue) Descriptor() protoreflect.EnumDescriptor {
+ return file_gateway_runtime_internal_examplepb_proto3_proto_enumTypes[0].Descriptor()
+}
+
+func (EnumValue) Type() protoreflect.EnumType {
+ return &file_gateway_runtime_internal_examplepb_proto3_proto_enumTypes[0]
+}
+
+func (x EnumValue) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use EnumValue.Descriptor instead.
+func (EnumValue) EnumDescriptor() ([]byte, []int) {
+ return file_gateway_runtime_internal_examplepb_proto3_proto_rawDescGZIP(), []int{0}
+}
+
+type Proto3Message struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Nested *Proto3Message `protobuf:"bytes,41,opt,name=nested,proto3" json:"nested,omitempty"`
+ FloatValue float32 `protobuf:"fixed32,42,opt,name=float_value,json=floatValue,proto3" json:"float_value,omitempty"`
+ DoubleValue float64 `protobuf:"fixed64,43,opt,name=double_value,json=doubleValue,proto3" json:"double_value,omitempty"`
+ Int64Value int64 `protobuf:"varint,3,opt,name=int64_value,json=int64Value,proto3" json:"int64_value,omitempty"`
+ Int32Value int32 `protobuf:"varint,4,opt,name=int32_value,json=int32Value,proto3" json:"int32_value,omitempty"`
+ Uint64Value uint64 `protobuf:"varint,5,opt,name=uint64_value,json=uint64Value,proto3" json:"uint64_value,omitempty"`
+ Uint32Value uint32 `protobuf:"varint,6,opt,name=uint32_value,json=uint32Value,proto3" json:"uint32_value,omitempty"`
+ BoolValue bool `protobuf:"varint,7,opt,name=bool_value,json=boolValue,proto3" json:"bool_value,omitempty"`
+ StringValue string `protobuf:"bytes,8,opt,name=string_value,json=stringValue,proto3" json:"string_value,omitempty"`
+ BytesValue []byte `protobuf:"bytes,9,opt,name=bytes_value,json=bytesValue,proto3" json:"bytes_value,omitempty"`
+ RepeatedValue []string `protobuf:"bytes,10,rep,name=repeated_value,json=repeatedValue,proto3" json:"repeated_value,omitempty"`
+ RepeatedMessage []*wrapperspb.UInt64Value `protobuf:"bytes,44,rep,name=repeated_message,json=repeatedMessage,proto3" json:"repeated_message,omitempty"`
+ EnumValue EnumValue `protobuf:"varint,11,opt,name=enum_value,json=enumValue,proto3,enum=janus.gateway.runtime.internal.examplepb.EnumValue" json:"enum_value,omitempty"`
+ RepeatedEnum []EnumValue `protobuf:"varint,12,rep,packed,name=repeated_enum,json=repeatedEnum,proto3,enum=janus.gateway.runtime.internal.examplepb.EnumValue" json:"repeated_enum,omitempty"`
+ TimestampValue *timestamppb.Timestamp `protobuf:"bytes,13,opt,name=timestamp_value,json=timestampValue,proto3" json:"timestamp_value,omitempty"`
+ DurationValue *durationpb.Duration `protobuf:"bytes,14,opt,name=duration_value,json=durationValue,proto3" json:"duration_value,omitempty"`
+ FieldmaskValue *fieldmaskpb.FieldMask `protobuf:"bytes,15,opt,name=fieldmask_value,json=fieldmaskValue,proto3" json:"fieldmask_value,omitempty"`
+ // Types that are assignable to OneofValue:
+ // *Proto3Message_OneofBoolValue
+ // *Proto3Message_OneofStringValue
+ OneofValue isProto3Message_OneofValue `protobuf_oneof:"oneof_value"`
+ // Types that are assignable to NestedOneofValue:
+ // *Proto3Message_NestedOneofValueOne
+ NestedOneofValue isProto3Message_NestedOneofValue `protobuf_oneof:"nested_oneof_value"`
+ WrapperDoubleValue *wrapperspb.DoubleValue `protobuf:"bytes,17,opt,name=wrapper_double_value,json=wrapperDoubleValue,proto3" json:"wrapper_double_value,omitempty"`
+ WrapperFloatValue *wrapperspb.FloatValue `protobuf:"bytes,18,opt,name=wrapper_float_value,json=wrapperFloatValue,proto3" json:"wrapper_float_value,omitempty"`
+ WrapperInt64Value *wrapperspb.Int64Value `protobuf:"bytes,19,opt,name=wrapper_int64_value,json=wrapperInt64Value,proto3" json:"wrapper_int64_value,omitempty"`
+ WrapperInt32Value *wrapperspb.Int32Value `protobuf:"bytes,20,opt,name=wrapper_int32_value,json=wrapperInt32Value,proto3" json:"wrapper_int32_value,omitempty"`
+ WrapperUInt64Value *wrapperspb.UInt64Value `protobuf:"bytes,21,opt,name=wrapper_u_int64_value,json=wrapperUInt64Value,proto3" json:"wrapper_u_int64_value,omitempty"`
+ WrapperUInt32Value *wrapperspb.UInt32Value `protobuf:"bytes,22,opt,name=wrapper_u_int32_value,json=wrapperUInt32Value,proto3" json:"wrapper_u_int32_value,omitempty"`
+ WrapperBoolValue *wrapperspb.BoolValue `protobuf:"bytes,23,opt,name=wrapper_bool_value,json=wrapperBoolValue,proto3" json:"wrapper_bool_value,omitempty"`
+ WrapperStringValue *wrapperspb.StringValue `protobuf:"bytes,24,opt,name=wrapper_string_value,json=wrapperStringValue,proto3" json:"wrapper_string_value,omitempty"`
+ WrapperBytesValue *wrapperspb.BytesValue `protobuf:"bytes,25,opt,name=wrapper_bytes_value,json=wrapperBytesValue,proto3" json:"wrapper_bytes_value,omitempty"`
+ MapValue map[string]string `protobuf:"bytes,26,rep,name=map_value,json=mapValue,proto3" json:"map_value,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ MapValue2 map[string]int32 `protobuf:"bytes,27,rep,name=map_value2,json=mapValue2,proto3" json:"map_value2,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"`
+ MapValue3 map[int32]string `protobuf:"bytes,28,rep,name=map_value3,json=mapValue3,proto3" json:"map_value3,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ MapValue4 map[string]int64 `protobuf:"bytes,29,rep,name=map_value4,json=mapValue4,proto3" json:"map_value4,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"`
+ MapValue5 map[int64]string `protobuf:"bytes,30,rep,name=map_value5,json=mapValue5,proto3" json:"map_value5,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ MapValue6 map[string]uint32 `protobuf:"bytes,31,rep,name=map_value6,json=mapValue6,proto3" json:"map_value6,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"`
+ MapValue7 map[uint32]string `protobuf:"bytes,32,rep,name=map_value7,json=mapValue7,proto3" json:"map_value7,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ MapValue8 map[string]uint64 `protobuf:"bytes,33,rep,name=map_value8,json=mapValue8,proto3" json:"map_value8,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"`
+ MapValue9 map[uint64]string `protobuf:"bytes,34,rep,name=map_value9,json=mapValue9,proto3" json:"map_value9,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ MapValue10 map[string]float32 `protobuf:"bytes,35,rep,name=map_value10,json=mapValue10,proto3" json:"map_value10,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"fixed32,2,opt,name=value,proto3"`
+ MapValue12 map[string]float64 `protobuf:"bytes,37,rep,name=map_value12,json=mapValue12,proto3" json:"map_value12,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"fixed64,2,opt,name=value,proto3"`
+ MapValue14 map[string]bool `protobuf:"bytes,39,rep,name=map_value14,json=mapValue14,proto3" json:"map_value14,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"`
+ MapValue15 map[bool]string `protobuf:"bytes,40,rep,name=map_value15,json=mapValue15,proto3" json:"map_value15,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ MapValue16 map[string]*wrapperspb.UInt64Value `protobuf:"bytes,45,rep,name=map_value16,json=mapValue16,proto3" json:"map_value16,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+}
+
+func (x *Proto3Message) Reset() {
+ *x = Proto3Message{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_gateway_runtime_internal_examplepb_proto3_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Proto3Message) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Proto3Message) ProtoMessage() {}
+
+func (x *Proto3Message) ProtoReflect() protoreflect.Message {
+ mi := &file_gateway_runtime_internal_examplepb_proto3_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Proto3Message.ProtoReflect.Descriptor instead.
+func (*Proto3Message) Descriptor() ([]byte, []int) {
+ return file_gateway_runtime_internal_examplepb_proto3_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Proto3Message) GetNested() *Proto3Message {
+ if x != nil {
+ return x.Nested
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetFloatValue() float32 {
+ if x != nil {
+ return x.FloatValue
+ }
+ return 0
+}
+
+func (x *Proto3Message) GetDoubleValue() float64 {
+ if x != nil {
+ return x.DoubleValue
+ }
+ return 0
+}
+
+func (x *Proto3Message) GetInt64Value() int64 {
+ if x != nil {
+ return x.Int64Value
+ }
+ return 0
+}
+
+func (x *Proto3Message) GetInt32Value() int32 {
+ if x != nil {
+ return x.Int32Value
+ }
+ return 0
+}
+
+func (x *Proto3Message) GetUint64Value() uint64 {
+ if x != nil {
+ return x.Uint64Value
+ }
+ return 0
+}
+
+func (x *Proto3Message) GetUint32Value() uint32 {
+ if x != nil {
+ return x.Uint32Value
+ }
+ return 0
+}
+
+func (x *Proto3Message) GetBoolValue() bool {
+ if x != nil {
+ return x.BoolValue
+ }
+ return false
+}
+
+func (x *Proto3Message) GetStringValue() string {
+ if x != nil {
+ return x.StringValue
+ }
+ return ""
+}
+
+func (x *Proto3Message) GetBytesValue() []byte {
+ if x != nil {
+ return x.BytesValue
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetRepeatedValue() []string {
+ if x != nil {
+ return x.RepeatedValue
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetRepeatedMessage() []*wrapperspb.UInt64Value {
+ if x != nil {
+ return x.RepeatedMessage
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetEnumValue() EnumValue {
+ if x != nil {
+ return x.EnumValue
+ }
+ return EnumValue_X
+}
+
+func (x *Proto3Message) GetRepeatedEnum() []EnumValue {
+ if x != nil {
+ return x.RepeatedEnum
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetTimestampValue() *timestamppb.Timestamp {
+ if x != nil {
+ return x.TimestampValue
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetDurationValue() *durationpb.Duration {
+ if x != nil {
+ return x.DurationValue
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetFieldmaskValue() *fieldmaskpb.FieldMask {
+ if x != nil {
+ return x.FieldmaskValue
+ }
+ return nil
+}
+
+func (m *Proto3Message) GetOneofValue() isProto3Message_OneofValue {
+ if m != nil {
+ return m.OneofValue
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetOneofBoolValue() bool {
+ if x, ok := x.GetOneofValue().(*Proto3Message_OneofBoolValue); ok {
+ return x.OneofBoolValue
+ }
+ return false
+}
+
+func (x *Proto3Message) GetOneofStringValue() string {
+ if x, ok := x.GetOneofValue().(*Proto3Message_OneofStringValue); ok {
+ return x.OneofStringValue
+ }
+ return ""
+}
+
+func (m *Proto3Message) GetNestedOneofValue() isProto3Message_NestedOneofValue {
+ if m != nil {
+ return m.NestedOneofValue
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetNestedOneofValueOne() *Proto3Message {
+ if x, ok := x.GetNestedOneofValue().(*Proto3Message_NestedOneofValueOne); ok {
+ return x.NestedOneofValueOne
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetWrapperDoubleValue() *wrapperspb.DoubleValue {
+ if x != nil {
+ return x.WrapperDoubleValue
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetWrapperFloatValue() *wrapperspb.FloatValue {
+ if x != nil {
+ return x.WrapperFloatValue
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetWrapperInt64Value() *wrapperspb.Int64Value {
+ if x != nil {
+ return x.WrapperInt64Value
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetWrapperInt32Value() *wrapperspb.Int32Value {
+ if x != nil {
+ return x.WrapperInt32Value
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetWrapperUInt64Value() *wrapperspb.UInt64Value {
+ if x != nil {
+ return x.WrapperUInt64Value
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetWrapperUInt32Value() *wrapperspb.UInt32Value {
+ if x != nil {
+ return x.WrapperUInt32Value
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetWrapperBoolValue() *wrapperspb.BoolValue {
+ if x != nil {
+ return x.WrapperBoolValue
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetWrapperStringValue() *wrapperspb.StringValue {
+ if x != nil {
+ return x.WrapperStringValue
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetWrapperBytesValue() *wrapperspb.BytesValue {
+ if x != nil {
+ return x.WrapperBytesValue
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetMapValue() map[string]string {
+ if x != nil {
+ return x.MapValue
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetMapValue2() map[string]int32 {
+ if x != nil {
+ return x.MapValue2
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetMapValue3() map[int32]string {
+ if x != nil {
+ return x.MapValue3
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetMapValue4() map[string]int64 {
+ if x != nil {
+ return x.MapValue4
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetMapValue5() map[int64]string {
+ if x != nil {
+ return x.MapValue5
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetMapValue6() map[string]uint32 {
+ if x != nil {
+ return x.MapValue6
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetMapValue7() map[uint32]string {
+ if x != nil {
+ return x.MapValue7
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetMapValue8() map[string]uint64 {
+ if x != nil {
+ return x.MapValue8
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetMapValue9() map[uint64]string {
+ if x != nil {
+ return x.MapValue9
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetMapValue10() map[string]float32 {
+ if x != nil {
+ return x.MapValue10
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetMapValue12() map[string]float64 {
+ if x != nil {
+ return x.MapValue12
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetMapValue14() map[string]bool {
+ if x != nil {
+ return x.MapValue14
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetMapValue15() map[bool]string {
+ if x != nil {
+ return x.MapValue15
+ }
+ return nil
+}
+
+func (x *Proto3Message) GetMapValue16() map[string]*wrapperspb.UInt64Value {
+ if x != nil {
+ return x.MapValue16
+ }
+ return nil
+}
+
+type isProto3Message_OneofValue interface {
+ isProto3Message_OneofValue()
+}
+
+type Proto3Message_OneofBoolValue struct {
+ OneofBoolValue bool `protobuf:"varint,1,opt,name=oneof_bool_value,json=oneofBoolValue,proto3,oneof"`
+}
+
+type Proto3Message_OneofStringValue struct {
+ OneofStringValue string `protobuf:"bytes,2,opt,name=oneof_string_value,json=oneofStringValue,proto3,oneof"`
+}
+
+func (*Proto3Message_OneofBoolValue) isProto3Message_OneofValue() {}
+
+func (*Proto3Message_OneofStringValue) isProto3Message_OneofValue() {}
+
+type isProto3Message_NestedOneofValue interface {
+ isProto3Message_NestedOneofValue()
+}
+
+type Proto3Message_NestedOneofValueOne struct {
+ NestedOneofValueOne *Proto3Message `protobuf:"bytes,46,opt,name=nested_oneof_value_one,json=nestedOneofValueOne,proto3,oneof"`
+}
+
+func (*Proto3Message_NestedOneofValueOne) isProto3Message_NestedOneofValue() {}
+
+var File_gateway_runtime_internal_examplepb_proto3_proto protoreflect.FileDescriptor
+
+var file_gateway_runtime_internal_examplepb_proto3_proto_rawDesc = []byte{
+ 0x0a, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d,
+ 0x65, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70,
+ 0x6c, 0x65, 0x70, 0x62, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x12, 0x27, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e,
+ 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
+ 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67,
+ 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67,
+ 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c,
+ 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f,
+ 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69,
+ 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67,
+ 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77,
+ 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xcc, 0x20,
+ 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12,
+ 0x4e, 0x0a, 0x06, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x18, 0x29, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x36, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x72,
+ 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e,
+ 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x06, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x12,
+ 0x1f, 0x0a, 0x0b, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x2a,
+ 0x20, 0x01, 0x28, 0x02, 0x52, 0x0a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65,
+ 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65,
+ 0x18, 0x2b, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61,
+ 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x76, 0x61, 0x6c,
+ 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x56,
+ 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x76, 0x61,
+ 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x33, 0x32,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f,
+ 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x75, 0x69, 0x6e,
+ 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x69, 0x6e, 0x74,
+ 0x33, 0x32, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b,
+ 0x75, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62,
+ 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52,
+ 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74,
+ 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a,
+ 0x0b, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x09, 0x20, 0x01,
+ 0x28, 0x0c, 0x52, 0x0a, 0x62, 0x79, 0x74, 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x25,
+ 0x0a, 0x0e, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65,
+ 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x47, 0x0a, 0x10, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65,
+ 0x64, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x2c, 0x20, 0x03, 0x28, 0x0b, 0x32,
+ 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+ 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x72,
+ 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x51,
+ 0x0a, 0x0a, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0b, 0x20, 0x01,
+ 0x28, 0x0e, 0x32, 0x32, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61,
+ 0x79, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
+ 0x61, 0x6c, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x45, 0x6e, 0x75,
+ 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x65, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75,
+ 0x65, 0x12, 0x57, 0x0a, 0x0d, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x65, 0x6e,
+ 0x75, 0x6d, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x32, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e,
+ 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e,
+ 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
+ 0x70, 0x62, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x72, 0x65,
+ 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x43, 0x0a, 0x0f, 0x74, 0x69,
+ 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0d, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
+ 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12,
+ 0x40, 0x0a, 0x0e, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x76, 0x61, 0x6c, 0x75,
+ 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69,
+ 0x6f, 0x6e, 0x52, 0x0d, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x61, 0x6c, 0x75,
+ 0x65, 0x12, 0x43, 0x0a, 0x0f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x6d, 0x61, 0x73, 0x6b, 0x5f, 0x76,
+ 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f,
+ 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65,
+ 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0e, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x6d, 0x61, 0x73,
+ 0x6b, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x5f,
+ 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08,
+ 0x48, 0x00, 0x52, 0x0e, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c,
+ 0x75, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x5f, 0x73, 0x74, 0x72, 0x69,
+ 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00,
+ 0x52, 0x10, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c,
+ 0x75, 0x65, 0x12, 0x6d, 0x0a, 0x16, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x6e, 0x65,
+ 0x6f, 0x66, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6f, 0x6e, 0x65, 0x18, 0x2e, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61,
+ 0x79, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
+ 0x61, 0x6c, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x6f,
+ 0x74, 0x6f, 0x33, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x01, 0x52, 0x13, 0x6e, 0x65,
+ 0x73, 0x74, 0x65, 0x64, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x6e,
+ 0x65, 0x12, 0x4e, 0x0a, 0x14, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x5f, 0x64, 0x6f, 0x75,
+ 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+ 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x77,
+ 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75,
+ 0x65, 0x12, 0x4b, 0x0a, 0x13, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x5f, 0x66, 0x6c, 0x6f,
+ 0x61, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b,
+ 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+ 0x2e, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x11, 0x77, 0x72, 0x61,
+ 0x70, 0x70, 0x65, 0x72, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4b,
+ 0x0a, 0x13, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f,
+ 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f,
+ 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e,
+ 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x11, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65,
+ 0x72, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4b, 0x0a, 0x13, 0x77,
+ 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x76, 0x61, 0x6c,
+ 0x75, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+ 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x11, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x49, 0x6e,
+ 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4f, 0x0a, 0x15, 0x77, 0x72, 0x61, 0x70,
+ 0x70, 0x65, 0x72, 0x5f, 0x75, 0x5f, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x76, 0x61, 0x6c, 0x75,
+ 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x55, 0x49,
+ 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4f, 0x0a, 0x15, 0x77, 0x72, 0x61,
+ 0x70, 0x70, 0x65, 0x72, 0x5f, 0x75, 0x5f, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x76, 0x61, 0x6c,
+ 0x75, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+ 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33,
+ 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x55,
+ 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x48, 0x0a, 0x12, 0x77, 0x72,
+ 0x61, 0x70, 0x70, 0x65, 0x72, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65,
+ 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c,
+ 0x75, 0x65, 0x52, 0x10, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x42, 0x6f, 0x6f, 0x6c, 0x56,
+ 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4e, 0x0a, 0x14, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x5f,
+ 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x18, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65,
+ 0x52, 0x12, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56,
+ 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4b, 0x0a, 0x13, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x5f,
+ 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x19, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x62, 0x75, 0x66, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x11,
+ 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x42, 0x79, 0x74, 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75,
+ 0x65, 0x12, 0x61, 0x0a, 0x09, 0x6d, 0x61, 0x70, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x1a,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x44, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65,
+ 0x77, 0x61, 0x79, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65,
+ 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x50,
+ 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x61, 0x70,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x61, 0x70, 0x56,
+ 0x61, 0x6c, 0x75, 0x65, 0x12, 0x64, 0x0a, 0x0a, 0x6d, 0x61, 0x70, 0x5f, 0x76, 0x61, 0x6c, 0x75,
+ 0x65, 0x32, 0x18, 0x1b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e,
+ 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e,
+ 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
+ 0x70, 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+ 0x2e, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x32, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
+ 0x09, 0x6d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x32, 0x12, 0x64, 0x0a, 0x0a, 0x6d, 0x61,
+ 0x70, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x33, 0x18, 0x1c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x45,
+ 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x72, 0x75,
+ 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x65,
+ 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4d,
+ 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x33,
+ 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x6d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x33,
+ 0x12, 0x64, 0x0a, 0x0a, 0x6d, 0x61, 0x70, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x34, 0x18, 0x1d,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65,
+ 0x77, 0x61, 0x79, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65,
+ 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x50,
+ 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x61, 0x70,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x34, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x6d, 0x61, 0x70,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x34, 0x12, 0x64, 0x0a, 0x0a, 0x6d, 0x61, 0x70, 0x5f, 0x76, 0x61,
+ 0x6c, 0x75, 0x65, 0x35, 0x18, 0x1e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x65, 0x61, 0x73,
+ 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d,
+ 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70,
+ 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4d, 0x65, 0x73, 0x73, 0x61,
+ 0x67, 0x65, 0x2e, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x35, 0x45, 0x6e, 0x74, 0x72,
+ 0x79, 0x52, 0x09, 0x6d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x35, 0x12, 0x64, 0x0a, 0x0a,
+ 0x6d, 0x61, 0x70, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x36, 0x18, 0x1f, 0x20, 0x03, 0x28, 0x0b,
+ 0x32, 0x45, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e,
+ 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
+ 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f,
+ 0x33, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75,
+ 0x65, 0x36, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x6d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75,
+ 0x65, 0x36, 0x12, 0x64, 0x0a, 0x0a, 0x6d, 0x61, 0x70, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x37,
+ 0x18, 0x20, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x67, 0x61,
+ 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x69, 0x6e,
+ 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62,
+ 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d,
+ 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x37, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x6d,
+ 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x37, 0x12, 0x64, 0x0a, 0x0a, 0x6d, 0x61, 0x70, 0x5f,
+ 0x76, 0x61, 0x6c, 0x75, 0x65, 0x38, 0x18, 0x21, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x65,
+ 0x61, 0x73, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x72, 0x75, 0x6e, 0x74,
+ 0x69, 0x6d, 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x65, 0x78, 0x61,
+ 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4d, 0x65, 0x73,
+ 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x38, 0x45, 0x6e,
+ 0x74, 0x72, 0x79, 0x52, 0x09, 0x6d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x38, 0x12, 0x64,
+ 0x0a, 0x0a, 0x6d, 0x61, 0x70, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x39, 0x18, 0x22, 0x20, 0x03,
+ 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61,
+ 0x79, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
+ 0x61, 0x6c, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x6f,
+ 0x74, 0x6f, 0x33, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x61, 0x70, 0x56, 0x61,
+ 0x6c, 0x75, 0x65, 0x39, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x6d, 0x61, 0x70, 0x56, 0x61,
+ 0x6c, 0x75, 0x65, 0x39, 0x12, 0x67, 0x0a, 0x0b, 0x6d, 0x61, 0x70, 0x5f, 0x76, 0x61, 0x6c, 0x75,
+ 0x65, 0x31, 0x30, 0x18, 0x23, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x46, 0x2e, 0x65, 0x61, 0x73, 0x65,
+ 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65,
+ 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
+ 0x65, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
+ 0x65, 0x2e, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x30, 0x45, 0x6e, 0x74, 0x72,
+ 0x79, 0x52, 0x0a, 0x6d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x30, 0x12, 0x67, 0x0a,
+ 0x0b, 0x6d, 0x61, 0x70, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x32, 0x18, 0x25, 0x20, 0x03,
+ 0x28, 0x0b, 0x32, 0x46, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61,
+ 0x79, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
+ 0x61, 0x6c, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x6f,
+ 0x74, 0x6f, 0x33, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x61, 0x70, 0x56, 0x61,
+ 0x6c, 0x75, 0x65, 0x31, 0x32, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x6d, 0x61, 0x70, 0x56,
+ 0x61, 0x6c, 0x75, 0x65, 0x31, 0x32, 0x12, 0x67, 0x0a, 0x0b, 0x6d, 0x61, 0x70, 0x5f, 0x76, 0x61,
+ 0x6c, 0x75, 0x65, 0x31, 0x34, 0x18, 0x27, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x46, 0x2e, 0x65, 0x61,
+ 0x73, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69,
+ 0x6d, 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x65, 0x78, 0x61, 0x6d,
+ 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4d, 0x65, 0x73, 0x73,
+ 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x34, 0x45, 0x6e,
+ 0x74, 0x72, 0x79, 0x52, 0x0a, 0x6d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x34, 0x12,
+ 0x67, 0x0a, 0x0b, 0x6d, 0x61, 0x70, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x35, 0x18, 0x28,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x46, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65,
+ 0x77, 0x61, 0x79, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65,
+ 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x50,
+ 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x61, 0x70,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x35, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x6d, 0x61,
+ 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x35, 0x12, 0x67, 0x0a, 0x0b, 0x6d, 0x61, 0x70, 0x5f,
+ 0x76, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x36, 0x18, 0x2d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x46, 0x2e,
+ 0x65, 0x61, 0x73, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x72, 0x75, 0x6e,
+ 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x65, 0x78,
+ 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4d, 0x65,
+ 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x36,
+ 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x6d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x31,
+ 0x36, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x6e, 0x74,
+ 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3c,
+ 0x0a, 0x0e, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x32, 0x45, 0x6e, 0x74, 0x72, 0x79,
+ 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
+ 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3c, 0x0a, 0x0e,
+ 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x33, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10,
+ 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79,
+ 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3c, 0x0a, 0x0e, 0x4d, 0x61,
+ 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x34, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
+ 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14,
+ 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76,
+ 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3c, 0x0a, 0x0e, 0x4d, 0x61, 0x70, 0x56,
+ 0x61, 0x6c, 0x75, 0x65, 0x35, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
+ 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05,
+ 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c,
+ 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3c, 0x0a, 0x0e, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c,
+ 0x75, 0x65, 0x36, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,
+ 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
+ 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3c, 0x0a, 0x0e, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65,
+ 0x37, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
+ 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02,
+ 0x38, 0x01, 0x1a, 0x3c, 0x0a, 0x0e, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x38, 0x45,
+ 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
+ 0x1a, 0x3c, 0x0a, 0x0e, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x39, 0x45, 0x6e, 0x74,
+ 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52,
+ 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3d,
+ 0x0a, 0x0f, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x30, 0x45, 0x6e, 0x74, 0x72,
+ 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
+ 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x02, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3d, 0x0a,
+ 0x0f, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x32, 0x45, 0x6e, 0x74, 0x72, 0x79,
+ 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
+ 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3d, 0x0a, 0x0f,
+ 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x34, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
+ 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
+ 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08,
+ 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3d, 0x0a, 0x0f, 0x4d,
+ 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x35, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10,
+ 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x6b, 0x65, 0x79,
+ 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x5b, 0x0a, 0x0f, 0x4d, 0x61,
+ 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x36, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
+ 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
+ 0x32, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c,
+ 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+ 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61,
+ 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x6f, 0x6e, 0x65, 0x6f, 0x66,
+ 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x14, 0x0a, 0x12, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64,
+ 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x20, 0x0a, 0x09,
+ 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x05, 0x0a, 0x01, 0x58, 0x10, 0x00,
+ 0x12, 0x05, 0x0a, 0x01, 0x59, 0x10, 0x01, 0x12, 0x05, 0x0a, 0x01, 0x5a, 0x10, 0x02, 0x42, 0x49,
+ 0x5a, 0x47, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x69, 0x6e,
+ 0x63, 0x68, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x65, 0x61, 0x73, 0x65, 0x2d, 0x67,
+ 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2f, 0x72,
+ 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f,
+ 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x33,
+}
+
+var (
+ file_gateway_runtime_internal_examplepb_proto3_proto_rawDescOnce sync.Once
+ file_gateway_runtime_internal_examplepb_proto3_proto_rawDescData = file_gateway_runtime_internal_examplepb_proto3_proto_rawDesc
+)
+
+func file_gateway_runtime_internal_examplepb_proto3_proto_rawDescGZIP() []byte {
+ file_gateway_runtime_internal_examplepb_proto3_proto_rawDescOnce.Do(func() {
+ file_gateway_runtime_internal_examplepb_proto3_proto_rawDescData = protoimpl.X.CompressGZIP(file_gateway_runtime_internal_examplepb_proto3_proto_rawDescData)
+ })
+ return file_gateway_runtime_internal_examplepb_proto3_proto_rawDescData
+}
+
+var file_gateway_runtime_internal_examplepb_proto3_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_gateway_runtime_internal_examplepb_proto3_proto_msgTypes = make([]protoimpl.MessageInfo, 15)
+var file_gateway_runtime_internal_examplepb_proto3_proto_goTypes = []interface{}{
+ (EnumValue)(0), // 0: janus.gateway.runtime.internal.examplepb.EnumValue
+ (*Proto3Message)(nil), // 1: janus.gateway.runtime.internal.examplepb.Proto3Message
+ nil, // 2: janus.gateway.runtime.internal.examplepb.Proto3Message.MapValueEntry
+ nil, // 3: janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue2Entry
+ nil, // 4: janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue3Entry
+ nil, // 5: janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue4Entry
+ nil, // 6: janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue5Entry
+ nil, // 7: janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue6Entry
+ nil, // 8: janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue7Entry
+ nil, // 9: janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue8Entry
+ nil, // 10: janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue9Entry
+ nil, // 11: janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue10Entry
+ nil, // 12: janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue12Entry
+ nil, // 13: janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue14Entry
+ nil, // 14: janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue15Entry
+ nil, // 15: janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue16Entry
+ (*wrapperspb.UInt64Value)(nil), // 16: google.protobuf.UInt64Value
+ (*timestamppb.Timestamp)(nil), // 17: google.protobuf.Timestamp
+ (*durationpb.Duration)(nil), // 18: google.protobuf.Duration
+ (*fieldmaskpb.FieldMask)(nil), // 19: google.protobuf.FieldMask
+ (*wrapperspb.DoubleValue)(nil), // 20: google.protobuf.DoubleValue
+ (*wrapperspb.FloatValue)(nil), // 21: google.protobuf.FloatValue
+ (*wrapperspb.Int64Value)(nil), // 22: google.protobuf.Int64Value
+ (*wrapperspb.Int32Value)(nil), // 23: google.protobuf.Int32Value
+ (*wrapperspb.UInt32Value)(nil), // 24: google.protobuf.UInt32Value
+ (*wrapperspb.BoolValue)(nil), // 25: google.protobuf.BoolValue
+ (*wrapperspb.StringValue)(nil), // 26: google.protobuf.StringValue
+ (*wrapperspb.BytesValue)(nil), // 27: google.protobuf.BytesValue
+}
+var file_gateway_runtime_internal_examplepb_proto3_proto_depIdxs = []int32{
+ 1, // 0: janus.gateway.runtime.internal.examplepb.Proto3Message.nested:type_name -> janus.gateway.runtime.internal.examplepb.Proto3Message
+ 16, // 1: janus.gateway.runtime.internal.examplepb.Proto3Message.repeated_message:type_name -> google.protobuf.UInt64Value
+ 0, // 2: janus.gateway.runtime.internal.examplepb.Proto3Message.enum_value:type_name -> janus.gateway.runtime.internal.examplepb.EnumValue
+ 0, // 3: janus.gateway.runtime.internal.examplepb.Proto3Message.repeated_enum:type_name -> janus.gateway.runtime.internal.examplepb.EnumValue
+ 17, // 4: janus.gateway.runtime.internal.examplepb.Proto3Message.timestamp_value:type_name -> google.protobuf.Timestamp
+ 18, // 5: janus.gateway.runtime.internal.examplepb.Proto3Message.duration_value:type_name -> google.protobuf.Duration
+ 19, // 6: janus.gateway.runtime.internal.examplepb.Proto3Message.fieldmask_value:type_name -> google.protobuf.FieldMask
+ 1, // 7: janus.gateway.runtime.internal.examplepb.Proto3Message.nested_oneof_value_one:type_name -> janus.gateway.runtime.internal.examplepb.Proto3Message
+ 20, // 8: janus.gateway.runtime.internal.examplepb.Proto3Message.wrapper_double_value:type_name -> google.protobuf.DoubleValue
+ 21, // 9: janus.gateway.runtime.internal.examplepb.Proto3Message.wrapper_float_value:type_name -> google.protobuf.FloatValue
+ 22, // 10: janus.gateway.runtime.internal.examplepb.Proto3Message.wrapper_int64_value:type_name -> google.protobuf.Int64Value
+ 23, // 11: janus.gateway.runtime.internal.examplepb.Proto3Message.wrapper_int32_value:type_name -> google.protobuf.Int32Value
+ 16, // 12: janus.gateway.runtime.internal.examplepb.Proto3Message.wrapper_u_int64_value:type_name -> google.protobuf.UInt64Value
+ 24, // 13: janus.gateway.runtime.internal.examplepb.Proto3Message.wrapper_u_int32_value:type_name -> google.protobuf.UInt32Value
+ 25, // 14: janus.gateway.runtime.internal.examplepb.Proto3Message.wrapper_bool_value:type_name -> google.protobuf.BoolValue
+ 26, // 15: janus.gateway.runtime.internal.examplepb.Proto3Message.wrapper_string_value:type_name -> google.protobuf.StringValue
+ 27, // 16: janus.gateway.runtime.internal.examplepb.Proto3Message.wrapper_bytes_value:type_name -> google.protobuf.BytesValue
+ 2, // 17: janus.gateway.runtime.internal.examplepb.Proto3Message.map_value:type_name -> janus.gateway.runtime.internal.examplepb.Proto3Message.MapValueEntry
+ 3, // 18: janus.gateway.runtime.internal.examplepb.Proto3Message.map_value2:type_name -> janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue2Entry
+ 4, // 19: janus.gateway.runtime.internal.examplepb.Proto3Message.map_value3:type_name -> janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue3Entry
+ 5, // 20: janus.gateway.runtime.internal.examplepb.Proto3Message.map_value4:type_name -> janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue4Entry
+ 6, // 21: janus.gateway.runtime.internal.examplepb.Proto3Message.map_value5:type_name -> janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue5Entry
+ 7, // 22: janus.gateway.runtime.internal.examplepb.Proto3Message.map_value6:type_name -> janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue6Entry
+ 8, // 23: janus.gateway.runtime.internal.examplepb.Proto3Message.map_value7:type_name -> janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue7Entry
+ 9, // 24: janus.gateway.runtime.internal.examplepb.Proto3Message.map_value8:type_name -> janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue8Entry
+ 10, // 25: janus.gateway.runtime.internal.examplepb.Proto3Message.map_value9:type_name -> janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue9Entry
+ 11, // 26: janus.gateway.runtime.internal.examplepb.Proto3Message.map_value10:type_name -> janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue10Entry
+ 12, // 27: janus.gateway.runtime.internal.examplepb.Proto3Message.map_value12:type_name -> janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue12Entry
+ 13, // 28: janus.gateway.runtime.internal.examplepb.Proto3Message.map_value14:type_name -> janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue14Entry
+ 14, // 29: janus.gateway.runtime.internal.examplepb.Proto3Message.map_value15:type_name -> janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue15Entry
+ 15, // 30: janus.gateway.runtime.internal.examplepb.Proto3Message.map_value16:type_name -> janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue16Entry
+ 16, // 31: janus.gateway.runtime.internal.examplepb.Proto3Message.MapValue16Entry.value:type_name -> google.protobuf.UInt64Value
+ 32, // [32:32] is the sub-list for method output_type
+ 32, // [32:32] is the sub-list for method input_type
+ 32, // [32:32] is the sub-list for extension type_name
+ 32, // [32:32] is the sub-list for extension extendee
+ 0, // [0:32] is the sub-list for field type_name
+}
+
+func init() { file_gateway_runtime_internal_examplepb_proto3_proto_init() }
+func file_gateway_runtime_internal_examplepb_proto3_proto_init() {
+ if File_gateway_runtime_internal_examplepb_proto3_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_gateway_runtime_internal_examplepb_proto3_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Proto3Message); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ file_gateway_runtime_internal_examplepb_proto3_proto_msgTypes[0].OneofWrappers = []interface{}{
+ (*Proto3Message_OneofBoolValue)(nil),
+ (*Proto3Message_OneofStringValue)(nil),
+ (*Proto3Message_NestedOneofValueOne)(nil),
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_gateway_runtime_internal_examplepb_proto3_proto_rawDesc,
+ NumEnums: 1,
+ NumMessages: 15,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_gateway_runtime_internal_examplepb_proto3_proto_goTypes,
+ DependencyIndexes: file_gateway_runtime_internal_examplepb_proto3_proto_depIdxs,
+ EnumInfos: file_gateway_runtime_internal_examplepb_proto3_proto_enumTypes,
+ MessageInfos: file_gateway_runtime_internal_examplepb_proto3_proto_msgTypes,
+ }.Build()
+ File_gateway_runtime_internal_examplepb_proto3_proto = out.File
+ file_gateway_runtime_internal_examplepb_proto3_proto_rawDesc = nil
+ file_gateway_runtime_internal_examplepb_proto3_proto_goTypes = nil
+ file_gateway_runtime_internal_examplepb_proto3_proto_depIdxs = nil
+}
diff --git a/gateway/runtime/internal/examplepb/proto3.proto b/gateway/runtime/internal/examplepb/proto3.proto
new file mode 100644
index 0000000..043b576
--- /dev/null
+++ b/gateway/runtime/internal/examplepb/proto3.proto
@@ -0,0 +1,67 @@
+syntax = "proto3";
+
+package janus.gateway.runtime.internal.examplepb;
+
+option go_package = "github.com/binchencoder/janus-gateway/gateway/runtime/internal/examplepb";
+
+import "google/protobuf/duration.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/timestamp.proto";
+import "google/protobuf/wrappers.proto";
+
+message Proto3Message {
+ // Next number: 47
+ Proto3Message nested = 41;
+ float float_value = 42;
+ double double_value = 43;
+ int64 int64_value = 3;
+ int32 int32_value = 4;
+ uint64 uint64_value = 5;
+ uint32 uint32_value = 6;
+ bool bool_value = 7;
+ string string_value = 8;
+ bytes bytes_value = 9;
+ repeated string repeated_value = 10;
+ repeated google.protobuf.UInt64Value repeated_message = 44;
+ EnumValue enum_value = 11;
+ repeated EnumValue repeated_enum = 12;
+ google.protobuf.Timestamp timestamp_value = 13;
+ google.protobuf.Duration duration_value = 14;
+ google.protobuf.FieldMask fieldmask_value = 15;
+ oneof oneof_value {
+ bool oneof_bool_value = 1;
+ string oneof_string_value = 2;
+ }
+ oneof nested_oneof_value {
+ Proto3Message nested_oneof_value_one = 46;
+ }
+ google.protobuf.DoubleValue wrapper_double_value = 17;
+ google.protobuf.FloatValue wrapper_float_value = 18;
+ google.protobuf.Int64Value wrapper_int64_value = 19;
+ google.protobuf.Int32Value wrapper_int32_value = 20;
+ google.protobuf.UInt64Value wrapper_u_int64_value = 21;
+ google.protobuf.UInt32Value wrapper_u_int32_value = 22;
+ google.protobuf.BoolValue wrapper_bool_value = 23;
+ google.protobuf.StringValue wrapper_string_value = 24;
+ google.protobuf.BytesValue wrapper_bytes_value = 25;
+ map map_value = 26;
+ map map_value2 = 27;
+ map map_value3 = 28;
+ map map_value4 = 29;
+ map map_value5 = 30;
+ map map_value6 = 31;
+ map map_value7 = 32;
+ map map_value8 = 33;
+ map map_value9 = 34;
+ map map_value10 = 35;
+ map map_value12 = 37;
+ map map_value14 = 39;
+ map map_value15 = 40;
+ map map_value16 = 45;
+}
+
+enum EnumValue {
+ X = 0;
+ Y = 1;
+ Z = 2;
+}
diff --git a/gateway/runtime/marshal_httpbodyproto.go b/gateway/runtime/marshal_httpbodyproto.go
index f55285b..b86135c 100644
--- a/gateway/runtime/marshal_httpbodyproto.go
+++ b/gateway/runtime/marshal_httpbodyproto.go
@@ -4,13 +4,6 @@ import (
"google.golang.org/genproto/googleapis/api/httpbody"
)
-// SetHTTPBodyMarshaler overwrite the default marshaler with the HTTPBodyMarshaler
-func SetHTTPBodyMarshaler(serveMux *ServeMux) {
- serveMux.marshalers.mimeMap[MIMEWildcard] = &HTTPBodyMarshaler{
- Marshaler: &JSONPb{OrigName: true},
- }
-}
-
// HTTPBodyMarshaler is a Marshaler which supports marshaling of a
// google.api.HttpBody message as the full response body if it is
// the actual message used as the response. If not, then this will
@@ -19,18 +12,14 @@ type HTTPBodyMarshaler struct {
Marshaler
}
-// ContentType implementation to keep backwards compatability with marshal interface
-func (h *HTTPBodyMarshaler) ContentType() string {
- return h.ContentTypeFromMessage(nil)
-}
-
-// ContentTypeFromMessage in case v is a google.api.HttpBody message it returns
-// its specified content type otherwise fall back to the default Marshaler.
-func (h *HTTPBodyMarshaler) ContentTypeFromMessage(v interface{}) string {
+// ContentType returns its specified content type in case v is a
+// google.api.HttpBody message, otherwise it will fall back to the default Marshalers
+// content type.
+func (h *HTTPBodyMarshaler) ContentType(v interface{}) string {
if httpBody, ok := v.(*httpbody.HttpBody); ok {
return httpBody.GetContentType()
}
- return h.Marshaler.ContentType()
+ return h.Marshaler.ContentType(v)
}
// Marshal marshals "v" by returning the body bytes if v is a
diff --git a/gateway/runtime/marshal_httpbodyproto_test.go b/gateway/runtime/marshal_httpbodyproto_test.go
index 4bcd358..f7e907a 100644
--- a/gateway/runtime/marshal_httpbodyproto_test.go
+++ b/gateway/runtime/marshal_httpbodyproto_test.go
@@ -4,25 +4,29 @@ import (
"bytes"
"testing"
- "github.com/binchencoder/ease-gateway/gateway/runtime"
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
+ "github.com/binchencoder/janus-gateway/gateway/runtime"
"google.golang.org/genproto/googleapis/api/httpbody"
+ "google.golang.org/protobuf/encoding/protojson"
)
func TestHTTPBodyContentType(t *testing.T) {
m := runtime.HTTPBodyMarshaler{
&runtime.JSONPb{
- OrigName: true,
+ MarshalOptions: protojson.MarshalOptions{
+ UseProtoNames: true,
+ },
},
}
expected := "CustomContentType"
message := &httpbody.HttpBody{
ContentType: expected,
}
- res := m.ContentType()
+ res := m.ContentType(nil)
if res != "application/json" {
t.Errorf("content type not equal (%q, %q)", res, expected)
}
- res = m.ContentTypeFromMessage(message)
+ res = m.ContentType(message)
if res != expected {
t.Errorf("content type not equal (%q, %q)", res, expected)
}
@@ -31,7 +35,9 @@ func TestHTTPBodyContentType(t *testing.T) {
func TestHTTPBodyMarshal(t *testing.T) {
m := runtime.HTTPBodyMarshaler{
&runtime.JSONPb{
- OrigName: true,
+ MarshalOptions: protojson.MarshalOptions{
+ UseProtoNames: true,
+ },
},
}
expected := []byte("Some test")
diff --git a/gateway/runtime/marshal_json.go b/gateway/runtime/marshal_json.go
index f9d3a58..d6aa825 100644
--- a/gateway/runtime/marshal_json.go
+++ b/gateway/runtime/marshal_json.go
@@ -15,7 +15,7 @@ import (
type JSONBuiltin struct{}
// ContentType always Returns "application/json".
-func (*JSONBuiltin) ContentType() string {
+func (*JSONBuiltin) ContentType(_ interface{}) string {
return "application/json"
}
diff --git a/gateway/runtime/marshal_jsonpb.go b/gateway/runtime/marshal_jsonpb.go
index f0de351..7387c8e 100644
--- a/gateway/runtime/marshal_jsonpb.go
+++ b/gateway/runtime/marshal_jsonpb.go
@@ -6,21 +6,25 @@ import (
"fmt"
"io"
"reflect"
+ "strconv"
- "github.com/golang/protobuf/jsonpb"
- "github.com/golang/protobuf/proto"
+ "google.golang.org/protobuf/encoding/protojson"
+ "google.golang.org/protobuf/proto"
)
// JSONPb is a Marshaler which marshals/unmarshals into/from JSON
-// with the "github.com/golang/protobuf/jsonpb".
-// It supports fully functionality of protobuf unlike JSONBuiltin.
+// with the "google.golang.org/protobuf/encoding/protojson" marshaler.
+// It supports the full functionality of protobuf unlike JSONBuiltin.
//
// The NewDecoder method returns a DecoderWrapper, so the underlying
// *json.Decoder methods can be used.
-type JSONPb jsonpb.Marshaler
+type JSONPb struct {
+ protojson.MarshalOptions
+ protojson.UnmarshalOptions
+}
// ContentType always returns "application/json".
-func (*JSONPb) ContentType() string {
+func (*JSONPb) ContentType(_ interface{}) string {
return "application/json"
}
@@ -47,7 +51,13 @@ func (j *JSONPb) marshalTo(w io.Writer, v interface{}) error {
_, err = w.Write(buf)
return err
}
- return (*jsonpb.Marshaler)(j).Marshal(w, p)
+ b, err := j.MarshalOptions.Marshal(p)
+ if err != nil {
+ return err
+ }
+
+ _, err = w.Write(b)
+ return err
}
var (
@@ -56,8 +66,8 @@ var (
)
// marshalNonProto marshals a non-message field of a protobuf message.
-// This function does not correctly marshals arbitrary data structure into JSON,
-// but it is only capable of marshaling non-message field values of protobuf,
+// This function does not correctly marshal arbitrary data structures into JSON,
+// it is only capable of marshaling non-message field values of protobuf,
// i.e. primitive types, enums; pointers to primitives or enums; maps from
// integer/string types to primitives/enums/pointers to messages.
func (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) {
@@ -74,7 +84,7 @@ func (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) {
if rv.Kind() == reflect.Slice {
if rv.IsNil() {
- if j.EmitDefaults {
+ if j.EmitUnpopulated {
return []byte("[]"), nil
}
return []byte("null"), nil
@@ -93,7 +103,37 @@ func (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) {
return nil, err
}
}
- if err = (*jsonpb.Marshaler)(j).Marshal(&buf, rv.Index(i).Interface().(proto.Message)); err != nil {
+ if err = j.marshalTo(&buf, rv.Index(i).Interface().(proto.Message)); err != nil {
+ return nil, err
+ }
+ }
+ err = buf.WriteByte(']')
+ if err != nil {
+ return nil, err
+ }
+
+ return buf.Bytes(), nil
+ }
+
+ if rv.Type().Elem().Implements(typeProtoEnum) {
+ var buf bytes.Buffer
+ err := buf.WriteByte('[')
+ if err != nil {
+ return nil, err
+ }
+ for i := 0; i < rv.Len(); i++ {
+ if i != 0 {
+ err = buf.WriteByte(',')
+ if err != nil {
+ return nil, err
+ }
+ }
+ if j.UseEnumNumbers {
+ _, err = buf.WriteString(strconv.FormatInt(rv.Index(i).Int(), 10))
+ } else {
+ _, err = buf.WriteString("\"" + rv.Index(i).Interface().(protoEnum).String() + "\"")
+ }
+ if err != nil {
return nil, err
}
}
@@ -120,7 +160,7 @@ func (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) {
}
return json.Marshal(m)
}
- if enum, ok := rv.Interface().(protoEnum); ok && !j.EnumsAsInts {
+ if enum, ok := rv.Interface().(protoEnum); ok && !j.UseEnumNumbers {
return json.Marshal(enum.String())
}
return json.Marshal(rv.Interface())
@@ -128,25 +168,29 @@ func (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) {
// Unmarshal unmarshals JSON "data" into "v"
func (j *JSONPb) Unmarshal(data []byte, v interface{}) error {
- return unmarshalJSONPb(data, v)
+ return unmarshalJSONPb(data, j.UnmarshalOptions, v)
}
// NewDecoder returns a Decoder which reads JSON stream from "r".
func (j *JSONPb) NewDecoder(r io.Reader) Decoder {
d := json.NewDecoder(r)
- return DecoderWrapper{Decoder: d}
+ return DecoderWrapper{
+ Decoder: d,
+ UnmarshalOptions: j.UnmarshalOptions,
+ }
}
// DecoderWrapper is a wrapper around a *json.Decoder that adds
// support for protos to the Decode method.
type DecoderWrapper struct {
*json.Decoder
+ protojson.UnmarshalOptions
}
// Decode wraps the embedded decoder's Decode method to support
// protos using a jsonpb.Unmarshaler.
func (d DecoderWrapper) Decode(v interface{}) error {
- return decodeJSONPb(d.Decoder, v)
+ return decodeJSONPb(d.Decoder, d.UnmarshalOptions, v)
}
// NewEncoder returns an Encoder which writes JSON stream into "w".
@@ -162,21 +206,28 @@ func (j *JSONPb) NewEncoder(w io.Writer) Encoder {
})
}
-func unmarshalJSONPb(data []byte, v interface{}) error {
+func unmarshalJSONPb(data []byte, unmarshaler protojson.UnmarshalOptions, v interface{}) error {
d := json.NewDecoder(bytes.NewReader(data))
- return decodeJSONPb(d, v)
+ return decodeJSONPb(d, unmarshaler, v)
}
-func decodeJSONPb(d *json.Decoder, v interface{}) error {
+func decodeJSONPb(d *json.Decoder, unmarshaler protojson.UnmarshalOptions, v interface{}) error {
p, ok := v.(proto.Message)
if !ok {
- return decodeNonProtoField(d, v)
+ return decodeNonProtoField(d, unmarshaler, v)
}
- unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: allowUnknownFields}
- return unmarshaler.UnmarshalNext(d, p)
+
+ // Decode into bytes for marshalling
+ var b json.RawMessage
+ err := d.Decode(&b)
+ if err != nil {
+ return err
+ }
+
+ return unmarshaler.Unmarshal([]byte(b), p)
}
-func decodeNonProtoField(d *json.Decoder, v interface{}) error {
+func decodeNonProtoField(d *json.Decoder, unmarshaler protojson.UnmarshalOptions, v interface{}) error {
rv := reflect.ValueOf(v)
if rv.Kind() != reflect.Ptr {
return fmt.Errorf("%T is not a pointer", v)
@@ -186,8 +237,14 @@ func decodeNonProtoField(d *json.Decoder, v interface{}) error {
rv.Set(reflect.New(rv.Type().Elem()))
}
if rv.Type().ConvertibleTo(typeProtoMessage) {
- unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: allowUnknownFields}
- return unmarshaler.UnmarshalNext(d, rv.Interface().(proto.Message))
+ // Decode into bytes for marshalling
+ var b json.RawMessage
+ err := d.Decode(&b)
+ if err != nil {
+ return err
+ }
+
+ return unmarshaler.Unmarshal([]byte(b), rv.Interface().(proto.Message))
}
rv = rv.Elem()
}
@@ -211,24 +268,45 @@ func decodeNonProtoField(d *json.Decoder, v interface{}) error {
}
bk := result[0]
bv := reflect.New(rv.Type().Elem())
- if err := unmarshalJSONPb([]byte(*v), bv.Interface()); err != nil {
+ if v == nil {
+ null := json.RawMessage("null")
+ v = &null
+ }
+ if err := unmarshalJSONPb([]byte(*v), unmarshaler, bv.Interface()); err != nil {
return err
}
rv.SetMapIndex(bk, bv.Elem())
}
return nil
}
+ if rv.Kind() == reflect.Slice {
+ var sl []json.RawMessage
+ if err := d.Decode(&sl); err != nil {
+ return err
+ }
+ if sl != nil {
+ rv.Set(reflect.MakeSlice(rv.Type(), 0, 0))
+ }
+ for _, item := range sl {
+ bv := reflect.New(rv.Type().Elem())
+ if err := unmarshalJSONPb([]byte(item), unmarshaler, bv.Interface()); err != nil {
+ return err
+ }
+ rv.Set(reflect.Append(rv, bv.Elem()))
+ }
+ return nil
+ }
if _, ok := rv.Interface().(protoEnum); ok {
var repr interface{}
if err := d.Decode(&repr); err != nil {
return err
}
- switch repr.(type) {
+ switch v := repr.(type) {
case string:
// TODO(yugui) Should use proto.StructProperties?
return fmt.Errorf("unmarshaling of symbolic enum %q not supported: %T", repr, rv.Interface())
case float64:
- rv.Set(reflect.ValueOf(int32(repr.(float64))).Convert(rv.Type()))
+ rv.Set(reflect.ValueOf(int32(v)).Convert(rv.Type()))
return nil
default:
return fmt.Errorf("cannot assign %#v into Go type %T", repr, rv.Interface())
@@ -242,6 +320,8 @@ type protoEnum interface {
EnumDescriptor() ([]byte, []int)
}
+var typeProtoEnum = reflect.TypeOf((*protoEnum)(nil)).Elem()
+
var typeProtoMessage = reflect.TypeOf((*proto.Message)(nil)).Elem()
// Delimiter for newline encoded JSON streams.
@@ -249,14 +329,16 @@ func (j *JSONPb) Delimiter() []byte {
return []byte("\n")
}
-// allowUnknownFields helps not to return an error when the destination
-// is a struct and the input contains object keys which do not match any
-// non-ignored, exported fields in the destination.
-var allowUnknownFields = true
-
-// DisallowUnknownFields enables option in decoder (unmarshaller) to
-// return an error when it finds an unknown field. This function must be
-// called before using the JSON marshaller.
-func DisallowUnknownFields() {
- allowUnknownFields = false
-}
+var (
+ convFromType = map[reflect.Kind]reflect.Value{
+ reflect.String: reflect.ValueOf(String),
+ reflect.Bool: reflect.ValueOf(Bool),
+ reflect.Float64: reflect.ValueOf(Float64),
+ reflect.Float32: reflect.ValueOf(Float32),
+ reflect.Int64: reflect.ValueOf(Int64),
+ reflect.Int32: reflect.ValueOf(Int32),
+ reflect.Uint64: reflect.ValueOf(Uint64),
+ reflect.Uint32: reflect.ValueOf(Uint32),
+ reflect.Slice: reflect.ValueOf(Bytes),
+ }
+)
diff --git a/gateway/runtime/marshal_proto.go b/gateway/runtime/marshal_proto.go
index f65d1a2..007f8f1 100644
--- a/gateway/runtime/marshal_proto.go
+++ b/gateway/runtime/marshal_proto.go
@@ -4,15 +4,16 @@ import (
"io"
"errors"
- "github.com/golang/protobuf/proto"
"io/ioutil"
+
+ "google.golang.org/protobuf/proto"
)
// ProtoMarshaller is a Marshaller which marshals/unmarshals into/from serialize proto bytes
type ProtoMarshaller struct{}
// ContentType always returns "application/octet-stream".
-func (*ProtoMarshaller) ContentType() string {
+func (*ProtoMarshaller) ContentType(_ interface{}) string {
return "application/octet-stream"
}
diff --git a/gateway/runtime/marshaler.go b/gateway/runtime/marshaler.go
index 98fe6e8..2c0d25f 100644
--- a/gateway/runtime/marshaler.go
+++ b/gateway/runtime/marshaler.go
@@ -16,7 +16,9 @@ type Marshaler interface {
// NewEncoder returns an Encoder which writes bytes sequence into "w".
NewEncoder(w io.Writer) Encoder
// ContentType returns the Content-Type which this marshaler is responsible for.
- ContentType() string
+ // The parameter describes the type which is being marshalled, which can sometimes
+ // affect the content type returned.
+ ContentType(v interface{}) string
}
// Decoder decodes a byte sequence
@@ -43,6 +45,6 @@ func (f EncoderFunc) Encode(v interface{}) error { return f(v) }
// Delimited defines the streaming delimiter.
type Delimited interface {
- // Delimiter returns the record seperator for the stream.
+ // Delimiter returns the record separator for the stream.
Delimiter() []byte
}
diff --git a/gateway/runtime/marshaler_registry.go b/gateway/runtime/marshaler_registry.go
index 42e9d15..a714de0 100644
--- a/gateway/runtime/marshaler_registry.go
+++ b/gateway/runtime/marshaler_registry.go
@@ -2,7 +2,11 @@ package runtime
import (
"errors"
+ "mime"
"net/http"
+
+ "google.golang.org/grpc/grpclog"
+ "google.golang.org/protobuf/encoding/protojson"
)
// MIMEWildcard is the fallback MIME type used for requests which do not match
@@ -13,9 +17,15 @@ var (
acceptHeader = http.CanonicalHeaderKey("Accept")
contentTypeHeader = http.CanonicalHeaderKey("Content-Type")
- defaultMarshaler = &JSONPb{
- OrigName: true,
- EnumsAsInts: true,
+ defaultMarshaler = &HTTPBodyMarshaler{
+ Marshaler: &JSONPb{
+ MarshalOptions: protojson.MarshalOptions{
+ EmitUnpopulated: true,
+ },
+ UnmarshalOptions: protojson.UnmarshalOptions{
+ DiscardUnknown: true,
+ },
+ },
}
)
@@ -34,7 +44,12 @@ func MarshalerForRequest(mux *ServeMux, r *http.Request) (inbound Marshaler, out
}
for _, contentTypeVal := range r.Header[contentTypeHeader] {
- if m, ok := mux.marshalers.mimeMap[contentTypeVal]; ok {
+ contentType, _, err := mime.ParseMediaType(contentTypeVal)
+ if err != nil {
+ grpclog.Infof("Failed to parse Content-Type %s: %v", contentTypeVal, err)
+ continue
+ }
+ if m, ok := mux.marshalers.mimeMap[contentType]; ok {
inbound = m
break
}
diff --git a/gateway/runtime/marshaler_registry_test.go b/gateway/runtime/marshaler_registry_test.go
index dfe2269..d3854b5 100644
--- a/gateway/runtime/marshaler_registry_test.go
+++ b/gateway/runtime/marshaler_registry_test.go
@@ -2,11 +2,13 @@ package runtime_test
import (
"errors"
+ "fmt"
"io"
"net/http"
"testing"
- "github.com/binchencoder/ease-gateway/gateway/runtime"
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
+ "github.com/binchencoder/janus-gateway/gateway/runtime"
)
func TestMarshalerForRequest(t *testing.T) {
@@ -14,36 +16,40 @@ func TestMarshalerForRequest(t *testing.T) {
if err != nil {
t.Fatalf(`http.NewRequest("GET", "http://example.com", nil) failed with %v; want success`, err)
}
- r.Header.Set("Accept", "application/x-out")
- r.Header.Set("Content-Type", "application/x-in")
mux := runtime.NewServeMux()
+ r.Header.Set("Accept", "application/x-out")
+ r.Header.Set("Content-Type", "application/x-in")
in, out := runtime.MarshalerForRequest(mux, r)
- if _, ok := in.(*runtime.JSONPb); !ok {
- t.Errorf("in = %#v; want a runtime.JSONPb", in)
+ if _, ok := in.(*runtime.HTTPBodyMarshaler); !ok {
+ t.Errorf("in = %#v; want a runtime.HTTPBodyMarshaler", in)
}
- if _, ok := out.(*runtime.JSONPb); !ok {
- t.Errorf("out = %#v; want a runtime.JSONPb", in)
+ if _, ok := out.(*runtime.HTTPBodyMarshaler); !ok {
+ t.Errorf("out = %#v; want a runtime.HTTPBodyMarshaler", in)
}
- var marshalers [3]dummyMarshaler
+ marshalers := []dummyMarshaler{0, 1, 2}
specs := []struct {
opt runtime.ServeMuxOption
wantIn runtime.Marshaler
wantOut runtime.Marshaler
}{
+ // The option with wildcard overwrites the default configuration
{
opt: runtime.WithMarshalerOption(runtime.MIMEWildcard, &marshalers[0]),
wantIn: &marshalers[0],
wantOut: &marshalers[0],
},
+ // You can specify a marshaler for a specific MIME type.
+ // The output marshaler follows the input one unless specified.
{
opt: runtime.WithMarshalerOption("application/x-in", &marshalers[1]),
wantIn: &marshalers[1],
- wantOut: &marshalers[0],
+ wantOut: &marshalers[1],
},
+ // You can also separately specify an output marshaler
{
opt: runtime.WithMarshalerOption("application/x-out", &marshalers[2]),
wantIn: &marshalers[1],
@@ -66,19 +72,29 @@ func TestMarshalerForRequest(t *testing.T) {
}
}
- r.Header.Set("Content-Type", "application/x-another")
+ r.Header.Set("Content-Type", "application/x-in; charset=UTF-8")
in, out = runtime.MarshalerForRequest(mux, r)
if got, want := in, &marshalers[1]; got != want {
t.Errorf("in = %#v; want %#v", got, want)
}
+ if got, want := out, &marshalers[2]; got != want {
+ t.Errorf("out = %#v; want %#v", got, want)
+ }
+
+ r.Header.Set("Content-Type", "application/x-another")
+ r.Header.Set("Accept", "application/x-another")
+ in, out = runtime.MarshalerForRequest(mux, r)
+ if got, want := in, &marshalers[0]; got != want {
+ t.Errorf("in = %#v; want %#v", got, want)
+ }
if got, want := out, &marshalers[0]; got != want {
t.Errorf("out = %#v; want %#v", got, want)
}
}
-type dummyMarshaler struct{}
+type dummyMarshaler int
-func (dummyMarshaler) ContentType() string { return "" }
+func (dummyMarshaler) ContentType(_ interface{}) string { return "" }
func (dummyMarshaler) Marshal(interface{}) ([]byte, error) {
return nil, errors.New("not implemented")
}
@@ -94,6 +110,10 @@ func (dummyMarshaler) NewEncoder(w io.Writer) runtime.Encoder {
return dummyEncoder{}
}
+func (m dummyMarshaler) GoString() string {
+ return fmt.Sprintf("dummyMarshaler(%d)", m)
+}
+
type dummyDecoder struct{}
func (dummyDecoder) Decode(interface{}) error {
diff --git a/gateway/runtime/mux.go b/gateway/runtime/mux.go
index 6bda659..fa8e9bf 100644
--- a/gateway/runtime/mux.go
+++ b/gateway/runtime/mux.go
@@ -2,30 +2,56 @@ package runtime
import (
"context"
+ "errors"
"fmt"
"net/http"
"net/textproto"
+ "regexp"
"strings"
- "github.com/golang/protobuf/proto"
+ "github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule"
"google.golang.org/grpc/codes"
+ "google.golang.org/grpc/grpclog"
+ "google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
+ "google.golang.org/protobuf/proto"
"github.com/binchencoder/gateway-proto/data"
)
+// UnescapingMode defines the behavior of ServeMux when unescaping path parameters.
+type UnescapingMode int
+
+const (
+ // UnescapingModeLegacy is the default V2 behavior, which escapes the entire
+ // path string before doing any routing.
+ UnescapingModeLegacy UnescapingMode = iota
+
+ // UnescapingModeAllExceptReserved unescapes all path parameters except RFC 6570
+ // reserved characters.
+ UnescapingModeAllExceptReserved
+
+ // UnescapingModeAllExceptSlash unescapes URL path parameters except path
+ // separators, which will be left as "%2F".
+ UnescapingModeAllExceptSlash
+
+ // UnescapingModeAllCharacters unescapes all URL path parameters.
+ UnescapingModeAllCharacters
+
+ // UnescapingModeDefault is the default escaping type.
+ // TODO(v3): default this to UnescapingModeAllExceptReserved per grpc-httpjson-transcoding's
+ // reference implementation
+ UnescapingModeDefault = UnescapingModeLegacy
+)
+
+var (
+ encodedPathSplitter = regexp.MustCompile("(/|%2F)")
+)
+
// A HandlerFunc handles a specific pair of path pattern and HTTP method.
type HandlerFunc func(ctx context.Context, w http.ResponseWriter, r *http.Request, pathParams map[string]string)
-// ErrUnknownURI is the error supplied to a custom ProtoErrorHandlerFunc when
-// a request is received with a URI path that does not match any registered
-// service method.
-//
-// Since gRPC servers return an "Unimplemented" code for requests with an
-// unrecognized URI path, this error also has a gRPC "Unimplemented" code.
-var ErrUnknownURI = status.Error(codes.Unimplemented, http.StatusText(http.StatusNotImplemented))
-
// ServeMux is a request multiplexer for grpc-gateway.
// It matches http requests to patterns and invokes the corresponding handler.
type ServeMux struct {
@@ -36,10 +62,11 @@ type ServeMux struct {
incomingHeaderMatcher HeaderMatcherFunc
outgoingHeaderMatcher HeaderMatcherFunc
metadataAnnotators []func(context.Context, *http.Request) metadata.MD
+ errorHandler ErrorHandlerFunc
streamErrorHandler StreamErrorHandlerFunc
- protoErrorHandler ProtoErrorHandlerFunc
+ routingErrorHandler RoutingErrorHandlerFunc
disablePathLengthFallback bool
- lastMatchWins bool
+ unescapingMode UnescapingMode
}
// ServeMuxOption is an option that can be given to a ServeMux on construction.
@@ -57,6 +84,23 @@ func WithForwardResponseOption(forwardResponseOption func(context.Context, http.
}
}
+// WithEscapingType sets the escaping type. See the definitions of UnescapingMode
+// for more information.
+func WithUnescapingMode(mode UnescapingMode) ServeMuxOption {
+ return func(serveMux *ServeMux) {
+ serveMux.unescapingMode = mode
+ }
+}
+
+// SetQueryParameterParser sets the query parameter parser, used to populate message from query parameters.
+// Configuring this will mean the generated OpenAPI output is no longer correct, and it should be
+// done with careful consideration.
+func SetQueryParameterParser(queryParameterParser QueryParameterParser) ServeMuxOption {
+ return func(serveMux *ServeMux) {
+ currentQueryParser = queryParameterParser
+ }
+}
+
// HeaderMatcherFunc checks whether a header key should be forwarded to/from gRPC context.
type HeaderMatcherFunc func(string) (string, bool)
@@ -78,11 +122,30 @@ func DefaultHeaderMatcher(key string) (string, bool) {
// This matcher will be called with each header in http.Request. If matcher returns true, that header will be
// passed to gRPC context. To transform the header before passing to gRPC context, matcher should return modified header.
func WithIncomingHeaderMatcher(fn HeaderMatcherFunc) ServeMuxOption {
+ for _, header := range fn.matchedMalformedHeaders() {
+ grpclog.Warningf("The configured forwarding filter would allow %q to be sent to the gRPC server, which will likely cause errors. See https://github.com/grpc/grpc-go/pull/4803#issuecomment-986093310 for more information.", header)
+ }
+
return func(mux *ServeMux) {
mux.incomingHeaderMatcher = fn
}
}
+// matchedMalformedHeaders returns the malformed headers that would be forwarded to gRPC server.
+func (fn HeaderMatcherFunc) matchedMalformedHeaders() []string {
+ if fn == nil {
+ return nil
+ }
+ headers := make([]string, 0)
+ for header := range malformedHTTPHeaders {
+ out, accept := fn(header)
+ if accept && isMalformedHTTPHeader(out) {
+ headers = append(headers, out)
+ }
+ }
+ return headers
+}
+
// WithOutgoingHeaderMatcher returns a ServeMuxOption representing a headerMatcher for outgoing response from gateway.
//
// This matcher will be called with each header in response header metadata. If matcher returns true, that header will be
@@ -104,21 +167,12 @@ func WithMetadata(annotator func(context.Context, *http.Request) metadata.MD) Se
}
}
-// WithProtoErrorHandler returns a ServeMuxOption for passing metadata to a gRPC context.
+// WithErrorHandler returns a ServeMuxOption for configuring a custom error handler.
//
-// This can be used to handle an error as general proto message defined by gRPC.
-// The response including body and status is not backward compatible with the default error handler.
-// When this option is used, HTTPError and OtherErrorHandler are overwritten on initialization.
-func WithProtoErrorHandler(fn ProtoErrorHandlerFunc) ServeMuxOption {
+// This can be used to configure a custom error response.
+func WithErrorHandler(fn ErrorHandlerFunc) ServeMuxOption {
return func(serveMux *ServeMux) {
- serveMux.protoErrorHandler = fn
- }
-}
-
-// WithDisablePathLengthFallback returns a ServeMuxOption for disable path length fallback.
-func WithDisablePathLengthFallback() ServeMuxOption {
- return func(serveMux *ServeMux) {
- serveMux.disablePathLengthFallback = true
+ serveMux.errorHandler = fn
}
}
@@ -127,7 +181,7 @@ func WithDisablePathLengthFallback() ServeMuxOption {
// calls.
//
// For stream errors that occur before any response has been written, the mux's
-// ProtoErrorHandler will be invoked. However, once data has been written, the errors must
+// ErrorHandler will be invoked. However, once data has been written, the errors must
// be handled differently: they must be included in the response body. The response body's
// final message will include the error details returned by the stream error handler.
func WithStreamErrorHandler(fn StreamErrorHandlerFunc) ServeMuxOption {
@@ -136,40 +190,88 @@ func WithStreamErrorHandler(fn StreamErrorHandlerFunc) ServeMuxOption {
}
}
-// WithLastMatchWins returns a ServeMuxOption that will enable "last
-// match wins" behavior, where if multiple path patterns match a
-// request path, the last one defined in the .proto file will be used.
-func WithLastMatchWins() ServeMuxOption {
+// WithRoutingErrorHandler returns a ServeMuxOption for configuring a custom error handler to handle http routing errors.
+//
+// Method called for errors which can happen before gRPC route selected or executed.
+// The following error codes: StatusMethodNotAllowed StatusNotFound StatusBadRequest
+func WithRoutingErrorHandler(fn RoutingErrorHandlerFunc) ServeMuxOption {
return func(serveMux *ServeMux) {
- serveMux.lastMatchWins = true
+ serveMux.routingErrorHandler = fn
+ }
+}
+
+// WithDisablePathLengthFallback returns a ServeMuxOption for disable path length fallback.
+func WithDisablePathLengthFallback() ServeMuxOption {
+ return func(serveMux *ServeMux) {
+ serveMux.disablePathLengthFallback = true
+ }
+}
+
+// WithHealthEndpointAt returns a ServeMuxOption that will add an endpoint to the created ServeMux at the path specified by endpointPath.
+// When called the handler will forward the request to the upstream grpc service health check (defined in the
+// gRPC Health Checking Protocol).
+//
+// See here https://grpc-ecosystem.github.io/grpc-gateway/docs/operations/health_check/ for more information on how
+// to setup the protocol in the grpc server.
+//
+// If you define a service as query parameter, this will also be forwarded as service in the HealthCheckRequest.
+func WithHealthEndpointAt(healthCheckClient grpc_health_v1.HealthClient, endpointPath string, sid data.ServiceId) ServeMuxOption {
+ return func(s *ServeMux) {
+ // error can be ignored since pattern is definitely valid
+ _ = s.HandlePath(
+ http.MethodGet, endpointPath, sid, func(ctx context.Context, w http.ResponseWriter, r *http.Request, _ map[string]string,
+ ) {
+ _, outboundMarshaler := MarshalerForRequest(s, r)
+
+ resp, err := healthCheckClient.Check(r.Context(), &grpc_health_v1.HealthCheckRequest{
+ Service: r.URL.Query().Get("service"),
+ })
+ if err != nil {
+ s.errorHandler(r.Context(), s, outboundMarshaler, w, r, err)
+ return
+ }
+
+ if resp.GetStatus() != grpc_health_v1.HealthCheckResponse_SERVING {
+ var err error
+ switch resp.GetStatus() {
+ case grpc_health_v1.HealthCheckResponse_NOT_SERVING, grpc_health_v1.HealthCheckResponse_UNKNOWN:
+ err = status.Error(codes.Unavailable, resp.String())
+ case grpc_health_v1.HealthCheckResponse_SERVICE_UNKNOWN:
+ err = status.Error(codes.NotFound, resp.String())
+ }
+
+ s.errorHandler(r.Context(), s, outboundMarshaler, w, r, err)
+ return
+ }
+
+ _ = outboundMarshaler.NewEncoder(w).Encode(resp)
+ })
}
}
+// WithHealthzEndpoint returns a ServeMuxOption that will add a /healthz endpoint to the created ServeMux.
+//
+// See WithHealthEndpointAt for the general implementation.
+func WithHealthzEndpoint(healthCheckClient grpc_health_v1.HealthClient, sid data.ServiceId) ServeMuxOption {
+ return WithHealthEndpointAt(healthCheckClient, "/healthz", sid)
+}
+
// NewServeMux returns a new ServeMux whose internal mapping is empty.
func NewServeMux(opts ...ServeMuxOption) *ServeMux {
serveMux := &ServeMux{
handlers: make(map[string][]handler),
forwardResponseOptions: make([]func(context.Context, http.ResponseWriter, proto.Message) error, 0),
marshalers: makeMarshalerMIMERegistry(),
- streamErrorHandler: DefaultHTTPStreamErrorHandler,
+ errorHandler: DefaultHTTPErrorHandler,
+ streamErrorHandler: DefaultStreamErrorHandler,
+ routingErrorHandler: DefaultRoutingErrorHandler,
+ unescapingMode: UnescapingModeDefault,
}
for _, opt := range opts {
opt(serveMux)
}
- if serveMux.protoErrorHandler != nil {
- HTTPError = serveMux.protoErrorHandler
- // OtherErrorHandler is no longer used when protoErrorHandler is set.
- // Overwritten by a special error handler to return Unknown.
- OtherErrorHandler = func(w http.ResponseWriter, r *http.Request, _ string, _ int) {
- ctx := context.Background()
- _, outboundMarshaler := MarshalerForRequest(serveMux, r)
- sterr := status.Error(codes.Unknown, "unexpected use of OtherErrorHandler")
- serveMux.protoErrorHandler(ctx, serveMux, outboundMarshaler, w, r, sterr)
- }
- }
-
if serveMux.incomingHeaderMatcher == nil {
serveMux.incomingHeaderMatcher = DefaultHeaderMatcher
}
@@ -185,65 +287,104 @@ func NewServeMux(opts ...ServeMuxOption) *ServeMux {
// Handle associates "h" to the pair of HTTP method and path pattern.
func (s *ServeMux) Handle(meth string, pat Pattern, sid data.ServiceId, h HandlerFunc) {
- if s.lastMatchWins {
- s.handlers[meth] = append([]handler{handler{pat: pat, h: h, serviceId: sid}}, s.handlers[meth]...)
- } else {
- s.handlers[meth] = append(s.handlers[meth], handler{pat: pat, h: h, serviceId: sid})
+ s.handlers[meth] = append([]handler{handler{pat: pat, h: h, serviceId: sid}}, s.handlers[meth]...)
+}
+
+// HandlePath allows users to configure custom path handlers.
+// refer: https://grpc-ecosystem.github.io/grpc-gateway/docs/operations/inject_router/
+func (s *ServeMux) HandlePath(meth string, pathPattern string, sid data.ServiceId, h HandlerFunc) error {
+ compiler, err := httprule.Parse(pathPattern)
+ if err != nil {
+ return fmt.Errorf("parsing path pattern: %w", err)
}
+ tp := compiler.Compile()
+ pattern, err := NewPattern(tp.Version, tp.OpCodes, tp.Pool, tp.Verb)
+ if err != nil {
+ return fmt.Errorf("creating new pattern: %w", err)
+ }
+ s.Handle(meth, pattern, sid, h)
+ return nil
}
-// ServeHTTP dispatches the request to the first handler whose pattern matches to r.Method and r.Path.
+// ServeHTTP dispatches the request to the first handler whose pattern matches to r.Method and r.URL.Path.
func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx, err := RequestReceived(w, r)
if err != nil {
- DefaultHTTPError(ctx, nil, &JSONBuiltin{}, w, r, err)
+ DefaultHTTPErrorHandler(ctx, nil, &JSONBuiltin{}, w, r, err)
return
}
path := r.URL.Path
if !strings.HasPrefix(path, "/") {
- if s.protoErrorHandler != nil {
- _, outboundMarshaler := MarshalerForRequest(s, r)
- sterr := status.Error(codes.InvalidArgument, http.StatusText(http.StatusBadRequest))
- s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr)
- } else {
- OtherErrorHandler(w, r, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
- }
+ _, outboundMarshaler := MarshalerForRequest(s, r)
+ s.routingErrorHandler(ctx, s, outboundMarshaler, w, r, http.StatusBadRequest)
return
}
- components := strings.Split(path[1:], "/")
- l := len(components)
- var verb string
- if idx := strings.LastIndex(components[l-1], ":"); idx == 0 {
- if s.protoErrorHandler != nil {
- _, outboundMarshaler := MarshalerForRequest(s, r)
- s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, ErrUnknownURI)
- } else {
- OtherErrorHandler(w, r, http.StatusText(http.StatusNotFound), http.StatusNotFound)
- }
- return
- } else if idx > 0 {
- c := components[l-1]
- components[l-1], verb = c[:idx], c[idx+1:]
+ // TODO(v3): remove UnescapingModeLegacy
+ if s.unescapingMode != UnescapingModeLegacy && r.URL.RawPath != "" {
+ path = r.URL.RawPath
+ }
+
+ var components []string
+ // since in UnescapeModeLegacy, the URL will already have been fully unescaped, if we also split on "%2F"
+ // in this escaping mode we would be double unescaping but in UnescapingModeAllCharacters, we still do as the
+ // path is the RawPath (i.e. unescaped). That does mean that the behavior of this function will change its default
+ // behavior when the UnescapingModeDefault gets changed from UnescapingModeLegacy to UnescapingModeAllExceptReserved
+ if s.unescapingMode == UnescapingModeAllCharacters {
+ components = encodedPathSplitter.Split(path[1:], -1)
+ } else {
+ components = strings.Split(path[1:], "/")
}
if override := r.Header.Get("X-HTTP-Method-Override"); override != "" && s.isPathLengthFallback(r) {
r.Method = strings.ToUpper(override)
if err := r.ParseForm(); err != nil {
- if s.protoErrorHandler != nil {
- _, outboundMarshaler := MarshalerForRequest(s, r)
- sterr := status.Error(codes.InvalidArgument, err.Error())
- s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr)
- } else {
- OtherErrorHandler(w, r, err.Error(), http.StatusBadRequest)
- }
+ _, outboundMarshaler := MarshalerForRequest(s, r)
+ sterr := status.Error(codes.InvalidArgument, err.Error())
+ s.errorHandler(ctx, s, outboundMarshaler, w, r, sterr)
return
}
}
+
+ // Verb out here is to memoize for the fallback case below
+ var verb string
+
for _, h := range s.handlers[r.Method] {
- pathParams, err := h.pat.Match(components, verb)
+ // If the pattern has a verb, explicitly look for a suffix in the last
+ // component that matches a colon plus the verb. This allows us to
+ // handle some cases that otherwise can't be correctly handled by the
+ // former LastIndex case, such as when the verb literal itself contains
+ // a colon. This should work for all cases that have run through the
+ // parser because we know what verb we're looking for, however, there
+ // are still some cases that the parser itself cannot disambiguate. See
+ // the comment there if interested.
+ patVerb := h.pat.Verb()
+ l := len(components)
+ lastComponent := components[l-1]
+ var idx int = -1
+ if patVerb != "" && strings.HasSuffix(lastComponent, ":"+patVerb) {
+ idx = len(lastComponent) - len(patVerb) - 1
+ }
+ if idx == 0 {
+ _, outboundMarshaler := MarshalerForRequest(s, r)
+ s.routingErrorHandler(ctx, s, outboundMarshaler, w, r, http.StatusNotFound)
+ return
+ }
+ if idx > 0 {
+ components[l-1], verb = lastComponent[:idx], lastComponent[idx+1:]
+ }
+
+ pathParams, err := h.pat.MatchAndEscape(components, verb, s.unescapingMode)
if err != nil {
+ var mse MalformedSequenceError
+ if ok := errors.As(err, &mse); ok {
+ _, outboundMarshaler := MarshalerForRequest(s, r)
+ s.errorHandler(ctx, s, outboundMarshaler, w, r, &HTTPStatusError{
+ HTTPStatus: http.StatusBadRequest,
+ Err: mse,
+ })
+ }
continue
}
h.h(ctx, w, r, pathParams)
@@ -251,47 +392,43 @@ func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
// lookup other methods to handle fallback from GET to POST and
- // to determine if it is MethodNotAllowed or NotFound.
+ // to determine if it is NotImplemented or NotFound.
for m, handlers := range s.handlers {
if m == r.Method {
continue
}
for _, h := range handlers {
- pathParams, err := h.pat.Match(components, verb)
+ pathParams, err := h.pat.MatchAndEscape(components, verb, s.unescapingMode)
if err != nil {
+ var mse MalformedSequenceError
+ if ok := errors.As(err, &mse); ok {
+ _, outboundMarshaler := MarshalerForRequest(s, r)
+ s.errorHandler(ctx, s, outboundMarshaler, w, r, &HTTPStatusError{
+ HTTPStatus: http.StatusBadRequest,
+ Err: mse,
+ })
+ }
continue
}
// X-HTTP-Method-Override is optional. Always allow fallback to POST.
if s.isPathLengthFallback(r) {
if err := r.ParseForm(); err != nil {
- if s.protoErrorHandler != nil {
- _, outboundMarshaler := MarshalerForRequest(s, r)
- sterr := status.Error(codes.InvalidArgument, err.Error())
- s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr)
- } else {
- OtherErrorHandler(w, r, err.Error(), http.StatusBadRequest)
- }
+ _, outboundMarshaler := MarshalerForRequest(s, r)
+ sterr := status.Error(codes.InvalidArgument, err.Error())
+ s.errorHandler(ctx, s, outboundMarshaler, w, r, sterr)
return
}
h.h(ctx, w, r, pathParams)
return
}
- if s.protoErrorHandler != nil {
- _, outboundMarshaler := MarshalerForRequest(s, r)
- s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, ErrUnknownURI)
- } else {
- OtherErrorHandler(w, r, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
- }
+ _, outboundMarshaler := MarshalerForRequest(s, r)
+ s.routingErrorHandler(ctx, s, outboundMarshaler, w, r, http.StatusMethodNotAllowed)
return
}
}
- if s.protoErrorHandler != nil {
- _, outboundMarshaler := MarshalerForRequest(s, r)
- s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, ErrUnknownURI)
- } else {
- OtherErrorHandler(w, r, http.StatusText(http.StatusNotFound), http.StatusNotFound)
- }
+ _, outboundMarshaler := MarshalerForRequest(s, r)
+ s.routingErrorHandler(ctx, s, outboundMarshaler, w, r, http.StatusNotFound)
}
// GetForwardResponseOptions returns the ForwardResponseOptions associated with this ServeMux.
diff --git a/gateway/runtime/mux_test.go b/gateway/runtime/mux_test.go
index fa4e3c2..91cba14 100644
--- a/gateway/runtime/mux_test.go
+++ b/gateway/runtime/mux_test.go
@@ -6,11 +6,17 @@ import (
"fmt"
"net/http"
"net/http/httptest"
+ "net/url"
+ "strconv"
+ "strings"
"testing"
- "github.com/binchencoder/ease-gateway/gateway/runtime"
- "github.com/grpc-ecosystem/grpc-gateway/utilities"
+ // "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
+ "github.com/binchencoder/janus-gateway/gateway/runtime"
+ "github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
+ "google.golang.org/grpc"
"google.golang.org/grpc/codes"
+ "google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/status"
)
@@ -21,9 +27,8 @@ func TestMuxServeHTTP(t *testing.T) {
pool []string
verb string
}
- for _, spec := range []struct {
- patterns []stubPattern
- patternOpts []runtime.PatternOpt
+ for i, spec := range []struct {
+ patterns []stubPattern
reqMethod string
reqPath string
@@ -33,8 +38,7 @@ func TestMuxServeHTTP(t *testing.T) {
respContent string
disablePathLengthFallback bool
- errHandler runtime.ProtoErrorHandlerFunc
- muxOpts []runtime.ServeMuxOption
+ unescapingMode runtime.UnescapingMode
}{
{
patterns: nil,
@@ -71,12 +75,12 @@ func TestMuxServeHTTP(t *testing.T) {
patterns: []stubPattern{
{
method: "GET",
- ops: []int{int(utilities.OpLitPush), 0},
- pool: []string{"foo"},
+ ops: []int{int(utilities.OpPush), 0},
},
{
method: "GET",
- ops: []int{int(utilities.OpPush), 0},
+ ops: []int{int(utilities.OpLitPush), 0},
+ pool: []string{"foo"},
},
},
reqMethod: "GET",
@@ -112,7 +116,7 @@ func TestMuxServeHTTP(t *testing.T) {
},
reqMethod: "DELETE",
reqPath: "/foo",
- respStatus: http.StatusMethodNotAllowed,
+ respStatus: http.StatusNotImplemented,
},
{
patterns: []stubPattern{
@@ -143,8 +147,7 @@ func TestMuxServeHTTP(t *testing.T) {
headers: map[string]string{
"Content-Type": "application/x-www-form-urlencoded",
},
- respStatus: http.StatusMethodNotAllowed,
- respContent: "Method Not Allowed\n",
+ respStatus: http.StatusNotImplemented,
disablePathLengthFallback: true,
},
{
@@ -204,7 +207,7 @@ func TestMuxServeHTTP(t *testing.T) {
headers: map[string]string{
"Content-Type": "application/json",
},
- respStatus: http.StatusMethodNotAllowed,
+ respStatus: http.StatusNotImplemented,
},
{
patterns: []stubPattern{
@@ -246,70 +249,73 @@ func TestMuxServeHTTP(t *testing.T) {
respContent: "GET /foo/{id=*}:verb",
},
{
- // mux identifying invalid path results in 'Not Found' status
- // (with custom handler looking for ErrUnknownURI)
patterns: []stubPattern{
{
method: "GET",
- ops: []int{int(utilities.OpLitPush), 0},
- pool: []string{"unimplemented"},
+ ops: []int{int(utilities.OpLitPush), 0, int(utilities.OpPush), 0, int(utilities.OpConcatN), 1, int(utilities.OpCapture), 1},
+ pool: []string{"foo", "id"},
},
},
- reqMethod: "GET",
- reqPath: "/foobar",
- respStatus: http.StatusNotFound,
- respContent: "GET /foobar",
- errHandler: unknownPathIs404,
+ reqMethod: "GET",
+ reqPath: "/foo/bar",
+ headers: map[string]string{
+ "Content-Type": "application/json",
+ },
+ respStatus: http.StatusOK,
+ respContent: "GET /foo/{id=*}",
},
{
- // server returning unimplemented results in 'Not Implemented' code
- // even when using custom error handler
patterns: []stubPattern{
{
method: "GET",
- ops: []int{int(utilities.OpLitPush), 0},
- pool: []string{"unimplemented"},
+ ops: []int{int(utilities.OpLitPush), 0, int(utilities.OpPush), 0, int(utilities.OpConcatN), 1, int(utilities.OpCapture), 1},
+ pool: []string{"foo", "id"},
},
},
- reqMethod: "GET",
- reqPath: "/unimplemented",
- respStatus: http.StatusNotImplemented,
- respContent: `GET /unimplemented`,
- errHandler: unknownPathIs404,
+ reqMethod: "GET",
+ reqPath: "/foo/bar:123",
+ headers: map[string]string{
+ "Content-Type": "application/json",
+ },
+ respStatus: http.StatusOK,
+ respContent: "GET /foo/{id=*}",
},
{
patterns: []stubPattern{
{
- method: "GET",
+ method: "POST",
ops: []int{int(utilities.OpLitPush), 0, int(utilities.OpPush), 0, int(utilities.OpConcatN), 1, int(utilities.OpCapture), 1},
pool: []string{"foo", "id"},
},
+ {
+ method: "POST",
+ ops: []int{int(utilities.OpLitPush), 0, int(utilities.OpPush), 0, int(utilities.OpConcatN), 1, int(utilities.OpCapture), 1},
+ pool: []string{"foo", "id"},
+ verb: "verb",
+ },
},
- patternOpts: []runtime.PatternOpt{runtime.AssumeColonVerbOpt(false)},
- reqMethod: "GET",
- reqPath: "/foo/bar",
+ reqMethod: "POST",
+ reqPath: "/foo/bar:verb",
headers: map[string]string{
"Content-Type": "application/json",
},
respStatus: http.StatusOK,
- respContent: "GET /foo/{id=*}",
+ respContent: "POST /foo/{id=*}:verb",
},
{
patterns: []stubPattern{
{
method: "GET",
- ops: []int{int(utilities.OpLitPush), 0, int(utilities.OpPush), 0, int(utilities.OpConcatN), 1, int(utilities.OpCapture), 1},
- pool: []string{"foo", "id"},
+ ops: []int{int(utilities.OpLitPush), 0},
+ pool: []string{"foo"},
},
},
- patternOpts: []runtime.PatternOpt{runtime.AssumeColonVerbOpt(false)},
- reqMethod: "GET",
- reqPath: "/foo/bar:123",
+ reqMethod: "POST",
+ reqPath: "foo",
headers: map[string]string{
"Content-Type": "application/json",
},
- respStatus: http.StatusOK,
- respContent: "GET /foo/{id=*}",
+ respStatus: http.StatusBadRequest,
},
{
patterns: []stubPattern{
@@ -322,78 +328,187 @@ func TestMuxServeHTTP(t *testing.T) {
method: "POST",
ops: []int{int(utilities.OpLitPush), 0, int(utilities.OpPush), 0, int(utilities.OpConcatN), 1, int(utilities.OpCapture), 1},
pool: []string{"foo", "id"},
- verb: "verb",
+ verb: "verb:subverb",
},
},
- patternOpts: []runtime.PatternOpt{runtime.AssumeColonVerbOpt(false)},
- reqMethod: "POST",
- reqPath: "/foo/bar:verb",
+ reqMethod: "POST",
+ reqPath: "/foo/bar:verb:subverb",
headers: map[string]string{
"Content-Type": "application/json",
},
respStatus: http.StatusOK,
- respContent: "POST /foo/{id=*}:verb",
- muxOpts: []runtime.ServeMuxOption{runtime.WithLastMatchWins()},
+ respContent: "POST /foo/{id=*}:verb:subverb",
+ },
+ {
+ patterns: []stubPattern{
+ {
+ method: "GET",
+ ops: []int{int(utilities.OpLitPush), 0, int(utilities.OpPush), 1, int(utilities.OpCapture), 1, int(utilities.OpLitPush), 2},
+ pool: []string{"foo", "id", "bar"},
+ },
+ },
+ reqMethod: "POST",
+ reqPath: "/foo/404%2fwith%2Fspace/bar",
+ headers: map[string]string{
+ "Content-Type": "application/json",
+ },
+ respStatus: http.StatusNotFound,
+ unescapingMode: runtime.UnescapingModeLegacy,
+ },
+ {
+ patterns: []stubPattern{
+ {
+ method: "GET",
+ ops: []int{
+ int(utilities.OpLitPush), 0,
+ int(utilities.OpPush), 0,
+ int(utilities.OpConcatN), 1,
+ int(utilities.OpCapture), 1,
+ int(utilities.OpLitPush), 2},
+ pool: []string{"foo", "id", "bar"},
+ },
+ },
+ reqMethod: "GET",
+ reqPath: "/foo/success%2fwith%2Fspace/bar",
+ headers: map[string]string{
+ "Content-Type": "application/json",
+ },
+ respStatus: http.StatusOK,
+ unescapingMode: runtime.UnescapingModeAllExceptReserved,
+ respContent: "GET /foo/{id=*}/bar",
+ },
+ {
+ patterns: []stubPattern{
+ {
+ method: "GET",
+ ops: []int{
+ int(utilities.OpLitPush), 0,
+ int(utilities.OpPush), 0,
+ int(utilities.OpConcatN), 1,
+ int(utilities.OpCapture), 1,
+ int(utilities.OpLitPush), 2},
+ pool: []string{"foo", "id", "bar"},
+ },
+ },
+ reqMethod: "GET",
+ reqPath: "/foo/success%2fwith%2Fspace/bar",
+ headers: map[string]string{
+ "Content-Type": "application/json",
+ },
+ respStatus: http.StatusNotFound,
+ unescapingMode: runtime.UnescapingModeAllCharacters,
+ },
+ {
+ patterns: []stubPattern{
+ {
+ method: "GET",
+ ops: []int{
+ int(utilities.OpLitPush), 0,
+ int(utilities.OpPush), 0,
+ int(utilities.OpConcatN), 1,
+ int(utilities.OpCapture), 1,
+ int(utilities.OpLitPush), 2},
+ pool: []string{"foo", "id", "bar"},
+ },
+ },
+ reqMethod: "GET",
+ reqPath: "/foo/success%2fwith%2Fspace/bar",
+ headers: map[string]string{
+ "Content-Type": "application/json",
+ },
+ respStatus: http.StatusNotFound,
+ unescapingMode: runtime.UnescapingModeLegacy,
+ },
+ {
+ patterns: []stubPattern{
+ {
+ method: "GET",
+ ops: []int{
+ int(utilities.OpLitPush), 0,
+ int(utilities.OpPushM), 0,
+ int(utilities.OpConcatN), 1,
+ int(utilities.OpCapture), 1,
+ },
+ pool: []string{"foo", "id", "bar"},
+ },
+ },
+ reqMethod: "GET",
+ reqPath: "/foo/success%2fwith%2Fspace",
+ headers: map[string]string{
+ "Content-Type": "application/json",
+ },
+ respStatus: http.StatusOK,
+ unescapingMode: runtime.UnescapingModeAllExceptReserved,
+ respContent: "GET /foo/{id=**}",
+ },
+ {
+ patterns: []stubPattern{
+ {
+ method: "POST",
+ ops: []int{
+ int(utilities.OpLitPush), 0,
+ int(utilities.OpLitPush), 1,
+ int(utilities.OpLitPush), 2,
+ int(utilities.OpPush), 0,
+ int(utilities.OpConcatN), 2,
+ int(utilities.OpCapture), 3,
+ },
+ pool: []string{"api", "v1", "organizations", "name"},
+ verb: "action",
+ },
+ },
+ reqMethod: "POST",
+ reqPath: "/api/v1/" + url.QueryEscape("organizations/foo") + ":action",
+ headers: map[string]string{
+ "Content-Type": "application/json",
+ },
+ respStatus: http.StatusOK,
+ unescapingMode: runtime.UnescapingModeAllCharacters,
+ respContent: "POST /api/v1/{name=organizations/*}:action",
},
} {
- opts := spec.muxOpts
- if spec.disablePathLengthFallback {
- opts = append(opts, runtime.WithDisablePathLengthFallback())
- }
- if spec.errHandler != nil {
- opts = append(opts, runtime.WithProtoErrorHandler(spec.errHandler))
- }
- mux := runtime.NewServeMux(opts...)
- for _, p := range spec.patterns {
- func(p stubPattern) {
- pat, err := runtime.NewPattern(1, p.ops, p.pool, p.verb, spec.patternOpts...)
- if err != nil {
- t.Fatalf("runtime.NewPattern(1, %#v, %#v, %q) failed with %v; want success", p.ops, p.pool, p.verb, err)
- }
- mux.Handle(p.method, pat, 1 /* sid */, func(ctx context.Context, w http.ResponseWriter, r *http.Request, pathParams map[string]string) {
- if r.URL.Path == "/unimplemented" {
- // simulate method returning "unimplemented" error
- _, m := runtime.MarshalerForRequest(mux, r)
- runtime.HTTPError(r.Context(), mux, m, w, r, status.Error(codes.Unimplemented, http.StatusText(http.StatusNotImplemented)))
- w.WriteHeader(http.StatusNotImplemented)
- return
+ t.Run(strconv.Itoa(i), func(t *testing.T) {
+ var opts []runtime.ServeMuxOption
+ opts = append(opts, runtime.WithUnescapingMode(spec.unescapingMode))
+ if spec.disablePathLengthFallback {
+ opts = append(opts,
+ runtime.WithDisablePathLengthFallback(),
+ )
+ }
+ mux := runtime.NewServeMux(opts...)
+ for _, p := range spec.patterns {
+ func(p stubPattern) {
+ pat, err := runtime.NewPattern(1, p.ops, p.pool, p.verb)
+ if err != nil {
+ t.Fatalf("runtime.NewPattern(1, %#v, %#v, %q) failed with %v; want success", p.ops, p.pool, p.verb, err)
}
- fmt.Fprintf(w, "%s %s", p.method, pat.String())
- })
- }(p)
- }
-
- url := fmt.Sprintf("http://host.example%s", spec.reqPath)
- r, err := http.NewRequest(spec.reqMethod, url, bytes.NewReader(nil))
- if err != nil {
- t.Fatalf("http.NewRequest(%q, %q, nil) failed with %v; want success", spec.reqMethod, url, err)
- }
- for name, value := range spec.headers {
- r.Header.Set(name, value)
- }
- w := httptest.NewRecorder()
- mux.ServeHTTP(w, r)
-
- if got, want := w.Code, spec.respStatus; got != want {
- t.Errorf("w.Code = %d; want %d; patterns=%v; req=%v", got, want, spec.patterns, r)
- }
- if spec.respContent != "" {
- if got, want := w.Body.String(), spec.respContent; got != want {
- t.Errorf("w.Body = %q; want %q; patterns=%v; req=%v", got, want, spec.patterns, r)
+ mux.Handle(p.method, pat, 1 /* sid */, func(ctx context.Context, w http.ResponseWriter, r *http.Request, pathParams map[string]string) {
+ fmt.Fprintf(w, "%s %s", p.method, pat.String())
+ })
+ }(p)
}
- }
- }
-}
-func unknownPathIs404(ctx context.Context, mux *runtime.ServeMux, m runtime.Marshaler, w http.ResponseWriter, r *http.Request, err error) {
- if err == runtime.ErrUnknownURI {
- w.WriteHeader(http.StatusNotFound)
- } else {
- c := status.Convert(err).Code()
- w.WriteHeader(runtime.HTTPStatusFromCode(c))
- }
+ reqUrl := fmt.Sprintf("https://host.example%s", spec.reqPath)
+ r, err := http.NewRequest(spec.reqMethod, reqUrl, bytes.NewReader(nil))
+ if err != nil {
+ t.Fatalf("http.NewRequest(%q, %q, nil) failed with %v; want success", spec.reqMethod, reqUrl, err)
+ }
+ for name, value := range spec.headers {
+ r.Header.Set(name, value)
+ }
+ w := httptest.NewRecorder()
+ mux.ServeHTTP(w, r)
- fmt.Fprintf(w, "%s %s", r.Method, r.URL.Path)
+ if got, want := w.Code, spec.respStatus; got != want {
+ t.Errorf("w.Code = %d; want %d; patterns=%v; req=%v", got, want, spec.patterns, r)
+ }
+ if spec.respContent != "" {
+ if got, want := w.Body.String(), spec.respContent; got != want {
+ t.Errorf("w.Body = %q; want %q; patterns=%v; req=%v", got, want, spec.patterns, r)
+ }
+ }
+ })
+ }
}
var defaultHeaderMatcherTests = []struct {
@@ -435,3 +550,191 @@ func TestDefaultHeaderMatcher(t *testing.T) {
})
}
}
+
+var defaultRouteMatcherTests = []struct {
+ name string
+ method string
+ path string
+ valid bool
+}{
+ {
+ "Test route /",
+ "GET",
+ "/",
+ true,
+ },
+ {
+ "Simple Endpoint",
+ "GET",
+ "/v1/{bucket}/do:action",
+ true,
+ },
+ {
+ "Complex Endpoint",
+ "POST",
+ "/v1/b/{bucket_name=buckets/*}/o/{name}",
+ true,
+ },
+ {
+ "Wildcard Endpoint",
+ "GET",
+ "/v1/endpoint/*",
+ true,
+ },
+ {
+ "Invalid Endpoint",
+ "POST",
+ "v1/b/:name/do",
+ false,
+ },
+}
+
+func TestServeMux_HandlePath(t *testing.T) {
+ mux := runtime.NewServeMux()
+ testFn := func(ctx context.Context, w http.ResponseWriter, r *http.Request, pathParams map[string]string) {
+ }
+ for _, tt := range defaultRouteMatcherTests {
+ t.Run(tt.name, func(t *testing.T) {
+ err := mux.HandlePath(tt.method, tt.path, 1 /* sid */, testFn)
+ if tt.valid && err != nil {
+ t.Errorf("The route %v with method %v and path %v invalid, got %v", tt.name, tt.method, tt.path, err)
+ }
+ if !tt.valid && err == nil {
+ t.Errorf("The route %v with method %v and path %v should be invalid", tt.name, tt.method, tt.path)
+ }
+ })
+ }
+}
+
+var healthCheckTests = []struct {
+ name string
+ code codes.Code
+ status grpc_health_v1.HealthCheckResponse_ServingStatus
+ httpStatusCode int
+}{
+ {
+ "Test grpc error code",
+ codes.NotFound,
+ grpc_health_v1.HealthCheckResponse_UNKNOWN,
+ http.StatusNotFound,
+ },
+ {
+ "Test HealthCheckResponse_SERVING",
+ codes.OK,
+ grpc_health_v1.HealthCheckResponse_SERVING,
+ http.StatusOK,
+ },
+ {
+ "Test HealthCheckResponse_NOT_SERVING",
+ codes.OK,
+ grpc_health_v1.HealthCheckResponse_NOT_SERVING,
+ http.StatusServiceUnavailable,
+ },
+ {
+ "Test HealthCheckResponse_UNKNOWN",
+ codes.OK,
+ grpc_health_v1.HealthCheckResponse_UNKNOWN,
+ http.StatusServiceUnavailable,
+ },
+ {
+ "Test HealthCheckResponse_SERVICE_UNKNOWN",
+ codes.OK,
+ grpc_health_v1.HealthCheckResponse_SERVICE_UNKNOWN,
+ http.StatusNotFound,
+ },
+}
+
+func TestWithHealthzEndpoint_codes(t *testing.T) {
+ for _, tt := range healthCheckTests {
+ t.Run(tt.name, func(t *testing.T) {
+ mux := runtime.NewServeMux(runtime.WithHealthzEndpoint(&dummyHealthCheckClient{status: tt.status, code: tt.code}, 1 /* sid */))
+
+ r := httptest.NewRequest(http.MethodGet, "/healthz", nil)
+ rr := httptest.NewRecorder()
+
+ mux.ServeHTTP(rr, r)
+
+ if rr.Code != tt.httpStatusCode {
+ t.Errorf(
+ "result http status code for grpc code %q and status %q should be %d, got %d",
+ tt.code, tt.status, tt.httpStatusCode, rr.Code,
+ )
+ }
+ })
+ }
+}
+
+func TestWithHealthEndpointAt_consistentWithHealthz(t *testing.T) {
+ const endpointPath = "/healthz"
+
+ r := httptest.NewRequest(http.MethodGet, endpointPath, nil)
+
+ for _, tt := range healthCheckTests {
+ tt := tt
+
+ t.Run(tt.name, func(t *testing.T) {
+ client := &dummyHealthCheckClient{
+ status: tt.status,
+ code: tt.code,
+ }
+
+ w := httptest.NewRecorder()
+
+ runtime.NewServeMux(
+ runtime.WithHealthEndpointAt(client, endpointPath, 1 /* sid */),
+ ).ServeHTTP(w, r)
+
+ refW := httptest.NewRecorder()
+
+ runtime.NewServeMux(
+ runtime.WithHealthzEndpoint(client, 1 /* sid */),
+ ).ServeHTTP(refW, r)
+
+ if w.Code != refW.Code {
+ t.Errorf(
+ "result http status code for grpc code %q and status %q should be equal to %d, but got %d",
+ tt.code, tt.status, refW.Code, w.Code,
+ )
+ }
+ })
+ }
+}
+
+func TestWithHealthzEndpoint_serviceParam(t *testing.T) {
+ service := "test"
+
+ // trigger error to output service in body
+ dummyClient := dummyHealthCheckClient{status: grpc_health_v1.HealthCheckResponse_UNKNOWN, code: codes.Unknown}
+ mux := runtime.NewServeMux(runtime.WithHealthzEndpoint(&dummyClient, 1 /* sid */))
+
+ r := httptest.NewRequest(http.MethodGet, "/healthz?service="+service, nil)
+ rr := httptest.NewRecorder()
+
+ mux.ServeHTTP(rr, r)
+
+ if !strings.Contains(rr.Body.String(), service) {
+ t.Errorf(
+ "service query parameter should be translated to HealthCheckRequest: expected %s to contain %s",
+ rr.Body.String(), service,
+ )
+ }
+}
+
+var _ grpc_health_v1.HealthClient = (*dummyHealthCheckClient)(nil)
+
+type dummyHealthCheckClient struct {
+ status grpc_health_v1.HealthCheckResponse_ServingStatus
+ code codes.Code
+}
+
+func (g *dummyHealthCheckClient) Check(ctx context.Context, r *grpc_health_v1.HealthCheckRequest, opts ...grpc.CallOption) (*grpc_health_v1.HealthCheckResponse, error) {
+ if g.code != codes.OK {
+ return nil, status.Error(g.code, r.GetService())
+ }
+
+ return &grpc_health_v1.HealthCheckResponse{Status: g.status}, nil
+}
+
+func (g *dummyHealthCheckClient) Watch(ctx context.Context, r *grpc_health_v1.HealthCheckRequest, opts ...grpc.CallOption) (grpc_health_v1.Health_WatchClient, error) {
+ return nil, status.Error(codes.Unimplemented, "unimplemented")
+}
diff --git a/gateway/runtime/pattern.go b/gateway/runtime/pattern.go
index 0905369..df7cb81 100644
--- a/gateway/runtime/pattern.go
+++ b/gateway/runtime/pattern.go
@@ -3,9 +3,10 @@ package runtime
import (
"errors"
"fmt"
+ "strconv"
"strings"
- "github.com/grpc-ecosystem/grpc-gateway/utilities"
+ "github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
"google.golang.org/grpc/grpclog"
)
@@ -14,14 +15,23 @@ var (
ErrNotMatch = errors.New("not match to the path pattern")
// ErrInvalidPattern indicates that the given definition of Pattern is not valid.
ErrInvalidPattern = errors.New("invalid pattern")
+ // ErrMalformedSequence indicates that an escape sequence was malformed.
+ ErrMalformedSequence = errors.New("malformed escape sequence")
)
+type MalformedSequenceError string
+
+func (e MalformedSequenceError) Error() string {
+ return "malformed path escape " + strconv.Quote(string(e))
+}
+
type op struct {
code utilities.OpCode
operand int
}
-// Pattern is a template pattern of http request paths defined in github.com/googleapis/googleapis/google/api/http.proto.
+// Pattern is a template pattern of http request paths defined in
+// https://github.com/googleapis/googleapis/blob/master/google/api/http.proto
type Pattern struct {
// ops is a list of operations
ops []op
@@ -35,31 +45,14 @@ type Pattern struct {
tailLen int
// verb is the VERB part of the path pattern. It is empty if the pattern does not have VERB part.
verb string
- // assumeColonVerb indicates whether a path suffix after a final
- // colon may only be interpreted as a verb.
- assumeColonVerb bool
}
-type patternOptions struct {
- assumeColonVerb bool
-}
-
-// PatternOpt is an option for creating Patterns.
-type PatternOpt func(*patternOptions)
-
// NewPattern returns a new Pattern from the given definition values.
// "ops" is a sequence of op codes. "pool" is a constant pool.
// "verb" is the verb part of the pattern. It is empty if the pattern does not have the part.
// "version" must be 1 for now.
// It returns an error if the given definition is invalid.
-func NewPattern(version int, ops []int, pool []string, verb string, opts ...PatternOpt) (Pattern, error) {
- options := patternOptions{
- assumeColonVerb: true,
- }
- for _, o := range opts {
- o(&options)
- }
-
+func NewPattern(version int, ops []int, pool []string, verb string) (Pattern, error) {
if version != 1 {
grpclog.Infof("unsupported version: %d", version)
return Pattern{}, ErrInvalidPattern
@@ -111,7 +104,7 @@ func NewPattern(version int, ops []int, pool []string, verb string, opts ...Patt
}
stack -= op.operand
if stack < 0 {
- grpclog.Print("stack underflow")
+ grpclog.Info("stack underflow")
return Pattern{}, ErrInvalidPattern
}
stack++
@@ -139,13 +132,12 @@ func NewPattern(version int, ops []int, pool []string, verb string, opts ...Patt
typedOps = append(typedOps, op)
}
return Pattern{
- ops: typedOps,
- pool: pool,
- vars: vars,
- stacksize: maxstack,
- tailLen: tailLen,
- verb: verb,
- assumeColonVerb: options.assumeColonVerb,
+ ops: typedOps,
+ pool: pool,
+ vars: vars,
+ stacksize: maxstack,
+ tailLen: tailLen,
+ verb: verb,
}, nil
}
@@ -157,12 +149,13 @@ func MustPattern(p Pattern, err error) Pattern {
return p
}
-// Match examines components if it matches to the Pattern.
-// If it matches, the function returns a mapping from field paths to their captured values.
-// If otherwise, the function returns an error.
-func (p Pattern) Match(components []string, verb string) (map[string]string, error) {
+// MatchAndEscape examines components to determine if they match to a Pattern.
+// MatchAndEscape will return an error if no Patterns matched or if a pattern
+// matched but contained malformed escape sequences. If successful, the function
+// returns a mapping from field paths to their captured values.
+func (p Pattern) MatchAndEscape(components []string, verb string, unescapingMode UnescapingMode) (map[string]string, error) {
if p.verb != verb {
- if p.assumeColonVerb || p.verb != "" {
+ if p.verb != "" {
return nil, ErrNotMatch
}
if len(components) == 0 {
@@ -171,7 +164,6 @@ func (p Pattern) Match(components []string, verb string) (map[string]string, err
components = append([]string{}, components...)
components[len(components)-1] += ":" + verb
}
- verb = ""
}
var pos int
@@ -179,6 +171,8 @@ func (p Pattern) Match(components []string, verb string) (map[string]string, err
captured := make([]string, len(p.vars))
l := len(components)
for _, op := range p.ops {
+ var err error
+
switch op.code {
case utilities.OpNop:
continue
@@ -191,6 +185,10 @@ func (p Pattern) Match(components []string, verb string) (map[string]string, err
if lit := p.pool[op.operand]; c != lit {
return nil, ErrNotMatch
}
+ } else if op.code == utilities.OpPush {
+ if c, err = unescape(c, unescapingMode, false); err != nil {
+ return nil, err
+ }
}
stack = append(stack, c)
pos++
@@ -200,7 +198,11 @@ func (p Pattern) Match(components []string, verb string) (map[string]string, err
return nil, ErrNotMatch
}
end -= p.tailLen
- stack = append(stack, strings.Join(components[pos:end], "/"))
+ c := strings.Join(components[pos:end], "/")
+ if c, err = unescape(c, unescapingMode, true); err != nil {
+ return nil, err
+ }
+ stack = append(stack, c)
pos = end
case utilities.OpConcatN:
n := op.operand
@@ -222,6 +224,16 @@ func (p Pattern) Match(components []string, verb string) (map[string]string, err
return bindings, nil
}
+// MatchAndEscape examines components to determine if they match to a Pattern.
+// It will never perform per-component unescaping (see: UnescapingModeLegacy).
+// MatchAndEscape will return an error if no Patterns matched. If successful,
+// the function returns a mapping from field paths to their captured values.
+//
+// Deprecated: Use MatchAndEscape.
+func (p Pattern) Match(components []string, verb string) (map[string]string, error) {
+ return p.MatchAndEscape(components, verb, UnescapingModeDefault)
+}
+
// Verb returns the verb part of the Pattern.
func (p Pattern) Verb() string { return p.verb }
@@ -253,10 +265,119 @@ func (p Pattern) String() string {
return "/" + segs
}
-// AssumeColonVerbOpt indicates whether a path suffix after a final
-// colon may only be interpreted as a verb.
-func AssumeColonVerbOpt(val bool) PatternOpt {
- return PatternOpt(func(o *patternOptions) {
- o.assumeColonVerb = val
- })
+/*
+ * The following code is adopted and modified from Go's standard library
+ * and carries the attached license.
+ *
+ * Copyright 2009 The Go Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file.
+ */
+
+// ishex returns whether or not the given byte is a valid hex character
+func ishex(c byte) bool {
+ switch {
+ case '0' <= c && c <= '9':
+ return true
+ case 'a' <= c && c <= 'f':
+ return true
+ case 'A' <= c && c <= 'F':
+ return true
+ }
+ return false
+}
+
+func isRFC6570Reserved(c byte) bool {
+ switch c {
+ case '!', '#', '$', '&', '\'', '(', ')', '*',
+ '+', ',', '/', ':', ';', '=', '?', '@', '[', ']':
+ return true
+ default:
+ return false
+ }
+}
+
+// unhex converts a hex point to the bit representation
+func unhex(c byte) byte {
+ switch {
+ case '0' <= c && c <= '9':
+ return c - '0'
+ case 'a' <= c && c <= 'f':
+ return c - 'a' + 10
+ case 'A' <= c && c <= 'F':
+ return c - 'A' + 10
+ }
+ return 0
+}
+
+// shouldUnescapeWithMode returns true if the character is escapable with the
+// given mode
+func shouldUnescapeWithMode(c byte, mode UnescapingMode) bool {
+ switch mode {
+ case UnescapingModeAllExceptReserved:
+ if isRFC6570Reserved(c) {
+ return false
+ }
+ case UnescapingModeAllExceptSlash:
+ if c == '/' {
+ return false
+ }
+ case UnescapingModeAllCharacters:
+ return true
+ }
+ return true
+}
+
+// unescape unescapes a path string using the provided mode
+func unescape(s string, mode UnescapingMode, multisegment bool) (string, error) {
+ // TODO(v3): remove UnescapingModeLegacy
+ if mode == UnescapingModeLegacy {
+ return s, nil
+ }
+
+ if !multisegment {
+ mode = UnescapingModeAllCharacters
+ }
+
+ // Count %, check that they're well-formed.
+ n := 0
+ for i := 0; i < len(s); {
+ if s[i] == '%' {
+ n++
+ if i+2 >= len(s) || !ishex(s[i+1]) || !ishex(s[i+2]) {
+ s = s[i:]
+ if len(s) > 3 {
+ s = s[:3]
+ }
+
+ return "", MalformedSequenceError(s)
+ }
+ i += 3
+ } else {
+ i++
+ }
+ }
+
+ if n == 0 {
+ return s, nil
+ }
+
+ var t strings.Builder
+ t.Grow(len(s))
+ for i := 0; i < len(s); i++ {
+ switch s[i] {
+ case '%':
+ c := unhex(s[i+1])<<4 | unhex(s[i+2])
+ if shouldUnescapeWithMode(c, mode) {
+ t.WriteByte(c)
+ i += 2
+ continue
+ }
+ fallthrough
+ default:
+ t.WriteByte(s[i])
+ }
+ }
+
+ return t.String(), nil
}
diff --git a/gateway/runtime/pattern_test.go b/gateway/runtime/pattern_test.go
deleted file mode 100644
index 8f5a664..0000000
--- a/gateway/runtime/pattern_test.go
+++ /dev/null
@@ -1,590 +0,0 @@
-package runtime
-
-import (
- "fmt"
- "reflect"
- "strings"
- "testing"
-
- "github.com/grpc-ecosystem/grpc-gateway/utilities"
-)
-
-const (
- validVersion = 1
- anything = 0
-)
-
-func TestNewPattern(t *testing.T) {
- for _, spec := range []struct {
- ops []int
- pool []string
- verb string
-
- stackSizeWant, tailLenWant int
- }{
- {},
- {
- ops: []int{int(utilities.OpNop), anything},
- stackSizeWant: 0,
- tailLenWant: 0,
- },
- {
- ops: []int{int(utilities.OpPush), anything},
- stackSizeWant: 1,
- tailLenWant: 0,
- },
- {
- ops: []int{int(utilities.OpLitPush), 0},
- pool: []string{"abc"},
- stackSizeWant: 1,
- tailLenWant: 0,
- },
- {
- ops: []int{int(utilities.OpPushM), anything},
- stackSizeWant: 1,
- tailLenWant: 0,
- },
- {
- ops: []int{
- int(utilities.OpPush), anything,
- int(utilities.OpConcatN), 1,
- },
- stackSizeWant: 1,
- tailLenWant: 0,
- },
- {
- ops: []int{
- int(utilities.OpPush), anything,
- int(utilities.OpConcatN), 1,
- int(utilities.OpCapture), 0,
- },
- pool: []string{"abc"},
- stackSizeWant: 1,
- tailLenWant: 0,
- },
- {
- ops: []int{
- int(utilities.OpPush), anything,
- int(utilities.OpLitPush), 0,
- int(utilities.OpLitPush), 1,
- int(utilities.OpPushM), anything,
- int(utilities.OpConcatN), 2,
- int(utilities.OpCapture), 2,
- },
- pool: []string{"lit1", "lit2", "var1"},
- stackSizeWant: 4,
- tailLenWant: 0,
- },
- {
- ops: []int{
- int(utilities.OpPushM), anything,
- int(utilities.OpConcatN), 1,
- int(utilities.OpCapture), 2,
- int(utilities.OpLitPush), 0,
- int(utilities.OpLitPush), 1,
- },
- pool: []string{"lit1", "lit2", "var1"},
- stackSizeWant: 2,
- tailLenWant: 2,
- },
- {
- ops: []int{
- int(utilities.OpLitPush), 0,
- int(utilities.OpLitPush), 1,
- int(utilities.OpPushM), anything,
- int(utilities.OpLitPush), 2,
- int(utilities.OpConcatN), 3,
- int(utilities.OpLitPush), 3,
- int(utilities.OpCapture), 4,
- },
- pool: []string{"lit1", "lit2", "lit3", "lit4", "var1"},
- stackSizeWant: 4,
- tailLenWant: 2,
- },
- {
- ops: []int{int(utilities.OpLitPush), 0},
- pool: []string{"abc"},
- verb: "LOCK",
- stackSizeWant: 1,
- tailLenWant: 0,
- },
- } {
- pat, err := NewPattern(validVersion, spec.ops, spec.pool, spec.verb)
- if err != nil {
- t.Errorf("NewPattern(%d, %v, %q, %q) failed with %v; want success", validVersion, spec.ops, spec.pool, spec.verb, err)
- continue
- }
- if got, want := pat.stacksize, spec.stackSizeWant; got != want {
- t.Errorf("pat.stacksize = %d; want %d", got, want)
- }
- if got, want := pat.tailLen, spec.tailLenWant; got != want {
- t.Errorf("pat.stacksize = %d; want %d", got, want)
- }
- }
-}
-
-func TestNewPatternWithWrongOp(t *testing.T) {
- for _, spec := range []struct {
- ops []int
- pool []string
- verb string
- }{
- {
- // op code out of bound
- ops: []int{-1, anything},
- },
- {
- // op code out of bound
- ops: []int{int(utilities.OpEnd), 0},
- },
- {
- // odd number of items
- ops: []int{int(utilities.OpPush)},
- },
- {
- // negative index
- ops: []int{int(utilities.OpLitPush), -1},
- pool: []string{"abc"},
- },
- {
- // index out of bound
- ops: []int{int(utilities.OpLitPush), 1},
- pool: []string{"abc"},
- },
- {
- // negative # of segments
- ops: []int{int(utilities.OpConcatN), -1},
- pool: []string{"abc"},
- },
- {
- // negative index
- ops: []int{int(utilities.OpCapture), -1},
- pool: []string{"abc"},
- },
- {
- // index out of bound
- ops: []int{int(utilities.OpCapture), 1},
- pool: []string{"abc"},
- },
- {
- // pushM appears twice
- ops: []int{
- int(utilities.OpPushM), anything,
- int(utilities.OpLitPush), 0,
- int(utilities.OpPushM), anything,
- },
- pool: []string{"abc"},
- },
- } {
- _, err := NewPattern(validVersion, spec.ops, spec.pool, spec.verb)
- if err == nil {
- t.Errorf("NewPattern(%d, %v, %q, %q) succeeded; want failure with %v", validVersion, spec.ops, spec.pool, spec.verb, ErrInvalidPattern)
- continue
- }
- if err != ErrInvalidPattern {
- t.Errorf("NewPattern(%d, %v, %q, %q) failed with %v; want failure with %v", validVersion, spec.ops, spec.pool, spec.verb, err, ErrInvalidPattern)
- continue
- }
- }
-}
-
-func TestNewPatternWithStackUnderflow(t *testing.T) {
- for _, spec := range []struct {
- ops []int
- pool []string
- verb string
- }{
- {
- ops: []int{int(utilities.OpConcatN), 1},
- },
- {
- ops: []int{int(utilities.OpCapture), 0},
- pool: []string{"abc"},
- },
- } {
- _, err := NewPattern(validVersion, spec.ops, spec.pool, spec.verb)
- if err == nil {
- t.Errorf("NewPattern(%d, %v, %q, %q) succeeded; want failure with %v", validVersion, spec.ops, spec.pool, spec.verb, ErrInvalidPattern)
- continue
- }
- if err != ErrInvalidPattern {
- t.Errorf("NewPattern(%d, %v, %q, %q) failed with %v; want failure with %v", validVersion, spec.ops, spec.pool, spec.verb, err, ErrInvalidPattern)
- continue
- }
- }
-}
-
-func TestMatch(t *testing.T) {
- for _, spec := range []struct {
- ops []int
- pool []string
- verb string
-
- match []string
- notMatch []string
- }{
- {
- match: []string{""},
- notMatch: []string{"example"},
- },
- {
- ops: []int{int(utilities.OpNop), anything},
- match: []string{""},
- notMatch: []string{"example", "path/to/example"},
- },
- {
- ops: []int{int(utilities.OpPush), anything},
- match: []string{"abc", "def"},
- notMatch: []string{"", "abc/def"},
- },
- {
- ops: []int{int(utilities.OpLitPush), 0},
- pool: []string{"v1"},
- match: []string{"v1"},
- notMatch: []string{"", "v2"},
- },
- {
- ops: []int{int(utilities.OpPushM), anything},
- match: []string{"", "abc", "abc/def", "abc/def/ghi"},
- },
- {
- ops: []int{
- int(utilities.OpPushM), anything,
- int(utilities.OpLitPush), 0,
- },
- pool: []string{"tail"},
- match: []string{"tail", "abc/tail", "abc/def/tail"},
- notMatch: []string{
- "", "abc", "abc/def",
- "tail/extra", "abc/tail/extra", "abc/def/tail/extra",
- },
- },
- {
- ops: []int{
- int(utilities.OpLitPush), 0,
- int(utilities.OpLitPush), 1,
- int(utilities.OpPush), anything,
- int(utilities.OpConcatN), 1,
- int(utilities.OpCapture), 2,
- },
- pool: []string{"v1", "bucket", "name"},
- match: []string{"v1/bucket/my-bucket", "v1/bucket/our-bucket"},
- notMatch: []string{
- "",
- "v1",
- "v1/bucket",
- "v2/bucket/my-bucket",
- "v1/pubsub/my-topic",
- },
- },
- {
- ops: []int{
- int(utilities.OpLitPush), 0,
- int(utilities.OpLitPush), 1,
- int(utilities.OpPushM), anything,
- int(utilities.OpConcatN), 2,
- int(utilities.OpCapture), 2,
- },
- pool: []string{"v1", "o", "name"},
- match: []string{
- "v1/o",
- "v1/o/my-bucket",
- "v1/o/our-bucket",
- "v1/o/my-bucket/dir",
- "v1/o/my-bucket/dir/dir2",
- "v1/o/my-bucket/dir/dir2/obj",
- },
- notMatch: []string{
- "",
- "v1",
- "v2/o/my-bucket",
- "v1/b/my-bucket",
- },
- },
- {
- ops: []int{
- int(utilities.OpLitPush), 0,
- int(utilities.OpLitPush), 1,
- int(utilities.OpPush), anything,
- int(utilities.OpConcatN), 2,
- int(utilities.OpCapture), 2,
- int(utilities.OpLitPush), 3,
- int(utilities.OpPush), anything,
- int(utilities.OpConcatN), 1,
- int(utilities.OpCapture), 4,
- },
- pool: []string{"v2", "b", "name", "o", "oname"},
- match: []string{
- "v2/b/my-bucket/o/obj",
- "v2/b/our-bucket/o/obj",
- "v2/b/my-bucket/o/dir",
- },
- notMatch: []string{
- "",
- "v2",
- "v2/b",
- "v2/b/my-bucket",
- "v2/b/my-bucket/o",
- },
- },
- {
- ops: []int{int(utilities.OpLitPush), 0},
- pool: []string{"v1"},
- verb: "LOCK",
- match: []string{"v1:LOCK"},
- notMatch: []string{"v1", "LOCK"},
- },
- } {
- pat, err := NewPattern(validVersion, spec.ops, spec.pool, spec.verb)
- if err != nil {
- t.Errorf("NewPattern(%d, %v, %q, %q) failed with %v; want success", validVersion, spec.ops, spec.pool, spec.verb, err)
- continue
- }
-
- for _, path := range spec.match {
- _, err = pat.Match(segments(path))
- if err != nil {
- t.Errorf("pat.Match(%q) failed with %v; want success; pattern = (%v, %q)", path, err, spec.ops, spec.pool)
- }
- }
-
- for _, path := range spec.notMatch {
- _, err = pat.Match(segments(path))
- if err == nil {
- t.Errorf("pat.Match(%q) succeeded; want failure with %v; pattern = (%v, %q)", path, ErrNotMatch, spec.ops, spec.pool)
- continue
- }
- if err != ErrNotMatch {
- t.Errorf("pat.Match(%q) failed with %v; want failure with %v; pattern = (%v, %q)", spec.notMatch, err, ErrNotMatch, spec.ops, spec.pool)
- }
- }
- }
-}
-
-func TestMatchWithBinding(t *testing.T) {
- for _, spec := range []struct {
- ops []int
- pool []string
- path string
- verb string
-
- want map[string]string
- }{
- {
- want: make(map[string]string),
- },
- {
- ops: []int{int(utilities.OpNop), anything},
- want: make(map[string]string),
- },
- {
- ops: []int{int(utilities.OpPush), anything},
- path: "abc",
- want: make(map[string]string),
- },
- {
- ops: []int{int(utilities.OpPush), anything},
- verb: "LOCK",
- path: "abc:LOCK",
- want: make(map[string]string),
- },
- {
- ops: []int{int(utilities.OpLitPush), 0},
- pool: []string{"endpoint"},
- path: "endpoint",
- want: make(map[string]string),
- },
- {
- ops: []int{int(utilities.OpPushM), anything},
- path: "abc/def/ghi",
- want: make(map[string]string),
- },
- {
- ops: []int{
- int(utilities.OpLitPush), 0,
- int(utilities.OpLitPush), 1,
- int(utilities.OpPush), anything,
- int(utilities.OpConcatN), 1,
- int(utilities.OpCapture), 2,
- },
- pool: []string{"v1", "bucket", "name"},
- path: "v1/bucket/my-bucket",
- want: map[string]string{
- "name": "my-bucket",
- },
- },
- {
- ops: []int{
- int(utilities.OpLitPush), 0,
- int(utilities.OpLitPush), 1,
- int(utilities.OpPush), anything,
- int(utilities.OpConcatN), 1,
- int(utilities.OpCapture), 2,
- },
- pool: []string{"v1", "bucket", "name"},
- verb: "LOCK",
- path: "v1/bucket/my-bucket:LOCK",
- want: map[string]string{
- "name": "my-bucket",
- },
- },
- {
- ops: []int{
- int(utilities.OpLitPush), 0,
- int(utilities.OpLitPush), 1,
- int(utilities.OpPushM), anything,
- int(utilities.OpConcatN), 2,
- int(utilities.OpCapture), 2,
- },
- pool: []string{"v1", "o", "name"},
- path: "v1/o/my-bucket/dir/dir2/obj",
- want: map[string]string{
- "name": "o/my-bucket/dir/dir2/obj",
- },
- },
- {
- ops: []int{
- int(utilities.OpLitPush), 0,
- int(utilities.OpLitPush), 1,
- int(utilities.OpPushM), anything,
- int(utilities.OpLitPush), 2,
- int(utilities.OpConcatN), 3,
- int(utilities.OpCapture), 4,
- int(utilities.OpLitPush), 3,
- },
- pool: []string{"v1", "o", ".ext", "tail", "name"},
- path: "v1/o/my-bucket/dir/dir2/obj/.ext/tail",
- want: map[string]string{
- "name": "o/my-bucket/dir/dir2/obj/.ext",
- },
- },
- {
- ops: []int{
- int(utilities.OpLitPush), 0,
- int(utilities.OpLitPush), 1,
- int(utilities.OpPush), anything,
- int(utilities.OpConcatN), 2,
- int(utilities.OpCapture), 2,
- int(utilities.OpLitPush), 3,
- int(utilities.OpPush), anything,
- int(utilities.OpConcatN), 1,
- int(utilities.OpCapture), 4,
- },
- pool: []string{"v2", "b", "name", "o", "oname"},
- path: "v2/b/my-bucket/o/obj",
- want: map[string]string{
- "name": "b/my-bucket",
- "oname": "obj",
- },
- },
- } {
- pat, err := NewPattern(validVersion, spec.ops, spec.pool, spec.verb)
- if err != nil {
- t.Errorf("NewPattern(%d, %v, %q, %q) failed with %v; want success", validVersion, spec.ops, spec.pool, spec.verb, err)
- continue
- }
-
- got, err := pat.Match(segments(spec.path))
- if err != nil {
- t.Errorf("pat.Match(%q) failed with %v; want success; pattern = (%v, %q)", spec.path, err, spec.ops, spec.pool)
- }
- if !reflect.DeepEqual(got, spec.want) {
- t.Errorf("pat.Match(%q) = %q; want %q; pattern = (%v, %q)", spec.path, got, spec.want, spec.ops, spec.pool)
- }
- }
-}
-
-func segments(path string) (components []string, verb string) {
- if path == "" {
- return nil, ""
- }
- components = strings.Split(path, "/")
- l := len(components)
- c := components[l-1]
- if idx := strings.LastIndex(c, ":"); idx >= 0 {
- components[l-1], verb = c[:idx], c[idx+1:]
- }
- return components, verb
-}
-
-func TestPatternString(t *testing.T) {
- for _, spec := range []struct {
- ops []int
- pool []string
-
- want string
- }{
- {
- want: "/",
- },
- {
- ops: []int{int(utilities.OpNop), anything},
- want: "/",
- },
- {
- ops: []int{int(utilities.OpPush), anything},
- want: "/*",
- },
- {
- ops: []int{int(utilities.OpLitPush), 0},
- pool: []string{"endpoint"},
- want: "/endpoint",
- },
- {
- ops: []int{int(utilities.OpPushM), anything},
- want: "/**",
- },
- {
- ops: []int{
- int(utilities.OpPush), anything,
- int(utilities.OpConcatN), 1,
- },
- want: "/*",
- },
- {
- ops: []int{
- int(utilities.OpPush), anything,
- int(utilities.OpConcatN), 1,
- int(utilities.OpCapture), 0,
- },
- pool: []string{"name"},
- want: "/{name=*}",
- },
- {
- ops: []int{
- int(utilities.OpLitPush), 0,
- int(utilities.OpLitPush), 1,
- int(utilities.OpPush), anything,
- int(utilities.OpConcatN), 2,
- int(utilities.OpCapture), 2,
- int(utilities.OpLitPush), 3,
- int(utilities.OpPushM), anything,
- int(utilities.OpLitPush), 4,
- int(utilities.OpConcatN), 3,
- int(utilities.OpCapture), 6,
- int(utilities.OpLitPush), 5,
- },
- pool: []string{"v1", "buckets", "bucket_name", "objects", ".ext", "tail", "name"},
- want: "/v1/{bucket_name=buckets/*}/{name=objects/**/.ext}/tail",
- },
- } {
- p, err := NewPattern(validVersion, spec.ops, spec.pool, "")
- if err != nil {
- t.Errorf("NewPattern(%d, %v, %q, %q) failed with %v; want success", validVersion, spec.ops, spec.pool, "", err)
- continue
- }
- if got, want := p.String(), spec.want; got != want {
- t.Errorf("%#v.String() = %q; want %q", p, got, want)
- }
-
- verb := "LOCK"
- p, err = NewPattern(validVersion, spec.ops, spec.pool, verb)
- if err != nil {
- t.Errorf("NewPattern(%d, %v, %q, %q) failed with %v; want success", validVersion, spec.ops, spec.pool, verb, err)
- continue
- }
- if got, want := p.String(), fmt.Sprintf("%s:%s", spec.want, verb); got != want {
- t.Errorf("%#v.String() = %q; want %q", p, got, want)
- }
- }
-}
diff --git a/gateway/runtime/proto2_convert.go b/gateway/runtime/proto2_convert.go
deleted file mode 100644
index a3151e2..0000000
--- a/gateway/runtime/proto2_convert.go
+++ /dev/null
@@ -1,80 +0,0 @@
-package runtime
-
-import (
- "github.com/golang/protobuf/proto"
-)
-
-// StringP returns a pointer to a string whose pointee is same as the given string value.
-func StringP(val string) (*string, error) {
- return proto.String(val), nil
-}
-
-// BoolP parses the given string representation of a boolean value,
-// and returns a pointer to a bool whose value is same as the parsed value.
-func BoolP(val string) (*bool, error) {
- b, err := Bool(val)
- if err != nil {
- return nil, err
- }
- return proto.Bool(b), nil
-}
-
-// Float64P parses the given string representation of a floating point number,
-// and returns a pointer to a float64 whose value is same as the parsed number.
-func Float64P(val string) (*float64, error) {
- f, err := Float64(val)
- if err != nil {
- return nil, err
- }
- return proto.Float64(f), nil
-}
-
-// Float32P parses the given string representation of a floating point number,
-// and returns a pointer to a float32 whose value is same as the parsed number.
-func Float32P(val string) (*float32, error) {
- f, err := Float32(val)
- if err != nil {
- return nil, err
- }
- return proto.Float32(f), nil
-}
-
-// Int64P parses the given string representation of an integer
-// and returns a pointer to a int64 whose value is same as the parsed integer.
-func Int64P(val string) (*int64, error) {
- i, err := Int64(val)
- if err != nil {
- return nil, err
- }
- return proto.Int64(i), nil
-}
-
-// Int32P parses the given string representation of an integer
-// and returns a pointer to a int32 whose value is same as the parsed integer.
-func Int32P(val string) (*int32, error) {
- i, err := Int32(val)
- if err != nil {
- return nil, err
- }
- return proto.Int32(i), err
-}
-
-// Uint64P parses the given string representation of an integer
-// and returns a pointer to a uint64 whose value is same as the parsed integer.
-func Uint64P(val string) (*uint64, error) {
- i, err := Uint64(val)
- if err != nil {
- return nil, err
- }
- return proto.Uint64(i), err
-}
-
-// Uint32P parses the given string representation of an integer
-// and returns a pointer to a uint32 whose value is same as the parsed integer.
-func Uint32P(val string) (*uint32, error) {
- i, err := Uint32(val)
- if err != nil {
- return nil, err
- }
- return proto.Uint32(i), err
-}
diff --git a/gateway/runtime/proto_errors.go b/gateway/runtime/proto_errors.go
deleted file mode 100644
index ca76324..0000000
--- a/gateway/runtime/proto_errors.go
+++ /dev/null
@@ -1,106 +0,0 @@
-package runtime
-
-import (
- "context"
- "io"
- "net/http"
-
- "github.com/golang/protobuf/ptypes/any"
- "github.com/grpc-ecosystem/grpc-gateway/internal"
- "google.golang.org/grpc/codes"
- "google.golang.org/grpc/grpclog"
- "google.golang.org/grpc/status"
-)
-
-// StreamErrorHandlerFunc accepts an error as a gRPC error generated via status package and translates it into a
-// a proto struct used to represent error at the end of a stream.
-type StreamErrorHandlerFunc func(context.Context, error) *StreamError
-
-// StreamError is the payload for the final message in a server stream in the event that the server returns an
-// error after a response message has already been sent.
-type StreamError internal.StreamError
-
-// ProtoErrorHandlerFunc handles the error as a gRPC error generated via status package and replies to the request.
-type ProtoErrorHandlerFunc func(context.Context, *ServeMux, Marshaler, http.ResponseWriter, *http.Request, error)
-
-var _ ProtoErrorHandlerFunc = DefaultHTTPProtoErrorHandler
-
-// DefaultHTTPProtoErrorHandler is an implementation of HTTPError.
-// If "err" is an error from gRPC system, the function replies with the status code mapped by HTTPStatusFromCode.
-// If otherwise, it replies with http.StatusInternalServerError.
-//
-// The response body returned by this function is a Status message marshaled by a Marshaler.
-//
-// Do not set this function to HTTPError variable directly, use WithProtoErrorHandler option instead.
-func DefaultHTTPProtoErrorHandler(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, _ *http.Request, err error) {
- // return Internal when Marshal failed
- const fallback = `{"code": 13, "message": "failed to marshal error message"}`
-
- s, ok := status.FromError(err)
- if !ok {
- s = status.New(codes.Unknown, err.Error())
- }
-
- w.Header().Del("Trailer")
-
- contentType := marshaler.ContentType()
- // Check marshaler on run time in order to keep backwards compatability
- // An interface param needs to be added to the ContentType() function on
- // the Marshal interface to be able to remove this check
- if httpBodyMarshaler, ok := marshaler.(*HTTPBodyMarshaler); ok {
- pb := s.Proto()
- contentType = httpBodyMarshaler.ContentTypeFromMessage(pb)
- }
- w.Header().Set("Content-Type", contentType)
-
- buf, merr := marshaler.Marshal(s.Proto())
- if merr != nil {
- grpclog.Infof("Failed to marshal error message %q: %v", s.Proto(), merr)
- w.WriteHeader(http.StatusInternalServerError)
- if _, err := io.WriteString(w, fallback); err != nil {
- grpclog.Infof("Failed to write response: %v", err)
- }
- return
- }
-
- md, ok := ServerMetadataFromContext(ctx)
- if !ok {
- grpclog.Infof("Failed to extract ServerMetadata from context")
- }
-
- handleForwardResponseServerMetadata(w, mux, md)
- handleForwardResponseTrailerHeader(w, md)
- st := HTTPStatusFromCode(s.Code())
- w.WriteHeader(st)
- if _, err := w.Write(buf); err != nil {
- grpclog.Infof("Failed to write response: %v", err)
- }
-
- handleForwardResponseTrailer(w, md)
-}
-
-// DefaultHTTPStreamErrorHandler converts the given err into a *StreamError via
-// default logic.
-//
-// It extracts the gRPC status from err if possible. The fields of the status are
-// used to populate the returned StreamError, and the HTTP status code is derived
-// from the gRPC code via HTTPStatusFromCode. If the given err does not contain a
-// gRPC status, an "Unknown" gRPC code is used and "Internal Server Error" HTTP code.
-func DefaultHTTPStreamErrorHandler(_ context.Context, err error) *StreamError {
- grpcCode := codes.Unknown
- grpcMessage := err.Error()
- var grpcDetails []*any.Any
- if s, ok := status.FromError(err); ok {
- grpcCode = s.Code()
- grpcMessage = s.Message()
- grpcDetails = s.Proto().GetDetails()
- }
- httpCode := HTTPStatusFromCode(grpcCode)
- return &StreamError{
- GrpcCode: int32(grpcCode),
- HttpCode: int32(httpCode),
- Message: grpcMessage,
- HttpStatus: http.StatusText(httpCode),
- Details: grpcDetails,
- }
-}
diff --git a/gateway/runtime/query.go b/gateway/runtime/query.go
index ee0207e..fb0c84e 100644
--- a/gateway/runtime/query.go
+++ b/gateway/runtime/query.go
@@ -2,24 +2,45 @@ package runtime
import (
"encoding/base64"
+ "errors"
"fmt"
"net/url"
- "reflect"
"regexp"
"strconv"
"strings"
"time"
- "github.com/golang/protobuf/proto"
- "github.com/grpc-ecosystem/grpc-gateway/utilities"
+ "github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
+ "google.golang.org/genproto/protobuf/field_mask"
"google.golang.org/grpc/grpclog"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/reflect/protoreflect"
+ "google.golang.org/protobuf/reflect/protoregistry"
+ "google.golang.org/protobuf/types/known/durationpb"
+ "google.golang.org/protobuf/types/known/timestamppb"
+ "google.golang.org/protobuf/types/known/wrapperspb"
)
-var valuesKeyRegexp = regexp.MustCompile("^(.*)\\[(.*)\\]$")
+var valuesKeyRegexp = regexp.MustCompile(`^(.*)\[(.*)\]$`)
-// PopulateQueryParameters populates "values" into "msg".
-// A value is ignored if its key starts with one of the elements in "filter".
+var currentQueryParser QueryParameterParser = &defaultQueryParser{}
+
+// QueryParameterParser defines interface for all query parameter parsers
+type QueryParameterParser interface {
+ Parse(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error
+}
+
+// PopulateQueryParameters parses query parameters
+// into "msg" using current query parser
func PopulateQueryParameters(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error {
+ return currentQueryParser.Parse(msg, values, filter)
+}
+
+type defaultQueryParser struct{}
+
+// Parse populates "values" into "msg".
+// A value is ignored if its key starts with one of the elements in "filter".
+func (*defaultQueryParser) Parse(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error {
for key, values := range values {
match := valuesKeyRegexp.FindStringSubmatch(key)
if len(match) == 3 {
@@ -30,7 +51,7 @@ func PopulateQueryParameters(msg proto.Message, values url.Values, filter *utili
if filter.HasCommonPrefix(fieldPath) {
continue
}
- if err := populateFieldValueFromPath(msg, fieldPath, values); err != nil {
+ if err := populateFieldValueFromPath(msg.ProtoReflect(), fieldPath, values); err != nil {
return err
}
}
@@ -38,352 +59,271 @@ func PopulateQueryParameters(msg proto.Message, values url.Values, filter *utili
}
// PopulateFieldFromPath sets a value in a nested Protobuf structure.
-// It instantiates missing protobuf fields as it goes.
func PopulateFieldFromPath(msg proto.Message, fieldPathString string, value string) error {
fieldPath := strings.Split(fieldPathString, ".")
- return populateFieldValueFromPath(msg, fieldPath, []string{value})
+ return populateFieldValueFromPath(msg.ProtoReflect(), fieldPath, []string{value})
}
-func populateFieldValueFromPath(msg proto.Message, fieldPath []string, values []string) error {
- m := reflect.ValueOf(msg)
- if m.Kind() != reflect.Ptr {
- return fmt.Errorf("unexpected type %T: %v", msg, msg)
+func populateFieldValueFromPath(msgValue protoreflect.Message, fieldPath []string, values []string) error {
+ if len(fieldPath) < 1 {
+ return errors.New("no field path")
+ }
+ if len(values) < 1 {
+ return errors.New("no value provided")
}
- var props *proto.Properties
- m = m.Elem()
+
+ var fieldDescriptor protoreflect.FieldDescriptor
for i, fieldName := range fieldPath {
- isLast := i == len(fieldPath)-1
- if !isLast && m.Kind() != reflect.Struct {
- return fmt.Errorf("non-aggregate type in the mid of path: %s", strings.Join(fieldPath, "."))
- }
- var f reflect.Value
- var err error
- f, props, err = fieldByProtoName(m, fieldName)
- if err != nil {
- return err
- } else if !f.IsValid() {
- grpclog.Infof("field not found in %T: %s", msg, strings.Join(fieldPath, "."))
- return nil
- }
+ fields := msgValue.Descriptor().Fields()
- switch f.Kind() {
- case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, reflect.String, reflect.Uint32, reflect.Uint64:
- if !isLast {
- return fmt.Errorf("unexpected nested field %s in %s", fieldPath[i+1], strings.Join(fieldPath[:i+1], "."))
+ // Get field by name
+ fieldDescriptor = fields.ByName(protoreflect.Name(fieldName))
+ if fieldDescriptor == nil {
+ fieldDescriptor = fields.ByJSONName(fieldName)
+ if fieldDescriptor == nil {
+ // We're not returning an error here because this could just be
+ // an extra query parameter that isn't part of the request.
+ grpclog.Infof("field not found in %q: %q", msgValue.Descriptor().FullName(), strings.Join(fieldPath, "."))
+ return nil
}
- m = f
- case reflect.Slice:
- if !isLast {
- return fmt.Errorf("unexpected repeated field in %s", strings.Join(fieldPath, "."))
- }
- // Handle []byte
- if f.Type().Elem().Kind() == reflect.Uint8 {
- m = f
- break
- }
- return populateRepeatedField(f, values, props)
- case reflect.Ptr:
- if f.IsNil() {
- m = reflect.New(f.Type().Elem())
- f.Set(m.Convert(f.Type()))
- }
- m = f.Elem()
- continue
- case reflect.Struct:
- m = f
- continue
- case reflect.Map:
- if !isLast {
- return fmt.Errorf("unexpected nested field %s in %s", fieldPath[i+1], strings.Join(fieldPath[:i+1], "."))
- }
- return populateMapField(f, values, props)
- default:
- return fmt.Errorf("unexpected type %s in %T", f.Type(), msg)
}
- }
- switch len(values) {
- case 0:
- return fmt.Errorf("no value of field: %s", strings.Join(fieldPath, "."))
- case 1:
- default:
- grpclog.Infof("too many field values: %s", strings.Join(fieldPath, "."))
- }
- return populateField(m, values[0], props)
-}
-// fieldByProtoName looks up a field whose corresponding protobuf field name is "name".
-// "m" must be a struct value. It returns zero reflect.Value if no such field found.
-func fieldByProtoName(m reflect.Value, name string) (reflect.Value, *proto.Properties, error) {
- props := proto.GetProperties(m.Type())
+ // If this is the last element, we're done
+ if i == len(fieldPath)-1 {
+ break
+ }
- // look up field name in oneof map
- if op, ok := props.OneofTypes[name]; ok {
- v := reflect.New(op.Type.Elem())
- field := m.Field(op.Field)
- if !field.IsNil() {
- return reflect.Value{}, nil, fmt.Errorf("field already set for %s oneof", props.Prop[op.Field].OrigName)
+ // Only singular message fields are allowed
+ if fieldDescriptor.Message() == nil || fieldDescriptor.Cardinality() == protoreflect.Repeated {
+ return fmt.Errorf("invalid path: %q is not a message", fieldName)
}
- field.Set(v)
- return v.Elem().Field(0), op.Prop, nil
+
+ // Get the nested message
+ msgValue = msgValue.Mutable(fieldDescriptor).Message()
}
- for _, p := range props.Prop {
- if p.OrigName == name {
- return m.FieldByName(p.Name), p, nil
- }
- if p.JSONName == name {
- return m.FieldByName(p.Name), p, nil
+ // Check if oneof already set
+ if of := fieldDescriptor.ContainingOneof(); of != nil {
+ if f := msgValue.WhichOneof(of); f != nil {
+ return fmt.Errorf("field already set for oneof %q", of.FullName().Name())
}
}
- return reflect.Value{}, nil, nil
-}
-func populateMapField(f reflect.Value, values []string, props *proto.Properties) error {
- if len(values) != 2 {
- return fmt.Errorf("more than one value provided for key %s in map %s", values[0], props.Name)
+ switch {
+ case fieldDescriptor.IsList():
+ return populateRepeatedField(fieldDescriptor, msgValue.Mutable(fieldDescriptor).List(), values)
+ case fieldDescriptor.IsMap():
+ return populateMapField(fieldDescriptor, msgValue.Mutable(fieldDescriptor).Map(), values)
}
- key, value := values[0], values[1]
- keyType := f.Type().Key()
- valueType := f.Type().Elem()
- if f.IsNil() {
- f.Set(reflect.MakeMap(f.Type()))
+ if len(values) > 1 {
+ return fmt.Errorf("too many values for field %q: %s", fieldDescriptor.FullName().Name(), strings.Join(values, ", "))
}
- keyConv, ok := convFromType[keyType.Kind()]
- if !ok {
- return fmt.Errorf("unsupported key type %s in map %s", keyType, props.Name)
- }
- valueConv, ok := convFromType[valueType.Kind()]
- if !ok {
- return fmt.Errorf("unsupported value type %s in map %s", valueType, props.Name)
- }
+ return populateField(fieldDescriptor, msgValue, values[0])
+}
- keyV := keyConv.Call([]reflect.Value{reflect.ValueOf(key)})
- if err := keyV[1].Interface(); err != nil {
- return err.(error)
- }
- valueV := valueConv.Call([]reflect.Value{reflect.ValueOf(value)})
- if err := valueV[1].Interface(); err != nil {
- return err.(error)
+func populateField(fieldDescriptor protoreflect.FieldDescriptor, msgValue protoreflect.Message, value string) error {
+ v, err := parseField(fieldDescriptor, value)
+ if err != nil {
+ return fmt.Errorf("parsing field %q: %w", fieldDescriptor.FullName().Name(), err)
}
- f.SetMapIndex(keyV[0].Convert(keyType), valueV[0].Convert(valueType))
-
+ msgValue.Set(fieldDescriptor, v)
return nil
}
-func populateRepeatedField(f reflect.Value, values []string, props *proto.Properties) error {
- elemType := f.Type().Elem()
+func populateRepeatedField(fieldDescriptor protoreflect.FieldDescriptor, list protoreflect.List, values []string) error {
+ for _, value := range values {
+ v, err := parseField(fieldDescriptor, value)
+ if err != nil {
+ return fmt.Errorf("parsing list %q: %w", fieldDescriptor.FullName().Name(), err)
+ }
+ list.Append(v)
+ }
+
+ return nil
+}
- // is the destination field a slice of an enumeration type?
- if enumValMap := proto.EnumValueMap(props.Enum); enumValMap != nil {
- return populateFieldEnumRepeated(f, values, enumValMap)
+func populateMapField(fieldDescriptor protoreflect.FieldDescriptor, mp protoreflect.Map, values []string) error {
+ if len(values) != 2 {
+ return fmt.Errorf("more than one value provided for key %q in map %q", values[0], fieldDescriptor.FullName())
}
- conv, ok := convFromType[elemType.Kind()]
- if !ok {
- return fmt.Errorf("unsupported field type %s", elemType)
+ key, err := parseField(fieldDescriptor.MapKey(), values[0])
+ if err != nil {
+ return fmt.Errorf("parsing map key %q: %w", fieldDescriptor.FullName().Name(), err)
}
- f.Set(reflect.MakeSlice(f.Type(), len(values), len(values)).Convert(f.Type()))
- for i, v := range values {
- result := conv.Call([]reflect.Value{reflect.ValueOf(v)})
- if err := result[1].Interface(); err != nil {
- return err.(error)
- }
- f.Index(i).Set(result[0].Convert(f.Index(i).Type()))
+
+ value, err := parseField(fieldDescriptor.MapValue(), values[1])
+ if err != nil {
+ return fmt.Errorf("parsing map value %q: %w", fieldDescriptor.FullName().Name(), err)
}
+
+ mp.Set(key.MapKey(), value)
+
return nil
}
-func populateField(f reflect.Value, value string, props *proto.Properties) error {
- i := f.Addr().Interface()
-
- // Handle protobuf well known types
- var name string
- switch m := i.(type) {
- case interface{ XXX_WellKnownType() string }:
- name = m.XXX_WellKnownType()
- case proto.Message:
- const wktPrefix = "google.protobuf."
- if fullName := proto.MessageName(m); strings.HasPrefix(fullName, wktPrefix) {
- name = fullName[len(wktPrefix):]
+func parseField(fieldDescriptor protoreflect.FieldDescriptor, value string) (protoreflect.Value, error) {
+ switch fieldDescriptor.Kind() {
+ case protoreflect.BoolKind:
+ v, err := strconv.ParseBool(value)
+ if err != nil {
+ return protoreflect.Value{}, err
+ }
+ return protoreflect.ValueOfBool(v), nil
+ case protoreflect.EnumKind:
+ enum, err := protoregistry.GlobalTypes.FindEnumByName(fieldDescriptor.Enum().FullName())
+ switch {
+ case errors.Is(err, protoregistry.NotFound):
+ return protoreflect.Value{}, fmt.Errorf("enum %q is not registered", fieldDescriptor.Enum().FullName())
+ case err != nil:
+ return protoreflect.Value{}, fmt.Errorf("failed to look up enum: %w", err)
+ }
+ // Look for enum by name
+ v := enum.Descriptor().Values().ByName(protoreflect.Name(value))
+ if v == nil {
+ i, err := strconv.Atoi(value)
+ if err != nil {
+ return protoreflect.Value{}, fmt.Errorf("%q is not a valid value", value)
+ }
+ // Look for enum by number
+ v = enum.Descriptor().Values().ByNumber(protoreflect.EnumNumber(i))
+ if v == nil {
+ return protoreflect.Value{}, fmt.Errorf("%q is not a valid value", value)
+ }
}
+ return protoreflect.ValueOfEnum(v.Number()), nil
+ case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
+ v, err := strconv.ParseInt(value, 10, 32)
+ if err != nil {
+ return protoreflect.Value{}, err
+ }
+ return protoreflect.ValueOfInt32(int32(v)), nil
+ case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
+ v, err := strconv.ParseInt(value, 10, 64)
+ if err != nil {
+ return protoreflect.Value{}, err
+ }
+ return protoreflect.ValueOfInt64(v), nil
+ case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
+ v, err := strconv.ParseUint(value, 10, 32)
+ if err != nil {
+ return protoreflect.Value{}, err
+ }
+ return protoreflect.ValueOfUint32(uint32(v)), nil
+ case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
+ v, err := strconv.ParseUint(value, 10, 64)
+ if err != nil {
+ return protoreflect.Value{}, err
+ }
+ return protoreflect.ValueOfUint64(v), nil
+ case protoreflect.FloatKind:
+ v, err := strconv.ParseFloat(value, 32)
+ if err != nil {
+ return protoreflect.Value{}, err
+ }
+ return protoreflect.ValueOfFloat32(float32(v)), nil
+ case protoreflect.DoubleKind:
+ v, err := strconv.ParseFloat(value, 64)
+ if err != nil {
+ return protoreflect.Value{}, err
+ }
+ return protoreflect.ValueOfFloat64(v), nil
+ case protoreflect.StringKind:
+ return protoreflect.ValueOfString(value), nil
+ case protoreflect.BytesKind:
+ v, err := base64.URLEncoding.DecodeString(value)
+ if err != nil {
+ return protoreflect.Value{}, err
+ }
+ return protoreflect.ValueOfBytes(v), nil
+ case protoreflect.MessageKind, protoreflect.GroupKind:
+ return parseMessage(fieldDescriptor.Message(), value)
+ default:
+ panic(fmt.Sprintf("unknown field kind: %v", fieldDescriptor.Kind()))
}
- switch name {
- case "Timestamp":
+}
+
+func parseMessage(msgDescriptor protoreflect.MessageDescriptor, value string) (protoreflect.Value, error) {
+ var msg proto.Message
+ switch msgDescriptor.FullName() {
+ case "google.protobuf.Timestamp":
if value == "null" {
- f.FieldByName("Seconds").SetInt(0)
- f.FieldByName("Nanos").SetInt(0)
- return nil
+ break
}
-
t, err := time.Parse(time.RFC3339Nano, value)
if err != nil {
- return fmt.Errorf("bad Timestamp: %v", err)
+ return protoreflect.Value{}, err
}
- f.FieldByName("Seconds").SetInt(int64(t.Unix()))
- f.FieldByName("Nanos").SetInt(int64(t.Nanosecond()))
- return nil
- case "Duration":
+ msg = timestamppb.New(t)
+ case "google.protobuf.Duration":
if value == "null" {
- f.FieldByName("Seconds").SetInt(0)
- f.FieldByName("Nanos").SetInt(0)
- return nil
+ break
}
d, err := time.ParseDuration(value)
if err != nil {
- return fmt.Errorf("bad Duration: %v", err)
+ return protoreflect.Value{}, err
}
-
- ns := d.Nanoseconds()
- s := ns / 1e9
- ns %= 1e9
- f.FieldByName("Seconds").SetInt(s)
- f.FieldByName("Nanos").SetInt(ns)
- return nil
- case "DoubleValue":
- fallthrough
- case "FloatValue":
- float64Val, err := strconv.ParseFloat(value, 64)
+ msg = durationpb.New(d)
+ case "google.protobuf.DoubleValue":
+ v, err := strconv.ParseFloat(value, 64)
if err != nil {
- return fmt.Errorf("bad DoubleValue: %s", value)
+ return protoreflect.Value{}, err
}
- f.FieldByName("Value").SetFloat(float64Val)
- return nil
- case "Int64Value":
- fallthrough
- case "Int32Value":
- int64Val, err := strconv.ParseInt(value, 10, 64)
+ msg = &wrapperspb.DoubleValue{Value: v}
+ case "google.protobuf.FloatValue":
+ v, err := strconv.ParseFloat(value, 32)
if err != nil {
- return fmt.Errorf("bad DoubleValue: %s", value)
+ return protoreflect.Value{}, err
}
- f.FieldByName("Value").SetInt(int64Val)
- return nil
- case "UInt64Value":
- fallthrough
- case "UInt32Value":
- uint64Val, err := strconv.ParseUint(value, 10, 64)
+ msg = &wrapperspb.FloatValue{Value: float32(v)}
+ case "google.protobuf.Int64Value":
+ v, err := strconv.ParseInt(value, 10, 64)
if err != nil {
- return fmt.Errorf("bad DoubleValue: %s", value)
- }
- f.FieldByName("Value").SetUint(uint64Val)
- return nil
- case "BoolValue":
- if value == "true" {
- f.FieldByName("Value").SetBool(true)
- } else if value == "false" {
- f.FieldByName("Value").SetBool(false)
- } else {
- return fmt.Errorf("bad BoolValue: %s", value)
+ return protoreflect.Value{}, err
}
- return nil
- case "StringValue":
- f.FieldByName("Value").SetString(value)
- return nil
- case "BytesValue":
- bytesVal, err := base64.StdEncoding.DecodeString(value)
+ msg = &wrapperspb.Int64Value{Value: v}
+ case "google.protobuf.Int32Value":
+ v, err := strconv.ParseInt(value, 10, 32)
if err != nil {
- return fmt.Errorf("bad BytesValue: %s", value)
+ return protoreflect.Value{}, err
}
- f.FieldByName("Value").SetBytes(bytesVal)
- return nil
- case "FieldMask":
- p := f.FieldByName("Paths")
- for _, v := range strings.Split(value, ",") {
- if v != "" {
- p.Set(reflect.Append(p, reflect.ValueOf(v)))
- }
- }
- return nil
- }
-
- // Handle Time and Duration stdlib types
- switch t := i.(type) {
- case *time.Time:
- pt, err := time.Parse(time.RFC3339Nano, value)
+ msg = &wrapperspb.Int32Value{Value: int32(v)}
+ case "google.protobuf.UInt64Value":
+ v, err := strconv.ParseUint(value, 10, 64)
if err != nil {
- return fmt.Errorf("bad Timestamp: %v", err)
+ return protoreflect.Value{}, err
}
- *t = pt
- return nil
- case *time.Duration:
- d, err := time.ParseDuration(value)
+ msg = &wrapperspb.UInt64Value{Value: v}
+ case "google.protobuf.UInt32Value":
+ v, err := strconv.ParseUint(value, 10, 32)
if err != nil {
- return fmt.Errorf("bad Duration: %v", err)
+ return protoreflect.Value{}, err
}
- *t = d
- return nil
- }
-
- // is the destination field an enumeration type?
- if enumValMap := proto.EnumValueMap(props.Enum); enumValMap != nil {
- return populateFieldEnum(f, value, enumValMap)
- }
-
- conv, ok := convFromType[f.Kind()]
- if !ok {
- return fmt.Errorf("field type %T is not supported in query parameters", i)
- }
- result := conv.Call([]reflect.Value{reflect.ValueOf(value)})
- if err := result[1].Interface(); err != nil {
- return err.(error)
- }
- f.Set(result[0].Convert(f.Type()))
- return nil
-}
-
-func convertEnum(value string, t reflect.Type, enumValMap map[string]int32) (reflect.Value, error) {
- // see if it's an enumeration string
- if enumVal, ok := enumValMap[value]; ok {
- return reflect.ValueOf(enumVal).Convert(t), nil
- }
-
- // check for an integer that matches an enumeration value
- eVal, err := strconv.Atoi(value)
- if err != nil {
- return reflect.Value{}, fmt.Errorf("%s is not a valid %s", value, t)
- }
- for _, v := range enumValMap {
- if v == int32(eVal) {
- return reflect.ValueOf(eVal).Convert(t), nil
+ msg = &wrapperspb.UInt32Value{Value: uint32(v)}
+ case "google.protobuf.BoolValue":
+ v, err := strconv.ParseBool(value)
+ if err != nil {
+ return protoreflect.Value{}, err
}
- }
- return reflect.Value{}, fmt.Errorf("%s is not a valid %s", value, t)
-}
-
-func populateFieldEnum(f reflect.Value, value string, enumValMap map[string]int32) error {
- cval, err := convertEnum(value, f.Type(), enumValMap)
- if err != nil {
- return err
- }
- f.Set(cval)
- return nil
-}
-
-func populateFieldEnumRepeated(f reflect.Value, values []string, enumValMap map[string]int32) error {
- elemType := f.Type().Elem()
- f.Set(reflect.MakeSlice(f.Type(), len(values), len(values)).Convert(f.Type()))
- for i, v := range values {
- result, err := convertEnum(v, elemType, enumValMap)
+ msg = &wrapperspb.BoolValue{Value: v}
+ case "google.protobuf.StringValue":
+ msg = &wrapperspb.StringValue{Value: value}
+ case "google.protobuf.BytesValue":
+ v, err := base64.URLEncoding.DecodeString(value)
if err != nil {
- return err
+ return protoreflect.Value{}, err
}
- f.Index(i).Set(result)
+ msg = &wrapperspb.BytesValue{Value: v}
+ case "google.protobuf.FieldMask":
+ fm := &field_mask.FieldMask{}
+ fm.Paths = append(fm.Paths, strings.Split(value, ",")...)
+ msg = fm
+ default:
+ return protoreflect.Value{}, fmt.Errorf("unsupported message type: %q", string(msgDescriptor.FullName()))
}
- return nil
-}
-var (
- convFromType = map[reflect.Kind]reflect.Value{
- reflect.String: reflect.ValueOf(String),
- reflect.Bool: reflect.ValueOf(Bool),
- reflect.Float64: reflect.ValueOf(Float64),
- reflect.Float32: reflect.ValueOf(Float32),
- reflect.Int64: reflect.ValueOf(Int64),
- reflect.Int32: reflect.ValueOf(Int32),
- reflect.Uint64: reflect.ValueOf(Uint64),
- reflect.Uint32: reflect.ValueOf(Uint32),
- reflect.Slice: reflect.ValueOf(Bytes),
- }
-)
+ return protoreflect.ValueOfMessage(msg.ProtoReflect()), nil
+}
diff --git a/gateway/runtime/query_test.go b/gateway/runtime/query_test.go
deleted file mode 100644
index dff34c8..0000000
--- a/gateway/runtime/query_test.go
+++ /dev/null
@@ -1,923 +0,0 @@
-package runtime_test
-
-import (
- "errors"
- "fmt"
- "net/url"
- "reflect"
- "testing"
- "time"
-
- "github.com/golang/protobuf/proto"
- "github.com/golang/protobuf/ptypes"
- "github.com/golang/protobuf/ptypes/duration"
- "github.com/golang/protobuf/ptypes/timestamp"
- "github.com/golang/protobuf/ptypes/wrappers"
- "github.com/grpc-ecosystem/grpc-gateway/utilities"
- "google.golang.org/genproto/protobuf/field_mask"
-
- "github.com/binchencoder/ease-gateway/gateway/runtime"
-)
-
-func BenchmarkPopulateQueryParameters(b *testing.B) {
- timeT := time.Date(2016, time.December, 15, 12, 23, 32, 49, time.UTC)
- timeStr := timeT.Format(time.RFC3339Nano)
-
- durationT := 13 * time.Hour
- durationStr := durationT.String()
-
- fieldmaskStr := "float_value,double_value"
-
- msg := &proto3Message{}
- values := url.Values{
- "float_value": {"1.5"},
- "double_value": {"2.5"},
- "int64_value": {"-1"},
- "int32_value": {"-2"},
- "uint64_value": {"3"},
- "uint32_value": {"4"},
- "bool_value": {"true"},
- "string_value": {"str"},
- "bytes_value": {"Ynl0ZXM="},
- "repeated_value": {"a", "b", "c"},
- "enum_value": {"1"},
- "repeated_enum": {"1", "2", "0"},
- "timestamp_value": {timeStr},
- "duration_value": {durationStr},
- "fieldmask_value": {fieldmaskStr},
- "wrapper_float_value": {"1.5"},
- "wrapper_double_value": {"2.5"},
- "wrapper_int64_value": {"-1"},
- "wrapper_int32_value": {"-2"},
- "wrapper_u_int64_value": {"3"},
- "wrapper_u_int32_value": {"4"},
- "wrapper_bool_value": {"true"},
- "wrapper_string_value": {"str"},
- "wrapper_bytes_value": {"Ynl0ZXM="},
- "map_value[key]": {"value"},
- "map_value[second]": {"bar"},
- "map_value[third]": {"zzz"},
- "map_value[fourth]": {""},
- `map_value[~!@#$%^&*()]`: {"value"},
- "map_value2[key]": {"-2"},
- "map_value3[-2]": {"value"},
- "map_value4[key]": {"-1"},
- "map_value5[-1]": {"value"},
- "map_value6[key]": {"3"},
- "map_value7[3]": {"value"},
- "map_value8[key]": {"4"},
- "map_value9[4]": {"value"},
- "map_value10[key]": {"1.5"},
- "map_value11[1.5]": {"value"},
- "map_value12[key]": {"2.5"},
- "map_value13[2.5]": {"value"},
- "map_value14[key]": {"true"},
- "map_value15[true]": {"value"},
- }
- filter := utilities.NewDoubleArray([][]string{
- {"bool_value"}, {"repeated_value"},
- })
-
- for i := 0; i < b.N; i++ {
- _ = runtime.PopulateQueryParameters(msg, values, filter)
- }
-}
-
-func TestPopulateParameters(t *testing.T) {
- timeT := time.Date(2016, time.December, 15, 12, 23, 32, 49, time.UTC)
- timeStr := timeT.Format(time.RFC3339Nano)
- timePb, err := ptypes.TimestampProto(timeT)
- if err != nil {
- t.Fatalf("Couldn't setup timestamp in Protobuf format: %v", err)
- }
-
- durationT := 13 * time.Hour
- durationStr := durationT.String()
- durationPb := ptypes.DurationProto(durationT)
-
- fieldmaskStr := "float_value,double_value"
- fieldmaskPb := &field_mask.FieldMask{Paths: []string{"float_value", "double_value"}}
-
- for _, spec := range []struct {
- values url.Values
- filter *utilities.DoubleArray
- want proto.Message
- wanterr error
- }{
- {
- values: url.Values{
- "float_value": {"1.5"},
- "double_value": {"2.5"},
- "int64_value": {"-1"},
- "int32_value": {"-2"},
- "uint64_value": {"3"},
- "uint32_value": {"4"},
- "bool_value": {"true"},
- "string_value": {"str"},
- "bytes_value": {"Ynl0ZXM="},
- "repeated_value": {"a", "b", "c"},
- "enum_value": {"1"},
- "repeated_enum": {"1", "2", "0"},
- "timestamp_value": {timeStr},
- "duration_value": {durationStr},
- "fieldmask_value": {fieldmaskStr},
- "wrapper_float_value": {"1.5"},
- "wrapper_double_value": {"2.5"},
- "wrapper_int64_value": {"-1"},
- "wrapper_int32_value": {"-2"},
- "wrapper_u_int64_value": {"3"},
- "wrapper_u_int32_value": {"4"},
- "wrapper_bool_value": {"true"},
- "wrapper_string_value": {"str"},
- "wrapper_bytes_value": {"Ynl0ZXM="},
- "map_value[key]": {"value"},
- "map_value[second]": {"bar"},
- "map_value[third]": {"zzz"},
- "map_value[fourth]": {""},
- `map_value[~!@#$%^&*()]`: {"value"},
- "map_value2[key]": {"-2"},
- "map_value3[-2]": {"value"},
- "map_value4[key]": {"-1"},
- "map_value5[-1]": {"value"},
- "map_value6[key]": {"3"},
- "map_value7[3]": {"value"},
- "map_value8[key]": {"4"},
- "map_value9[4]": {"value"},
- "map_value10[key]": {"1.5"},
- "map_value11[1.5]": {"value"},
- "map_value12[key]": {"2.5"},
- "map_value13[2.5]": {"value"},
- "map_value14[key]": {"true"},
- "map_value15[true]": {"value"},
- },
- filter: utilities.NewDoubleArray(nil),
- want: &proto3Message{
- FloatValue: 1.5,
- DoubleValue: 2.5,
- Int64Value: -1,
- Int32Value: -2,
- Uint64Value: 3,
- Uint32Value: 4,
- BoolValue: true,
- StringValue: "str",
- BytesValue: []byte("bytes"),
- RepeatedValue: []string{"a", "b", "c"},
- EnumValue: EnumValue_Y,
- RepeatedEnum: []EnumValue{EnumValue_Y, EnumValue_Z, EnumValue_X},
- TimestampValue: timePb,
- DurationValue: durationPb,
- FieldMaskValue: fieldmaskPb,
- WrapperFloatValue: &wrappers.FloatValue{Value: 1.5},
- WrapperDoubleValue: &wrappers.DoubleValue{Value: 2.5},
- WrapperInt64Value: &wrappers.Int64Value{Value: -1},
- WrapperInt32Value: &wrappers.Int32Value{Value: -2},
- WrapperUInt64Value: &wrappers.UInt64Value{Value: 3},
- WrapperUInt32Value: &wrappers.UInt32Value{Value: 4},
- WrapperBoolValue: &wrappers.BoolValue{Value: true},
- WrapperStringValue: &wrappers.StringValue{Value: "str"},
- WrapperBytesValue: &wrappers.BytesValue{Value: []byte("bytes")},
- MapValue: map[string]string{
- "key": "value",
- "second": "bar",
- "third": "zzz",
- "fourth": "",
- `~!@#$%^&*()`: "value",
- },
- MapValue2: map[string]int32{"key": -2},
- MapValue3: map[int32]string{-2: "value"},
- MapValue4: map[string]int64{"key": -1},
- MapValue5: map[int64]string{-1: "value"},
- MapValue6: map[string]uint32{"key": 3},
- MapValue7: map[uint32]string{3: "value"},
- MapValue8: map[string]uint64{"key": 4},
- MapValue9: map[uint64]string{4: "value"},
- MapValue10: map[string]float32{"key": 1.5},
- MapValue11: map[float32]string{1.5: "value"},
- MapValue12: map[string]float64{"key": 2.5},
- MapValue13: map[float64]string{2.5: "value"},
- MapValue14: map[string]bool{"key": true},
- MapValue15: map[bool]string{true: "value"},
- },
- },
- {
- values: url.Values{
- "floatValue": {"1.5"},
- "doubleValue": {"2.5"},
- "int64Value": {"-1"},
- "int32Value": {"-2"},
- "uint64Value": {"3"},
- "uint32Value": {"4"},
- "boolValue": {"true"},
- "stringValue": {"str"},
- "bytesValue": {"Ynl0ZXM="},
- "repeatedValue": {"a", "b", "c"},
- "enumValue": {"1"},
- "repeatedEnum": {"1", "2", "0"},
- "timestampValue": {timeStr},
- "durationValue": {durationStr},
- "fieldmaskValue": {fieldmaskStr},
- "wrapperFloatValue": {"1.5"},
- "wrapperDoubleValue": {"2.5"},
- "wrapperInt64Value": {"-1"},
- "wrapperInt32Value": {"-2"},
- "wrapperUInt64Value": {"3"},
- "wrapperUInt32Value": {"4"},
- "wrapperBoolValue": {"true"},
- "wrapperStringValue": {"str"},
- "wrapperBytesValue": {"Ynl0ZXM="},
- },
- filter: utilities.NewDoubleArray(nil),
- want: &proto3Message{
- FloatValue: 1.5,
- DoubleValue: 2.5,
- Int64Value: -1,
- Int32Value: -2,
- Uint64Value: 3,
- Uint32Value: 4,
- BoolValue: true,
- StringValue: "str",
- BytesValue: []byte("bytes"),
- RepeatedValue: []string{"a", "b", "c"},
- EnumValue: EnumValue_Y,
- RepeatedEnum: []EnumValue{EnumValue_Y, EnumValue_Z, EnumValue_X},
- TimestampValue: timePb,
- DurationValue: durationPb,
- FieldMaskValue: fieldmaskPb,
- WrapperFloatValue: &wrappers.FloatValue{Value: 1.5},
- WrapperDoubleValue: &wrappers.DoubleValue{Value: 2.5},
- WrapperInt64Value: &wrappers.Int64Value{Value: -1},
- WrapperInt32Value: &wrappers.Int32Value{Value: -2},
- WrapperUInt64Value: &wrappers.UInt64Value{Value: 3},
- WrapperUInt32Value: &wrappers.UInt32Value{Value: 4},
- WrapperBoolValue: &wrappers.BoolValue{Value: true},
- WrapperStringValue: &wrappers.StringValue{Value: "str"},
- WrapperBytesValue: &wrappers.BytesValue{Value: []byte("bytes")},
- },
- },
- {
- values: url.Values{
- "enum_value": {"EnumValue_Z"},
- "repeated_enum": {"EnumValue_X", "2", "0"},
- },
- filter: utilities.NewDoubleArray(nil),
- want: &proto3Message{
- EnumValue: EnumValue_Z,
- RepeatedEnum: []EnumValue{EnumValue_X, EnumValue_Z, EnumValue_X},
- },
- },
- {
- values: url.Values{
- "float_value": {"1.5"},
- "double_value": {"2.5"},
- "int64_value": {"-1"},
- "int32_value": {"-2"},
- "uint64_value": {"3"},
- "uint32_value": {"4"},
- "bool_value": {"true"},
- "string_value": {"str"},
- "repeated_value": {"a", "b", "c"},
- "enum_value": {"1"},
- "repeated_enum": {"1", "2", "0"},
- },
- filter: utilities.NewDoubleArray(nil),
- want: &proto2Message{
- FloatValue: proto.Float32(1.5),
- DoubleValue: proto.Float64(2.5),
- Int64Value: proto.Int64(-1),
- Int32Value: proto.Int32(-2),
- Uint64Value: proto.Uint64(3),
- Uint32Value: proto.Uint32(4),
- BoolValue: proto.Bool(true),
- StringValue: proto.String("str"),
- RepeatedValue: []string{"a", "b", "c"},
- EnumValue: EnumValue_Y,
- RepeatedEnum: []EnumValue{EnumValue_Y, EnumValue_Z, EnumValue_X},
- },
- },
- {
- values: url.Values{
- "floatValue": {"1.5"},
- "doubleValue": {"2.5"},
- "int64Value": {"-1"},
- "int32Value": {"-2"},
- "uint64Value": {"3"},
- "uint32Value": {"4"},
- "boolValue": {"true"},
- "stringValue": {"str"},
- "repeatedValue": {"a", "b", "c"},
- "enumValue": {"1"},
- "repeatedEnum": {"1", "2", "0"},
- },
- filter: utilities.NewDoubleArray(nil),
- want: &proto2Message{
- FloatValue: proto.Float32(1.5),
- DoubleValue: proto.Float64(2.5),
- Int64Value: proto.Int64(-1),
- Int32Value: proto.Int32(-2),
- Uint64Value: proto.Uint64(3),
- Uint32Value: proto.Uint32(4),
- BoolValue: proto.Bool(true),
- StringValue: proto.String("str"),
- RepeatedValue: []string{"a", "b", "c"},
- EnumValue: EnumValue_Y,
- RepeatedEnum: []EnumValue{EnumValue_Y, EnumValue_Z, EnumValue_X},
- },
- },
- {
- values: url.Values{
- "nested.nested.nested.repeated_value": {"a", "b", "c"},
- "nested.nested.nested.string_value": {"s"},
- "nested.nested.string_value": {"t"},
- "nested.string_value": {"u"},
- "nested_non_null.string_value": {"v"},
- "nested.nested.map_value[first]": {"foo"},
- "nested.nested.map_value[second]": {"bar"},
- },
- filter: utilities.NewDoubleArray(nil),
- want: &proto3Message{
- Nested: &proto2Message{
- Nested: &proto3Message{
- MapValue: map[string]string{
- "first": "foo",
- "second": "bar",
- },
- Nested: &proto2Message{
- RepeatedValue: []string{"a", "b", "c"},
- StringValue: proto.String("s"),
- },
- StringValue: "t",
- },
- StringValue: proto.String("u"),
- },
- NestedNonNull: proto2Message{
- StringValue: proto.String("v"),
- },
- },
- },
- {
- values: url.Values{
- "uint64_value": {"1", "2", "3", "4", "5"},
- },
- filter: utilities.NewDoubleArray(nil),
- want: &proto3Message{
- Uint64Value: 1,
- },
- },
- {
- values: url.Values{
- "oneof_string_value": {"foobar"},
- },
- filter: utilities.NewDoubleArray(nil),
- want: &proto3Message{
- OneofValue: &proto3Message_OneofStringValue{"foobar"},
- },
- },
- {
- values: url.Values{
- "oneof_bool_value": {"true"},
- },
- filter: utilities.NewDoubleArray(nil),
- want: &proto3Message{
- OneofValue: &proto3Message_OneofBoolValue{true},
- },
- },
- {
- // Don't allow setting a oneof more than once
- values: url.Values{
- "oneof_bool_value": {"true"},
- "oneof_string_value": {"foobar"},
- },
- filter: utilities.NewDoubleArray(nil),
- want: &proto3Message{},
- wanterr: errors.New("field already set for oneof_value oneof"),
- },
- } {
- msg := proto.Clone(spec.want)
- msg.Reset()
- err := runtime.PopulateQueryParameters(msg, spec.values, spec.filter)
- if spec.wanterr != nil {
- if !reflect.DeepEqual(err, spec.wanterr) {
- t.Errorf("runtime.PopulateQueryParameters(msg, %v, %v) failed with %v; want error %v", spec.values, spec.filter, err, spec.wanterr)
- }
- continue
- }
-
- if err != nil {
- t.Errorf("runtime.PopulateQueryParameters(msg, %v, %v) failed with %v; want success", spec.values, spec.filter, err)
- continue
- }
- if got, want := msg, spec.want; !proto.Equal(got, want) {
- t.Errorf("runtime.PopulateQueryParameters(msg, %v, %v = %v; want %v", spec.values, spec.filter, got, want)
- }
- }
-}
-
-func TestPopulateParametersWithNativeTypes(t *testing.T) {
- timeT := time.Date(2016, time.December, 15, 12, 23, 32, 49, time.UTC)
- timeStr := timeT.Format(time.RFC3339Nano)
-
- durationT := 13 * time.Hour
- durationStr := durationT.String()
-
- for _, spec := range []struct {
- values url.Values
- want *nativeProto3Message
- }{
- {
- values: url.Values{
- "native_timestamp_value": {timeStr},
- "native_duration_value": {durationStr},
- },
- want: &nativeProto3Message{
- NativeTimeValue: &timeT,
- NativeDurationValue: &durationT,
- },
- },
- {
- values: url.Values{
- "nativeTimestampValue": {timeStr},
- "nativeDurationValue": {durationStr},
- },
- want: &nativeProto3Message{
- NativeTimeValue: &timeT,
- NativeDurationValue: &durationT,
- },
- },
- } {
- msg := new(nativeProto3Message)
- err := runtime.PopulateQueryParameters(msg, spec.values, utilities.NewDoubleArray(nil))
-
- if err != nil {
- t.Errorf("runtime.PopulateQueryParameters(msg, %v, utilities.NewDoubleArray(nil)) failed with %v; want success", spec.values, err)
- continue
- }
- if got, want := msg, spec.want; !proto.Equal(got, want) {
- t.Errorf("runtime.PopulateQueryParameters(msg, %v, utilities.NewDoubleArray(nil)) = %v; want %v", spec.values, got, want)
- }
- }
-}
-
-func TestPopulateParametersWithFilters(t *testing.T) {
- for _, spec := range []struct {
- values url.Values
- filter *utilities.DoubleArray
- want proto.Message
- }{
- {
- values: url.Values{
- "bool_value": {"true"},
- "string_value": {"str"},
- "repeated_value": {"a", "b", "c"},
- },
- filter: utilities.NewDoubleArray([][]string{
- {"bool_value"}, {"repeated_value"},
- }),
- want: &proto3Message{
- StringValue: "str",
- },
- },
- {
- values: url.Values{
- "nested.nested.bool_value": {"true"},
- "nested.nested.string_value": {"str"},
- "nested.string_value": {"str"},
- "string_value": {"str"},
- },
- filter: utilities.NewDoubleArray([][]string{
- {"nested"},
- }),
- want: &proto3Message{
- StringValue: "str",
- },
- },
- {
- values: url.Values{
- "nested.nested.bool_value": {"true"},
- "nested.nested.string_value": {"str"},
- "nested.string_value": {"str"},
- "string_value": {"str"},
- },
- filter: utilities.NewDoubleArray([][]string{
- {"nested", "nested"},
- }),
- want: &proto3Message{
- Nested: &proto2Message{
- StringValue: proto.String("str"),
- },
- StringValue: "str",
- },
- },
- {
- values: url.Values{
- "nested.nested.bool_value": {"true"},
- "nested.nested.string_value": {"str"},
- "nested.string_value": {"str"},
- "string_value": {"str"},
- },
- filter: utilities.NewDoubleArray([][]string{
- {"nested", "nested", "string_value"},
- }),
- want: &proto3Message{
- Nested: &proto2Message{
- StringValue: proto.String("str"),
- Nested: &proto3Message{
- BoolValue: true,
- },
- },
- StringValue: "str",
- },
- },
- } {
- msg := proto.Clone(spec.want)
- msg.Reset()
- err := runtime.PopulateQueryParameters(msg, spec.values, spec.filter)
- if err != nil {
- t.Errorf("runtime.PoplateQueryParameters(msg, %v, %v) failed with %v; want success", spec.values, spec.filter, err)
- continue
- }
- if got, want := msg, spec.want; !proto.Equal(got, want) {
- t.Errorf("runtime.PopulateQueryParameters(msg, %v, %v = %v; want %v", spec.values, spec.filter, got, want)
- }
- }
-}
-
-func TestPopulateQueryParametersWithInvalidNestedParameters(t *testing.T) {
- for _, spec := range []struct {
- msg proto.Message
- values url.Values
- filter *utilities.DoubleArray
- }{
- {
- msg: &proto3Message{},
- values: url.Values{
- "float_value.nested": {"test"},
- },
- filter: utilities.NewDoubleArray(nil),
- },
- {
- msg: &proto3Message{},
- values: url.Values{
- "double_value.nested": {"test"},
- },
- filter: utilities.NewDoubleArray(nil),
- },
- {
- msg: &proto3Message{},
- values: url.Values{
- "int64_value.nested": {"test"},
- },
- filter: utilities.NewDoubleArray(nil),
- },
- {
- msg: &proto3Message{},
- values: url.Values{
- "int32_value.nested": {"test"},
- },
- filter: utilities.NewDoubleArray(nil),
- },
- {
- msg: &proto3Message{},
- values: url.Values{
- "uint64_value.nested": {"test"},
- },
- filter: utilities.NewDoubleArray(nil),
- },
- {
- msg: &proto3Message{},
- values: url.Values{
- "uint32_value.nested": {"test"},
- },
- filter: utilities.NewDoubleArray(nil),
- },
- {
- msg: &proto3Message{},
- values: url.Values{
- "bool_value.nested": {"test"},
- },
- filter: utilities.NewDoubleArray(nil),
- },
- {
- msg: &proto3Message{},
- values: url.Values{
- "string_value.nested": {"test"},
- },
- filter: utilities.NewDoubleArray(nil),
- },
- {
- msg: &proto3Message{},
- values: url.Values{
- "repeated_value.nested": {"test"},
- },
- filter: utilities.NewDoubleArray(nil),
- },
- {
- msg: &proto3Message{},
- values: url.Values{
- "enum_value.nested": {"test"},
- },
- filter: utilities.NewDoubleArray(nil),
- },
- {
- msg: &proto3Message{},
- values: url.Values{
- "enum_value.nested": {"test"},
- },
- filter: utilities.NewDoubleArray(nil),
- },
- {
- msg: &proto3Message{},
- values: url.Values{
- "repeated_enum.nested": {"test"},
- },
- filter: utilities.NewDoubleArray(nil),
- },
- } {
- spec.msg.Reset()
- err := runtime.PopulateQueryParameters(spec.msg, spec.values, spec.filter)
- if err == nil {
- t.Errorf("runtime.PopulateQueryParameters(msg, %v, %v) did not fail; want error", spec.values, spec.filter)
- }
- }
-}
-
-type proto3Message struct {
- Nested *proto2Message `protobuf:"bytes,1,opt,name=nested,json=nested" json:"nested,omitempty"`
- NestedNonNull proto2Message `protobuf:"bytes,15,opt,name=nested_non_null,json=nestedNonNull" json:"nested_non_null,omitempty"`
- FloatValue float32 `protobuf:"fixed32,2,opt,name=float_value,json=floatValue" json:"float_value,omitempty"`
- DoubleValue float64 `protobuf:"fixed64,3,opt,name=double_value,json=doubleValue" json:"double_value,omitempty"`
- Int64Value int64 `protobuf:"varint,4,opt,name=int64_value,json=int64Value" json:"int64_value,omitempty"`
- Int32Value int32 `protobuf:"varint,5,opt,name=int32_value,json=int32Value" json:"int32_value,omitempty"`
- Uint64Value uint64 `protobuf:"varint,6,opt,name=uint64_value,json=uint64Value" json:"uint64_value,omitempty"`
- Uint32Value uint32 `protobuf:"varint,7,opt,name=uint32_value,json=uint32Value" json:"uint32_value,omitempty"`
- BoolValue bool `protobuf:"varint,8,opt,name=bool_value,json=boolValue" json:"bool_value,omitempty"`
- StringValue string `protobuf:"bytes,9,opt,name=string_value,json=stringValue" json:"string_value,omitempty"`
- BytesValue []byte `protobuf:"bytes,25,opt,name=bytes_value,json=bytesValue" json:"bytes_value,omitempty"`
- RepeatedValue []string `protobuf:"bytes,10,rep,name=repeated_value,json=repeatedValue" json:"repeated_value,omitempty"`
- EnumValue EnumValue `protobuf:"varint,11,opt,name=enum_value,json=enumValue,enum=runtime_test_api.EnumValue" json:"enum_value,omitempty"`
- RepeatedEnum []EnumValue `protobuf:"varint,12,rep,packed,name=repeated_enum,json=repeatedEnum,enum=runtime_test_api.EnumValue" json:"repeated_enum,omitempty"`
- TimestampValue *timestamp.Timestamp `protobuf:"bytes,16,opt,name=timestamp_value,json=timestampValue" json:"timestamp_value,omitempty"`
- DurationValue *duration.Duration `protobuf:"bytes,42,opt,name=duration_value,json=durationValue" json:"duration_value,omitempty"`
- FieldMaskValue *field_mask.FieldMask `protobuf:"bytes,27,opt,name=fieldmask_value,json=fieldmaskValue" json:"fieldmask_value,omitempty"`
- OneofValue proto3Message_OneofValue `protobuf_oneof:"oneof_value"`
- WrapperDoubleValue *wrappers.DoubleValue `protobuf:"bytes,17,opt,name=wrapper_double_value,json=wrapperDoubleValue" json:"wrapper_double_value,omitempty"`
- WrapperFloatValue *wrappers.FloatValue `protobuf:"bytes,18,opt,name=wrapper_float_value,json=wrapperFloatValue" json:"wrapper_float_value,omitempty"`
- WrapperInt64Value *wrappers.Int64Value `protobuf:"bytes,19,opt,name=wrapper_int64_value,json=wrapperInt64Value" json:"wrapper_int64_value,omitempty"`
- WrapperInt32Value *wrappers.Int32Value `protobuf:"bytes,20,opt,name=wrapper_int32_value,json=wrapperInt32Value" json:"wrapper_int32_value,omitempty"`
- WrapperUInt64Value *wrappers.UInt64Value `protobuf:"bytes,21,opt,name=wrapper_u_int64_value,json=wrapperUInt64Value" json:"wrapper_u_int64_value,omitempty"`
- WrapperUInt32Value *wrappers.UInt32Value `protobuf:"bytes,22,opt,name=wrapper_u_int32_value,json=wrapperUInt32Value" json:"wrapper_u_int32_value,omitempty"`
- WrapperBoolValue *wrappers.BoolValue `protobuf:"bytes,23,opt,name=wrapper_bool_value,json=wrapperBoolValue" json:"wrapper_bool_value,omitempty"`
- WrapperStringValue *wrappers.StringValue `protobuf:"bytes,24,opt,name=wrapper_string_value,json=wrapperStringValue" json:"wrapper_string_value,omitempty"`
- WrapperBytesValue *wrappers.BytesValue `protobuf:"bytes,26,opt,name=wrapper_bytes_value,json=wrapperBytesValue" json:"wrapper_bytes_value,omitempty"`
- MapValue map[string]string `protobuf:"bytes,27,opt,name=map_value,json=mapValue" json:"map_value,omitempty"`
- MapValue2 map[string]int32 `protobuf:"bytes,28,opt,name=map_value2,json=mapValue2" json:"map_value2,omitempty"`
- MapValue3 map[int32]string `protobuf:"bytes,29,opt,name=map_value3,json=mapValue3" json:"map_value3,omitempty"`
- MapValue4 map[string]int64 `protobuf:"bytes,30,opt,name=map_value4,json=mapValue4" json:"map_value4,omitempty"`
- MapValue5 map[int64]string `protobuf:"bytes,31,opt,name=map_value5,json=mapValue5" json:"map_value5,omitempty"`
- MapValue6 map[string]uint32 `protobuf:"bytes,32,opt,name=map_value6,json=mapValue6" json:"map_value6,omitempty"`
- MapValue7 map[uint32]string `protobuf:"bytes,33,opt,name=map_value7,json=mapValue7" json:"map_value7,omitempty"`
- MapValue8 map[string]uint64 `protobuf:"bytes,34,opt,name=map_value8,json=mapValue8" json:"map_value8,omitempty"`
- MapValue9 map[uint64]string `protobuf:"bytes,35,opt,name=map_value9,json=mapValue9" json:"map_value9,omitempty"`
- MapValue10 map[string]float32 `protobuf:"bytes,36,opt,name=map_value10,json=mapValue10" json:"map_value10,omitempty"`
- MapValue11 map[float32]string `protobuf:"bytes,37,opt,name=map_value11,json=mapValue11" json:"map_value11,omitempty"`
- MapValue12 map[string]float64 `protobuf:"bytes,38,opt,name=map_value12,json=mapValue12" json:"map_value12,omitempty"`
- MapValue13 map[float64]string `protobuf:"bytes,39,opt,name=map_value13,json=mapValue13" json:"map_value13,omitempty"`
- MapValue14 map[string]bool `protobuf:"bytes,40,opt,name=map_value14,json=mapValue14" json:"map_value14,omitempty"`
- MapValue15 map[bool]string `protobuf:"bytes,41,opt,name=map_value15,json=mapValue15" json:"map_value15,omitempty"`
-}
-
-func (m *proto3Message) Reset() { *m = proto3Message{} }
-func (m *proto3Message) String() string { return proto.CompactTextString(m) }
-func (*proto3Message) ProtoMessage() {}
-
-func (m *proto3Message) GetNested() *proto2Message {
- if m != nil {
- return m.Nested
- }
- return nil
-}
-
-type proto3Message_OneofValue interface {
- proto3Message_OneofValue()
-}
-
-type proto3Message_OneofBoolValue struct {
- OneofBoolValue bool `protobuf:"varint,13,opt,name=oneof_bool_value,json=oneofBoolValue,oneof"`
-}
-type proto3Message_OneofStringValue struct {
- OneofStringValue string `protobuf:"bytes,14,opt,name=oneof_string_value,json=oneofStringValue,oneof"`
-}
-
-func (*proto3Message_OneofBoolValue) proto3Message_OneofValue() {}
-func (*proto3Message_OneofStringValue) proto3Message_OneofValue() {}
-
-func (m *proto3Message) GetOneofValue() proto3Message_OneofValue {
- if m != nil {
- return m.OneofValue
- }
- return nil
-}
-
-func (m *proto3Message) GetOneofBoolValue() bool {
- if x, ok := m.GetOneofValue().(*proto3Message_OneofBoolValue); ok {
- return x.OneofBoolValue
- }
- return false
-}
-
-func (m *proto3Message) GetOneofStringValue() string {
- if x, ok := m.GetOneofValue().(*proto3Message_OneofStringValue); ok {
- return x.OneofStringValue
- }
- return ""
-}
-
-// XXX_OneofFuncs is for the internal use of the proto package.
-func (*proto3Message) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
- return _proto3Message_OneofMarshaler, _proto3Message_OneofUnmarshaler, _proto3Message_OneofSizer, []interface{}{
- (*proto3Message_OneofBoolValue)(nil),
- (*proto3Message_OneofStringValue)(nil),
- }
-}
-
-func _proto3Message_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
- m := msg.(*proto3Message)
- // oneof_value
- switch x := m.OneofValue.(type) {
- case *proto3Message_OneofBoolValue:
- t := uint64(0)
- if x.OneofBoolValue {
- t = 1
- }
- b.EncodeVarint(13<<3 | proto.WireVarint)
- b.EncodeVarint(t)
- case *proto3Message_OneofStringValue:
- b.EncodeVarint(14<<3 | proto.WireBytes)
- b.EncodeStringBytes(x.OneofStringValue)
- case nil:
- default:
- return fmt.Errorf("proto3Message.OneofValue has unexpected type %T", x)
- }
- return nil
-}
-
-func _proto3Message_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
- m := msg.(*proto3Message)
- switch tag {
- case 14: // oneof_value.oneof_bool_value
- if wire != proto.WireVarint {
- return true, proto.ErrInternalBadWireType
- }
- x, err := b.DecodeVarint()
- m.OneofValue = &proto3Message_OneofBoolValue{x != 0}
- return true, err
- case 15: // oneof_value.oneof_string_value
- if wire != proto.WireBytes {
- return true, proto.ErrInternalBadWireType
- }
- x, err := b.DecodeStringBytes()
- m.OneofValue = &proto3Message_OneofStringValue{x}
- return true, err
- default:
- return false, nil
- }
-}
-
-func _proto3Message_OneofSizer(msg proto.Message) (n int) {
- m := msg.(*proto3Message)
- // oneof_value
- switch x := m.OneofValue.(type) {
- case *proto3Message_OneofBoolValue:
- n += proto.SizeVarint(14<<3 | proto.WireVarint)
- n += 1
- case *proto3Message_OneofStringValue:
- n += proto.SizeVarint(15<<3 | proto.WireBytes)
- n += proto.SizeVarint(uint64(len(x.OneofStringValue)))
- n += len(x.OneofStringValue)
- case nil:
- default:
- panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
- }
- return n
-}
-
-type nativeProto3Message struct {
- NativeTimeValue *time.Time `protobuf:"bytes,1,opt,name=native_timestamp_value,json=nativeTimestampValue" json:"native_timestamp_value,omitempty"`
- NativeDurationValue *time.Duration `protobuf:"bytes,2,opt,name=native_duration_value,json=nativeDurationValue" json:"native_duration_value,omitempty"`
-}
-
-func (m *nativeProto3Message) Reset() { *m = nativeProto3Message{} }
-func (m *nativeProto3Message) String() string { return proto.CompactTextString(m) }
-func (*nativeProto3Message) ProtoMessage() {}
-
-type proto2Message struct {
- Nested *proto3Message `protobuf:"bytes,1,opt,name=nested,json=nested" json:"nested,omitempty"`
- FloatValue *float32 `protobuf:"fixed32,2,opt,name=float_value,json=floatValue" json:"float_value,omitempty"`
- DoubleValue *float64 `protobuf:"fixed64,3,opt,name=double_value,json=doubleValue" json:"double_value,omitempty"`
- Int64Value *int64 `protobuf:"varint,4,opt,name=int64_value,json=int64Value" json:"int64_value,omitempty"`
- Int32Value *int32 `protobuf:"varint,5,opt,name=int32_value,json=int32Value" json:"int32_value,omitempty"`
- Uint64Value *uint64 `protobuf:"varint,6,opt,name=uint64_value,json=uint64Value" json:"uint64_value,omitempty"`
- Uint32Value *uint32 `protobuf:"varint,7,opt,name=uint32_value,json=uint32Value" json:"uint32_value,omitempty"`
- BoolValue *bool `protobuf:"varint,8,opt,name=bool_value,json=boolValue" json:"bool_value,omitempty"`
- StringValue *string `protobuf:"bytes,9,opt,name=string_value,json=stringValue" json:"string_value,omitempty"`
- RepeatedValue []string `protobuf:"bytes,10,rep,name=repeated_value,json=repeatedValue" json:"repeated_value,omitempty"`
- EnumValue EnumValue `protobuf:"varint,11,opt,name=enum_value,json=enumValue,enum=runtime_test_api.EnumValue" json:"enum_value,omitempty"`
- RepeatedEnum []EnumValue `protobuf:"varint,12,rep,packed,name=repeated_enum,json=repeatedEnum,enum=runtime_test_api.EnumValue" json:"repeated_enum,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *proto2Message) Reset() { *m = proto2Message{} }
-func (m *proto2Message) String() string { return proto.CompactTextString(m) }
-func (*proto2Message) ProtoMessage() {}
-
-func (m *proto2Message) GetNested() *proto3Message {
- if m != nil {
- return m.Nested
- }
- return nil
-}
-
-func (m *proto2Message) GetFloatValue() float32 {
- if m != nil && m.FloatValue != nil {
- return *m.FloatValue
- }
- return 0
-}
-
-func (m *proto2Message) GetDoubleValue() float64 {
- if m != nil && m.DoubleValue != nil {
- return *m.DoubleValue
- }
- return 0
-}
-
-func (m *proto2Message) GetInt64Value() int64 {
- if m != nil && m.Int64Value != nil {
- return *m.Int64Value
- }
- return 0
-}
-
-func (m *proto2Message) GetInt32Value() int32 {
- if m != nil && m.Int32Value != nil {
- return *m.Int32Value
- }
- return 0
-}
-
-func (m *proto2Message) GetUint64Value() uint64 {
- if m != nil && m.Uint64Value != nil {
- return *m.Uint64Value
- }
- return 0
-}
-
-func (m *proto2Message) GetUint32Value() uint32 {
- if m != nil && m.Uint32Value != nil {
- return *m.Uint32Value
- }
- return 0
-}
-
-func (m *proto2Message) GetBoolValue() bool {
- if m != nil && m.BoolValue != nil {
- return *m.BoolValue
- }
- return false
-}
-
-func (m *proto2Message) GetStringValue() string {
- if m != nil && m.StringValue != nil {
- return *m.StringValue
- }
- return ""
-}
-
-func (m *proto2Message) GetRepeatedValue() []string {
- if m != nil {
- return m.RepeatedValue
- }
- return nil
-}
-
-type EnumValue int32
-
-const (
- EnumValue_X EnumValue = 0
- EnumValue_Y EnumValue = 1
- EnumValue_Z EnumValue = 2
-)
-
-var EnumValue_name = map[int32]string{
- 0: "EnumValue_X",
- 1: "EnumValue_Y",
- 2: "EnumValue_Z",
-}
-var EnumValue_value = map[string]int32{
- "EnumValue_X": 0,
- "EnumValue_Y": 1,
- "EnumValue_Z": 2,
-}
-
-func init() {
- proto.RegisterEnum("runtime_test_api.EnumValue", EnumValue_name, EnumValue_value)
-}
diff --git a/gateway/runtime/service.go b/gateway/runtime/service.go
index b048912..5b37ec2 100755
--- a/gateway/runtime/service.go
+++ b/gateway/runtime/service.go
@@ -3,15 +3,15 @@ package runtime
import (
"google.golang.org/grpc"
- options "github.com/binchencoder/ease-gateway/httpoptions"
+ options "github.com/binchencoder/janus-gateway/httpoptions"
vexpb "github.com/binchencoder/gateway-proto/data"
skypb "github.com/binchencoder/skylb-api/proto"
)
var (
// CallerServiceId sets the gRPC caller service ID of the gateway.
- // For ease-gateway, it's ServiceId_EASE_GATEWAY.
- CallerServiceId = vexpb.ServiceId_EASE_GATEWAY
+ // For janus-gateway, it's ServiceId_JANUS_GATEWAY.
+ CallerServiceId = vexpb.ServiceId_JANUS_GATEWAY
)
// Method represents a gRPC service method.
diff --git a/go.mod b/go.mod
index d129ac2..79e2544 100644
--- a/go.mod
+++ b/go.mod
@@ -1,26 +1,34 @@
-module github.com/binchencoder/ease-gateway
+module github.com/binchencoder/janus-gateway
-go 1.13
+go 1.17
-replace (
- github.com/coreos/bbolt v1.3.4 => go.etcd.io/bbolt v1.3.4
- github.com/coreos/bbolt v1.3.5 => go.etcd.io/bbolt v1.3.5
+require (
+ github.com/binchencoder/gateway-proto v0.0.7
+ github.com/binchencoder/letsgo v0.0.3
+ github.com/binchencoder/skylb-api v0.3.1
+ github.com/antihax/optional v1.0.0
+ github.com/golang/glog v1.0.0
+ github.com/golang/protobuf v1.5.2
+ github.com/google/go-cmp v0.5.7
+ github.com/grpc-ecosystem/grpc-gateway/v2 v2.9.0
+ github.com/rogpeppe/fastuuid v1.2.0
+ golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a
+ google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106
+ google.golang.org/grpc v1.45.0
+ google.golang.org/protobuf v1.28.0
+ gopkg.in/yaml.v2 v2.4.0
+ sigs.k8s.io/yaml v1.3.0
)
require (
- github.com/binchencoder/gateway-proto v0.0.3 // indirect
- github.com/binchencoder/letsgo v0.0.3
- github.com/binchencoder/skylb-api v0.0.3
- github.com/fatih/color v1.9.0
- github.com/ghodss/yaml v1.0.0
- github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
- github.com/golang/protobuf v1.4.2
- github.com/grpc-ecosystem/grpc-gateway v1.14.6
- github.com/klauspost/compress v1.10.10
- github.com/pborman/uuid v1.2.0
- github.com/prometheus/client_golang v1.7.1
- golang.org/x/net v0.0.0-20200625001655-4c5254603344
- google.golang.org/genproto v0.0.0-20200702021140-07506425bd67
- google.golang.org/grpc v1.30.0
- google.golang.org/grpc/examples v0.0.0-20200630190442-3de8449f8555 // indirect
+ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
+ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
+ golang.org/x/text v0.3.7 // indirect
+ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
+ google.golang.org/appengine v1.6.6 // indirect
+)
+
+replace (
+ github.com/coreos/bbolt v1.3.4 => go.etcd.io/bbolt v1.3.4
+ github.com/coreos/bbolt v1.3.5 => go.etcd.io/bbolt v1.3.5
)
diff --git a/go.sum b/go.sum
index c0b7558..7912701 100644
--- a/go.sum
+++ b/go.sum
@@ -1,6 +1,38 @@
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=
+cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
+cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
+cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
+cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
+cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
+cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
+cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
+cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
+cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
+cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
+cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
+cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
+cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
+cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
+cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
+cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
+cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
+cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
+cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
+cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
+cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
+cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
+cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
+cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
+cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
+cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
+cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
+cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
+cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
+cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
+dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
@@ -27,18 +59,21 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
-github.com/binchencoder/gateway-proto v0.0.3 h1:xU2ZVx5Zjub5P/WIl12FeCII1vGdV2THWtfm7fUR7z8=
-github.com/binchencoder/gateway-proto v0.0.3/go.mod h1:081rlF+665EejkDRHi7gTLpZvK0eDwVX23xviXQCjV0=
+github.com/binchencoder/janus-gateway v0.0.4/go.mod h1:L8fCaUA1FaYO0ReFNAri15ozAj9NeJ9B+Q6CQAyPFqY=
+github.com/binchencoder/gateway-proto v0.0.5/go.mod h1:853l4bAOm0Gt8XrDy+9obeKRlBLwP4HAk9tVYbgnSmU=
+github.com/binchencoder/gateway-proto v0.0.7 h1:+3d1QEBqDxFrTIVrSiao4saXNFNeK/vxsIsa1ClSYBI=
+github.com/binchencoder/gateway-proto v0.0.7/go.mod h1:DUtwTL1FDBeVIDIHxS8v2YajyWqe444jSvCxexR161A=
github.com/binchencoder/letsgo v0.0.3 h1:hEDDOeGdX9R/JPYMdVo9N/9iQa5BeBLluTssrNYy/ng=
github.com/binchencoder/letsgo v0.0.3/go.mod h1:WbqNFa5gFsogqe3gtycvPYswprKV7eGJIxScwQhAg44=
-github.com/binchencoder/skylb-api v0.0.3 h1:NnlPmEjTgOjH+s9TK3rBEY4Kn9aEzZkuEBUV2aR8UTM=
-github.com/binchencoder/skylb-api v0.0.3/go.mod h1:j/ATHuW3TU7M5+fWeTqrvOzmFQI7Z4AVerdP6JYOkUk=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
+github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
+github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
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=
@@ -74,6 +109,9 @@ github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo=
@@ -89,13 +127,24 @@ github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
+github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/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.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
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=
@@ -104,6 +153,11 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
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/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
+github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -112,11 +166,31 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
+github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
+github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
+github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
+github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
+github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
@@ -131,6 +205,10 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t
github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c=
github.com/grpc-ecosystem/grpc-gateway v1.14.6 h1:8ERzHx8aj1Sc47mu9n/AksaKCSWrMchFtkdrS4BIj5o=
github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw=
+github.com/grpc-ecosystem/grpc-gateway v1.15.2 h1:HC+hWRWf+v5zTMPyoaYTKIJih+4sd4XRWmj0qlG87Co=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.0.1 h1:X2vfSnm1WC8HEo0MBHZg2TcuDUHJj6kd1TmEAQncnSA=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.0.1/go.mod h1:oVMjMN64nzEcepv1kdZKgx1qNYt4Ro0Gqefiq2JWdis=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.8.0/go.mod h1:/fckq3NE+vGiJsd4fDt4ge1XrK8cN+e5G5QWIzdg7Q8=
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU=
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw=
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
@@ -155,6 +233,7 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
+github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
@@ -163,6 +242,8 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
+github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
@@ -309,12 +390,20 @@ github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
+github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
+go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
+go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
+go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
@@ -325,128 +414,214 @@ go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
-golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
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/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
+golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
+golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
+golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
+golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
+golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
+golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
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-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
+golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
+golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
+golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181220203305-927f97764cc3/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-20190125091013-d26f9f9a57f3/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-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
-golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
+golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
+golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
+golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM=
+golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
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-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80=
-golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
+golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
-golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
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-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20200103221440-774c71fcf114 h1:DnSr2mCsxyCE6ZgIkmcWUQY2R5cH/6wL7eIxEmQOMSE=
-golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
+golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
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/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
+google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
+google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
+google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
+google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
+google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
+google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
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-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
-google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
-google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
-google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
-google.golang.org/genproto v0.0.0-20200624020401-64a14ca9d1ad/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
+google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20200702021140-07506425bd67 h1:4BC1C1i30F3MZeiIO6y6IIo4DxrtOwITK87bQl3lhFA=
google.golang.org/genproto v0.0.0-20200702021140-07506425bd67/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
-google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
-google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
-google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
-google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
-google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
-google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
-google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
-google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
-google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
-google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154 h1:bFFRpT+e8JJVY7lMMfvezL1ZIwqiwmPl2bsE2yx4HqM=
+google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0 h1:M5a8xTlYTxwMn5ZFkwhRabsygDY5G8TYLyQDBxJNAxE=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
-google.golang.org/grpc/examples v0.0.0-20200630190442-3de8449f8555 h1:B6/wMqTY7mM93BBu0wfiO67B9+bcv4oQQsdrcijjfzA=
-google.golang.org/grpc/examples v0.0.0-20200630190442-3de8449f8555/go.mod h1:5j1uub0jRGhRiSghIlrThmBUgcgLXOVJQ/l1getT4uo=
+google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.33.1 h1:DGeFlSan2f+WEtCERJ4J9GJWk15TxUi8QGagfI87Xyc=
+google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
+google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M=
+google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
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=
@@ -455,8 +630,13 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
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.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
+google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
+google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -476,14 +656,23 @@ gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
+rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
+rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
+sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
upper.io/db.v3 v3.7.1+incompatible h1:GiK/NmDUClH3LrZd54qj5OQsz8brGFv652QXyRXtg2U=
upper.io/db.v3 v3.7.1+incompatible/go.mod h1:FgTdD24eBjJAbPKsQSiHUNgXjOR4Lub3u1UMHSIh82Y=
diff --git a/httpoptions/BUILD.bazel b/httpoptions/BUILD.bazel
index 9e28937..5bf5ff1 100644
--- a/httpoptions/BUILD.bazel
+++ b/httpoptions/BUILD.bazel
@@ -12,9 +12,9 @@ filegroup(
)
go_library(
- name = "go_default_library",
+ name = "httpoptions",
embed = [":options_go_proto"],
- importpath = "github.com/binchencoder/ease-gateway/httpoptions",
+ importpath = "github.com/binchencoder/janus-gateway/httpoptions",
)
proto_library(
@@ -27,27 +27,36 @@ proto_library(
"@com_google_protobuf//:any_proto",
"@com_google_protobuf//:descriptor_proto",
"@com_github_binchencoder_gateway_proto//data:data_proto",
+ "@com_github_binchencoder_gateway_proto//frontend:error_proto",
],
)
go_proto_library(
name = "options_go_proto",
compilers = ["@io_bazel_rules_go//proto:go_grpc"],
- importpath = "github.com/binchencoder/ease-gateway/httpoptions",
- proto = ":ease_api_proto",
+ importpath = "github.com/binchencoder/janus-gateway/httpoptions",
+ proto = ":options_proto",
deps = [
"@com_github_binchencoder_gateway_proto//data:go_default_library",
+ "@com_github_binchencoder_gateway_proto//frontend:go_default_library",
],
)
-proto_library(
- name = "ease_api_proto",
- srcs = [
- "annotations.proto",
- "http.proto",
- ],
- deps = [
- "@com_github_binchencoder_gateway_proto//data:data_proto",
- "@com_google_protobuf//:descriptor_proto",
- ],
+# proto_library(
+# name = "janus_api_proto",
+# srcs = [
+# "annotations.proto",
+# "http.proto",
+# ],
+# deps = [
+# "@com_github_binchencoder_gateway_proto//data:data_proto",
+# "@com_github_binchencoder_gateway_proto//frontend:error_proto",
+# "@com_google_protobuf//:descriptor_proto",
+# ],
+# )
+
+alias(
+ name = "go_default_library",
+ actual = ":options_go_proto",
+ visibility = ["//visibility:public"],
)
diff --git a/httpoptions/annotations.pb.go b/httpoptions/annotations.pb.go
new file mode 100755
index 0000000..575c928
--- /dev/null
+++ b/httpoptions/annotations.pb.go
@@ -0,0 +1,986 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.27.1
+// protoc v3.19.4
+// source: httpoptions/annotations.proto
+
+package annotations
+
+import (
+ data "github.com/binchencoder/gateway-proto/data"
+ _ "github.com/binchencoder/gateway-proto/frontend"
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ descriptorpb "google.golang.org/protobuf/types/descriptorpb"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type ApiSourceType int32
+
+const (
+ ApiSourceType_JANUS_GATEWAY ApiSourceType = 0
+ ApiSourceType_OPEN_GATEWAY ApiSourceType = 1
+)
+
+// Enum value maps for ApiSourceType.
+var (
+ ApiSourceType_name = map[int32]string{
+ 0: "JANUS_GATEWAY",
+ 1: "OPEN_GATEWAY",
+ }
+ ApiSourceType_value = map[string]int32{
+ "JANUS_GATEWAY": 0,
+ "OPEN_GATEWAY": 1,
+ }
+)
+
+func (x ApiSourceType) Enum() *ApiSourceType {
+ p := new(ApiSourceType)
+ *p = x
+ return p
+}
+
+func (x ApiSourceType) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (ApiSourceType) Descriptor() protoreflect.EnumDescriptor {
+ return file_httpoptions_annotations_proto_enumTypes[0].Descriptor()
+}
+
+func (ApiSourceType) Type() protoreflect.EnumType {
+ return &file_httpoptions_annotations_proto_enumTypes[0]
+}
+
+func (x ApiSourceType) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use ApiSourceType.Descriptor instead.
+func (ApiSourceType) EnumDescriptor() ([]byte, []int) {
+ return file_httpoptions_annotations_proto_rawDescGZIP(), []int{0}
+}
+
+type AuthTokenType int32
+
+const (
+ AuthTokenType_JANUS_AUTH_TOKEN AuthTokenType = 0
+ AuthTokenType_BASE_ACCESS_TOKEN AuthTokenType = 1
+)
+
+// Enum value maps for AuthTokenType.
+var (
+ AuthTokenType_name = map[int32]string{
+ 0: "JANUS_AUTH_TOKEN",
+ 1: "BASE_ACCESS_TOKEN",
+ }
+ AuthTokenType_value = map[string]int32{
+ "JANUS_AUTH_TOKEN": 0,
+ "BASE_ACCESS_TOKEN": 1,
+ }
+)
+
+func (x AuthTokenType) Enum() *AuthTokenType {
+ p := new(AuthTokenType)
+ *p = x
+ return p
+}
+
+func (x AuthTokenType) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (AuthTokenType) Descriptor() protoreflect.EnumDescriptor {
+ return file_httpoptions_annotations_proto_enumTypes[1].Descriptor()
+}
+
+func (AuthTokenType) Type() protoreflect.EnumType {
+ return &file_httpoptions_annotations_proto_enumTypes[1]
+}
+
+func (x AuthTokenType) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use AuthTokenType.Descriptor instead.
+func (AuthTokenType) EnumDescriptor() ([]byte, []int) {
+ return file_httpoptions_annotations_proto_rawDescGZIP(), []int{1}
+}
+
+type SpecSourceType int32
+
+const (
+ SpecSourceType_UNSPECIFIED SpecSourceType = 0
+ SpecSourceType_WEB SpecSourceType = 1
+)
+
+// Enum value maps for SpecSourceType.
+var (
+ SpecSourceType_name = map[int32]string{
+ 0: "UNSPECIFIED",
+ 1: "WEB",
+ }
+ SpecSourceType_value = map[string]int32{
+ "UNSPECIFIED": 0,
+ "WEB": 1,
+ }
+)
+
+func (x SpecSourceType) Enum() *SpecSourceType {
+ p := new(SpecSourceType)
+ *p = x
+ return p
+}
+
+func (x SpecSourceType) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (SpecSourceType) Descriptor() protoreflect.EnumDescriptor {
+ return file_httpoptions_annotations_proto_enumTypes[2].Descriptor()
+}
+
+func (SpecSourceType) Type() protoreflect.EnumType {
+ return &file_httpoptions_annotations_proto_enumTypes[2]
+}
+
+func (x SpecSourceType) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use SpecSourceType.Descriptor instead.
+func (SpecSourceType) EnumDescriptor() ([]byte, []int) {
+ return file_httpoptions_annotations_proto_rawDescGZIP(), []int{2}
+}
+
+type LoadBalancer int32
+
+const (
+ LoadBalancer_ROUND_ROBIN LoadBalancer = 0
+ LoadBalancer_CONSISTENT LoadBalancer = 1
+)
+
+// Enum value maps for LoadBalancer.
+var (
+ LoadBalancer_name = map[int32]string{
+ 0: "ROUND_ROBIN",
+ 1: "CONSISTENT",
+ }
+ LoadBalancer_value = map[string]int32{
+ "ROUND_ROBIN": 0,
+ "CONSISTENT": 1,
+ }
+)
+
+func (x LoadBalancer) Enum() *LoadBalancer {
+ p := new(LoadBalancer)
+ *p = x
+ return p
+}
+
+func (x LoadBalancer) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (LoadBalancer) Descriptor() protoreflect.EnumDescriptor {
+ return file_httpoptions_annotations_proto_enumTypes[3].Descriptor()
+}
+
+func (LoadBalancer) Type() protoreflect.EnumType {
+ return &file_httpoptions_annotations_proto_enumTypes[3]
+}
+
+func (x LoadBalancer) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use LoadBalancer.Descriptor instead.
+func (LoadBalancer) EnumDescriptor() ([]byte, []int) {
+ return file_httpoptions_annotations_proto_rawDescGZIP(), []int{3}
+}
+
+type OperatorType int32
+
+const (
+ OperatorType_OPERATOR_TYPE_UNKNOWN OperatorType = 0
+ OperatorType_GT OperatorType = 1
+ OperatorType_LT OperatorType = 2
+ OperatorType_EQ OperatorType = 3
+ OperatorType_MATCH OperatorType = 4
+ OperatorType_NON_NIL OperatorType = 5
+ OperatorType_LEN_GT OperatorType = 6
+ OperatorType_LEN_LT OperatorType = 7
+ OperatorType_LEN_EQ OperatorType = 8
+)
+
+// Enum value maps for OperatorType.
+var (
+ OperatorType_name = map[int32]string{
+ 0: "OPERATOR_TYPE_UNKNOWN",
+ 1: "GT",
+ 2: "LT",
+ 3: "EQ",
+ 4: "MATCH",
+ 5: "NON_NIL",
+ 6: "LEN_GT",
+ 7: "LEN_LT",
+ 8: "LEN_EQ",
+ }
+ OperatorType_value = map[string]int32{
+ "OPERATOR_TYPE_UNKNOWN": 0,
+ "GT": 1,
+ "LT": 2,
+ "EQ": 3,
+ "MATCH": 4,
+ "NON_NIL": 5,
+ "LEN_GT": 6,
+ "LEN_LT": 7,
+ "LEN_EQ": 8,
+ }
+)
+
+func (x OperatorType) Enum() *OperatorType {
+ p := new(OperatorType)
+ *p = x
+ return p
+}
+
+func (x OperatorType) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (OperatorType) Descriptor() protoreflect.EnumDescriptor {
+ return file_httpoptions_annotations_proto_enumTypes[4].Descriptor()
+}
+
+func (OperatorType) Type() protoreflect.EnumType {
+ return &file_httpoptions_annotations_proto_enumTypes[4]
+}
+
+func (x OperatorType) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use OperatorType.Descriptor instead.
+func (OperatorType) EnumDescriptor() ([]byte, []int) {
+ return file_httpoptions_annotations_proto_rawDescGZIP(), []int{4}
+}
+
+type FunctionType int32
+
+const (
+ FunctionType_FUNCTION_TYPE_UNKNOWN FunctionType = 0
+ FunctionType_TRIM FunctionType = 1
+)
+
+// Enum value maps for FunctionType.
+var (
+ FunctionType_name = map[int32]string{
+ 0: "FUNCTION_TYPE_UNKNOWN",
+ 1: "TRIM",
+ }
+ FunctionType_value = map[string]int32{
+ "FUNCTION_TYPE_UNKNOWN": 0,
+ "TRIM": 1,
+ }
+)
+
+func (x FunctionType) Enum() *FunctionType {
+ p := new(FunctionType)
+ *p = x
+ return p
+}
+
+func (x FunctionType) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (FunctionType) Descriptor() protoreflect.EnumDescriptor {
+ return file_httpoptions_annotations_proto_enumTypes[5].Descriptor()
+}
+
+func (FunctionType) Type() protoreflect.EnumType {
+ return &file_httpoptions_annotations_proto_enumTypes[5]
+}
+
+func (x FunctionType) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use FunctionType.Descriptor instead.
+func (FunctionType) EnumDescriptor() ([]byte, []int) {
+ return file_httpoptions_annotations_proto_rawDescGZIP(), []int{5}
+}
+
+type ValueType int32
+
+const (
+ ValueType_VALUE_TYPE_UNKNOWN ValueType = 0
+ ValueType_NUMBER ValueType = 1
+ ValueType_STRING ValueType = 2
+ ValueType_OBJ ValueType = 3
+)
+
+// Enum value maps for ValueType.
+var (
+ ValueType_name = map[int32]string{
+ 0: "VALUE_TYPE_UNKNOWN",
+ 1: "NUMBER",
+ 2: "STRING",
+ 3: "OBJ",
+ }
+ ValueType_value = map[string]int32{
+ "VALUE_TYPE_UNKNOWN": 0,
+ "NUMBER": 1,
+ "STRING": 2,
+ "OBJ": 3,
+ }
+)
+
+func (x ValueType) Enum() *ValueType {
+ p := new(ValueType)
+ *p = x
+ return p
+}
+
+func (x ValueType) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (ValueType) Descriptor() protoreflect.EnumDescriptor {
+ return file_httpoptions_annotations_proto_enumTypes[6].Descriptor()
+}
+
+func (ValueType) Type() protoreflect.EnumType {
+ return &file_httpoptions_annotations_proto_enumTypes[6]
+}
+
+func (x ValueType) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use ValueType.Descriptor instead.
+func (ValueType) EnumDescriptor() ([]byte, []int) {
+ return file_httpoptions_annotations_proto_rawDescGZIP(), []int{6}
+}
+
+type ApiMethod struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ LoginNotRequired bool `protobuf:"varint,1,opt,name=login_not_required,json=loginNotRequired,proto3" json:"login_not_required,omitempty"`
+ ClientSignRequired bool `protobuf:"varint,2,opt,name=client_sign_required,json=clientSignRequired,proto3" json:"client_sign_required,omitempty"`
+ HashKey string `protobuf:"bytes,3,opt,name=hash_key,json=hashKey,proto3" json:"hash_key,omitempty"`
+ IsThirdParty bool `protobuf:"varint,4,opt,name=is_third_party,json=isThirdParty,proto3" json:"is_third_party,omitempty"`
+ Timeout string `protobuf:"bytes,5,opt,name=timeout,proto3" json:"timeout,omitempty"`
+ ApiSource ApiSourceType `protobuf:"varint,6,opt,name=api_source,json=apiSource,proto3,enum=janus.api.ApiSourceType" json:"api_source,omitempty"`
+ TokenType AuthTokenType `protobuf:"varint,7,opt,name=token_type,json=tokenType,proto3,enum=janus.api.AuthTokenType" json:"token_type,omitempty"`
+ SpecSourceType SpecSourceType `protobuf:"varint,8,opt,name=spec_source_type,json=specSourceType,proto3,enum=janus.api.SpecSourceType" json:"spec_source_type,omitempty"`
+}
+
+func (x *ApiMethod) Reset() {
+ *x = ApiMethod{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_httpoptions_annotations_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ApiMethod) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ApiMethod) ProtoMessage() {}
+
+func (x *ApiMethod) ProtoReflect() protoreflect.Message {
+ mi := &file_httpoptions_annotations_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ApiMethod.ProtoReflect.Descriptor instead.
+func (*ApiMethod) Descriptor() ([]byte, []int) {
+ return file_httpoptions_annotations_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *ApiMethod) GetLoginNotRequired() bool {
+ if x != nil {
+ return x.LoginNotRequired
+ }
+ return false
+}
+
+func (x *ApiMethod) GetClientSignRequired() bool {
+ if x != nil {
+ return x.ClientSignRequired
+ }
+ return false
+}
+
+func (x *ApiMethod) GetHashKey() string {
+ if x != nil {
+ return x.HashKey
+ }
+ return ""
+}
+
+func (x *ApiMethod) GetIsThirdParty() bool {
+ if x != nil {
+ return x.IsThirdParty
+ }
+ return false
+}
+
+func (x *ApiMethod) GetTimeout() string {
+ if x != nil {
+ return x.Timeout
+ }
+ return ""
+}
+
+func (x *ApiMethod) GetApiSource() ApiSourceType {
+ if x != nil {
+ return x.ApiSource
+ }
+ return ApiSourceType_JANUS_GATEWAY
+}
+
+func (x *ApiMethod) GetTokenType() AuthTokenType {
+ if x != nil {
+ return x.TokenType
+ }
+ return AuthTokenType_JANUS_AUTH_TOKEN
+}
+
+func (x *ApiMethod) GetSpecSourceType() SpecSourceType {
+ if x != nil {
+ return x.SpecSourceType
+ }
+ return SpecSourceType_UNSPECIFIED
+}
+
+type ServiceSpec struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ ServiceId data.ServiceId `protobuf:"varint,1,opt,name=service_id,json=serviceId,proto3,enum=data.ServiceId" json:"service_id,omitempty"`
+ PortName string `protobuf:"bytes,2,opt,name=port_name,json=portName,proto3" json:"port_name,omitempty"`
+ Namespace string `protobuf:"bytes,3,opt,name=namespace,proto3" json:"namespace,omitempty"`
+ GenController bool `protobuf:"varint,4,opt,name=gen_controller,json=genController,proto3" json:"gen_controller,omitempty"`
+ Balancer LoadBalancer `protobuf:"varint,5,opt,name=balancer,proto3,enum=janus.api.LoadBalancer" json:"balancer,omitempty"`
+}
+
+func (x *ServiceSpec) Reset() {
+ *x = ServiceSpec{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_httpoptions_annotations_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ServiceSpec) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ServiceSpec) ProtoMessage() {}
+
+func (x *ServiceSpec) ProtoReflect() protoreflect.Message {
+ mi := &file_httpoptions_annotations_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ServiceSpec.ProtoReflect.Descriptor instead.
+func (*ServiceSpec) Descriptor() ([]byte, []int) {
+ return file_httpoptions_annotations_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *ServiceSpec) GetServiceId() data.ServiceId {
+ if x != nil {
+ return x.ServiceId
+ }
+ return data.ServiceId(0)
+}
+
+func (x *ServiceSpec) GetPortName() string {
+ if x != nil {
+ return x.PortName
+ }
+ return ""
+}
+
+func (x *ServiceSpec) GetNamespace() string {
+ if x != nil {
+ return x.Namespace
+ }
+ return ""
+}
+
+func (x *ServiceSpec) GetGenController() bool {
+ if x != nil {
+ return x.GenController
+ }
+ return false
+}
+
+func (x *ServiceSpec) GetBalancer() LoadBalancer {
+ if x != nil {
+ return x.Balancer
+ }
+ return LoadBalancer_ROUND_ROBIN
+}
+
+type ValidationRule struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Operator OperatorType `protobuf:"varint,1,opt,name=operator,proto3,enum=janus.api.OperatorType" json:"operator,omitempty"`
+ Type ValueType `protobuf:"varint,2,opt,name=type,proto3,enum=janus.api.ValueType" json:"type,omitempty"`
+ Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"`
+ Function FunctionType `protobuf:"varint,4,opt,name=function,proto3,enum=janus.api.FunctionType" json:"function,omitempty"`
+}
+
+func (x *ValidationRule) Reset() {
+ *x = ValidationRule{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_httpoptions_annotations_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ValidationRule) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ValidationRule) ProtoMessage() {}
+
+func (x *ValidationRule) ProtoReflect() protoreflect.Message {
+ mi := &file_httpoptions_annotations_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ValidationRule.ProtoReflect.Descriptor instead.
+func (*ValidationRule) Descriptor() ([]byte, []int) {
+ return file_httpoptions_annotations_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *ValidationRule) GetOperator() OperatorType {
+ if x != nil {
+ return x.Operator
+ }
+ return OperatorType_OPERATOR_TYPE_UNKNOWN
+}
+
+func (x *ValidationRule) GetType() ValueType {
+ if x != nil {
+ return x.Type
+ }
+ return ValueType_VALUE_TYPE_UNKNOWN
+}
+
+func (x *ValidationRule) GetValue() string {
+ if x != nil {
+ return x.Value
+ }
+ return ""
+}
+
+func (x *ValidationRule) GetFunction() FunctionType {
+ if x != nil {
+ return x.Function
+ }
+ return FunctionType_FUNCTION_TYPE_UNKNOWN
+}
+
+type ValidationRules struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Rules []*ValidationRule `protobuf:"bytes,1,rep,name=rules,proto3" json:"rules,omitempty"`
+}
+
+func (x *ValidationRules) Reset() {
+ *x = ValidationRules{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_httpoptions_annotations_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ValidationRules) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ValidationRules) ProtoMessage() {}
+
+func (x *ValidationRules) ProtoReflect() protoreflect.Message {
+ mi := &file_httpoptions_annotations_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ValidationRules.ProtoReflect.Descriptor instead.
+func (*ValidationRules) Descriptor() ([]byte, []int) {
+ return file_httpoptions_annotations_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *ValidationRules) GetRules() []*ValidationRule {
+ if x != nil {
+ return x.Rules
+ }
+ return nil
+}
+
+var file_httpoptions_annotations_proto_extTypes = []protoimpl.ExtensionInfo{
+ {
+ ExtendedType: (*descriptorpb.MethodOptions)(nil),
+ ExtensionType: (*HttpRule)(nil),
+ Field: 108345,
+ Name: "janus.api.http",
+ Tag: "bytes,108345,opt,name=http",
+ Filename: "httpoptions/annotations.proto",
+ },
+ {
+ ExtendedType: (*descriptorpb.MethodOptions)(nil),
+ ExtensionType: (*ApiMethod)(nil),
+ Field: 108361,
+ Name: "janus.api.method",
+ Tag: "bytes,108361,opt,name=method",
+ Filename: "httpoptions/annotations.proto",
+ },
+ {
+ ExtendedType: (*descriptorpb.ServiceOptions)(nil),
+ ExtensionType: (*ServiceSpec)(nil),
+ Field: 108349,
+ Name: "janus.api.service_spec",
+ Tag: "bytes,108349,opt,name=service_spec",
+ Filename: "httpoptions/annotations.proto",
+ },
+ {
+ ExtendedType: (*descriptorpb.FieldOptions)(nil),
+ ExtensionType: (*ValidationRules)(nil),
+ Field: 108102,
+ Name: "janus.api.rules",
+ Tag: "bytes,108102,opt,name=rules",
+ Filename: "httpoptions/annotations.proto",
+ },
+}
+
+// Extension fields to descriptorpb.MethodOptions.
+var (
+ // optional janus.api.HttpRule http = 108345;
+ E_Http = &file_httpoptions_annotations_proto_extTypes[0]
+ // optional janus.api.ApiMethod method = 108361;
+ E_Method = &file_httpoptions_annotations_proto_extTypes[1]
+)
+
+// Extension fields to descriptorpb.ServiceOptions.
+var (
+ // optional janus.api.ServiceSpec service_spec = 108349;
+ E_ServiceSpec = &file_httpoptions_annotations_proto_extTypes[2]
+)
+
+// Extension fields to descriptorpb.FieldOptions.
+var (
+ // optional janus.api.ValidationRules rules = 108102;
+ E_Rules = &file_httpoptions_annotations_proto_extTypes[3]
+)
+
+var File_httpoptions_annotations_proto protoreflect.FileDescriptor
+
+var file_httpoptions_annotations_proto_rawDesc = []byte{
+ 0x0a, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x6e,
+ 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
+ 0x08, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+ 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72,
+ 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x16, 0x68, 0x74, 0x74,
+ 0x70, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x1a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x2f, 0x65,
+ 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfa, 0x02, 0x0a, 0x09, 0x41,
+ 0x70, 0x69, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x6f, 0x67, 0x69,
+ 0x6e, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x4e, 0x6f, 0x74, 0x52, 0x65,
+ 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+ 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x69, 0x67, 0x6e,
+ 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x68, 0x61, 0x73, 0x68,
+ 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x68, 0x61, 0x73, 0x68,
+ 0x4b, 0x65, 0x79, 0x12, 0x24, 0x0a, 0x0e, 0x69, 0x73, 0x5f, 0x74, 0x68, 0x69, 0x72, 0x64, 0x5f,
+ 0x70, 0x61, 0x72, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x73, 0x54,
+ 0x68, 0x69, 0x72, 0x64, 0x50, 0x61, 0x72, 0x74, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d,
+ 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65,
+ 0x6f, 0x75, 0x74, 0x12, 0x36, 0x0a, 0x0a, 0x61, 0x70, 0x69, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63,
+ 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x61,
+ 0x70, 0x69, 0x2e, 0x41, 0x70, 0x69, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65,
+ 0x52, 0x09, 0x61, 0x70, 0x69, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x0a, 0x74,
+ 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32,
+ 0x17, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x54,
+ 0x6f, 0x6b, 0x65, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x54,
+ 0x79, 0x70, 0x65, 0x12, 0x42, 0x0a, 0x10, 0x73, 0x70, 0x65, 0x63, 0x5f, 0x73, 0x6f, 0x75, 0x72,
+ 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e,
+ 0x65, 0x61, 0x73, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x70, 0x65, 0x63, 0x53, 0x6f, 0x75,
+ 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0e, 0x73, 0x70, 0x65, 0x63, 0x53, 0x6f, 0x75,
+ 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xd3, 0x01, 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76,
+ 0x69, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, 0x2e, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69,
+ 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x64, 0x61,
+ 0x74, 0x61, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x52, 0x09, 0x73, 0x65,
+ 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x72, 0x74, 0x5f,
+ 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x72, 0x74,
+ 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63,
+ 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61,
+ 0x63, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x67, 0x65, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
+ 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x67, 0x65, 0x6e, 0x43,
+ 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x08, 0x62, 0x61, 0x6c,
+ 0x61, 0x6e, 0x63, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x65, 0x61,
+ 0x73, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e,
+ 0x63, 0x65, 0x72, 0x52, 0x08, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x22, 0xb7, 0x01,
+ 0x0a, 0x0e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65,
+ 0x12, 0x32, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4f, 0x70,
+ 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72,
+ 0x61, 0x74, 0x6f, 0x72, 0x12, 0x27, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x61,
+ 0x6c, 0x75, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a,
+ 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61,
+ 0x6c, 0x75, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18,
+ 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x61, 0x70, 0x69,
+ 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x66,
+ 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x41, 0x0a, 0x0f, 0x56, 0x61, 0x6c, 0x69, 0x64,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x05, 0x72, 0x75,
+ 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x65, 0x61, 0x73, 0x65,
+ 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+ 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x2a, 0x33, 0x0a, 0x0d, 0x41, 0x70,
+ 0x69, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x45,
+ 0x41, 0x53, 0x45, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x10, 0x00, 0x12, 0x10, 0x0a,
+ 0x0c, 0x4f, 0x50, 0x45, 0x4e, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x10, 0x01, 0x2a,
+ 0x3b, 0x0a, 0x0d, 0x41, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x54, 0x79, 0x70, 0x65,
+ 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x41, 0x53, 0x45, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x5f, 0x54, 0x4f,
+ 0x4b, 0x45, 0x4e, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x41, 0x43,
+ 0x43, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x4f, 0x4b, 0x45, 0x4e, 0x10, 0x01, 0x2a, 0x2a, 0x0a, 0x0e,
+ 0x53, 0x70, 0x65, 0x63, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f,
+ 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12,
+ 0x07, 0x0a, 0x03, 0x57, 0x45, 0x42, 0x10, 0x01, 0x2a, 0x2f, 0x0a, 0x0c, 0x4c, 0x6f, 0x61, 0x64,
+ 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x4f, 0x55, 0x4e,
+ 0x44, 0x5f, 0x52, 0x4f, 0x42, 0x49, 0x4e, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x43, 0x4f, 0x4e,
+ 0x53, 0x49, 0x53, 0x54, 0x45, 0x4e, 0x54, 0x10, 0x01, 0x2a, 0x7d, 0x0a, 0x0c, 0x4f, 0x70, 0x65,
+ 0x72, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x15, 0x4f, 0x50, 0x45,
+ 0x52, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f,
+ 0x57, 0x4e, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x47, 0x54, 0x10, 0x01, 0x12, 0x06, 0x0a, 0x02,
+ 0x4c, 0x54, 0x10, 0x02, 0x12, 0x06, 0x0a, 0x02, 0x45, 0x51, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05,
+ 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x04, 0x12, 0x0b, 0x0a, 0x07, 0x4e, 0x4f, 0x4e, 0x5f, 0x4e,
+ 0x49, 0x4c, 0x10, 0x05, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x45, 0x4e, 0x5f, 0x47, 0x54, 0x10, 0x06,
+ 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x45, 0x4e, 0x5f, 0x4c, 0x54, 0x10, 0x07, 0x12, 0x0a, 0x0a, 0x06,
+ 0x4c, 0x45, 0x4e, 0x5f, 0x45, 0x51, 0x10, 0x08, 0x2a, 0x33, 0x0a, 0x0c, 0x46, 0x75, 0x6e, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x15, 0x46, 0x55, 0x4e, 0x43,
+ 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57,
+ 0x4e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x52, 0x49, 0x4d, 0x10, 0x01, 0x2a, 0x44, 0x0a,
+ 0x09, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x41,
+ 0x4c, 0x55, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e,
+ 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x10, 0x01, 0x12, 0x0a,
+ 0x0a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x4f, 0x42,
+ 0x4a, 0x10, 0x03, 0x3a, 0x48, 0x0a, 0x04, 0x68, 0x74, 0x74, 0x70, 0x12, 0x1e, 0x2e, 0x67, 0x6f,
+ 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65,
+ 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xb9, 0xce, 0x06, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x48,
+ 0x74, 0x74, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x4d, 0x0a,
+ 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64,
+ 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xc9, 0xce, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x13, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x70, 0x69, 0x4d, 0x65,
+ 0x74, 0x68, 0x6f, 0x64, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x3a, 0x5b, 0x0a, 0x0c,
+ 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x12, 0x1f, 0x2e, 0x67,
+ 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53,
+ 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xbd, 0xce,
+ 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x61, 0x70, 0x69,
+ 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0b, 0x73, 0x65,
+ 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x3a, 0x50, 0x0a, 0x05, 0x72, 0x75, 0x6c,
+ 0x65, 0x73, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+ 0x73, 0x18, 0xc6, 0xcc, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x65, 0x61, 0x73, 0x65,
+ 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+ 0x75, 0x6c, 0x65, 0x73, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x42, 0x67, 0x0a, 0x0c, 0x63,
+ 0x6f, 0x6d, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x10, 0x41, 0x6e, 0x6e,
+ 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a,
+ 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x69, 0x6e, 0x63,
+ 0x68, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x65, 0x61, 0x73, 0x65, 0x2d, 0x67, 0x61,
+ 0x74, 0x65, 0x77, 0x61, 0x79, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+ 0x73, 0x3b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0xa2, 0x02, 0x04,
+ 0x45, 0x41, 0x50, 0x49, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_httpoptions_annotations_proto_rawDescOnce sync.Once
+ file_httpoptions_annotations_proto_rawDescData = file_httpoptions_annotations_proto_rawDesc
+)
+
+func file_httpoptions_annotations_proto_rawDescGZIP() []byte {
+ file_httpoptions_annotations_proto_rawDescOnce.Do(func() {
+ file_httpoptions_annotations_proto_rawDescData = protoimpl.X.CompressGZIP(file_httpoptions_annotations_proto_rawDescData)
+ })
+ return file_httpoptions_annotations_proto_rawDescData
+}
+
+var file_httpoptions_annotations_proto_enumTypes = make([]protoimpl.EnumInfo, 7)
+var file_httpoptions_annotations_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
+var file_httpoptions_annotations_proto_goTypes = []interface{}{
+ (ApiSourceType)(0), // 0: janus.api.ApiSourceType
+ (AuthTokenType)(0), // 1: janus.api.AuthTokenType
+ (SpecSourceType)(0), // 2: janus.api.SpecSourceType
+ (LoadBalancer)(0), // 3: janus.api.LoadBalancer
+ (OperatorType)(0), // 4: janus.api.OperatorType
+ (FunctionType)(0), // 5: janus.api.FunctionType
+ (ValueType)(0), // 6: janus.api.ValueType
+ (*ApiMethod)(nil), // 7: janus.api.ApiMethod
+ (*ServiceSpec)(nil), // 8: janus.api.ServiceSpec
+ (*ValidationRule)(nil), // 9: janus.api.ValidationRule
+ (*ValidationRules)(nil), // 10: janus.api.ValidationRules
+ (data.ServiceId)(0), // 11: data.ServiceId
+ (*descriptorpb.MethodOptions)(nil), // 12: google.protobuf.MethodOptions
+ (*descriptorpb.ServiceOptions)(nil), // 13: google.protobuf.ServiceOptions
+ (*descriptorpb.FieldOptions)(nil), // 14: google.protobuf.FieldOptions
+ (*HttpRule)(nil), // 15: janus.api.HttpRule
+}
+var file_httpoptions_annotations_proto_depIdxs = []int32{
+ 0, // 0: janus.api.ApiMethod.api_source:type_name -> janus.api.ApiSourceType
+ 1, // 1: janus.api.ApiMethod.token_type:type_name -> janus.api.AuthTokenType
+ 2, // 2: janus.api.ApiMethod.spec_source_type:type_name -> janus.api.SpecSourceType
+ 11, // 3: janus.api.ServiceSpec.service_id:type_name -> data.ServiceId
+ 3, // 4: janus.api.ServiceSpec.balancer:type_name -> janus.api.LoadBalancer
+ 4, // 5: janus.api.ValidationRule.operator:type_name -> janus.api.OperatorType
+ 6, // 6: janus.api.ValidationRule.type:type_name -> janus.api.ValueType
+ 5, // 7: janus.api.ValidationRule.function:type_name -> janus.api.FunctionType
+ 9, // 8: janus.api.ValidationRules.rules:type_name -> janus.api.ValidationRule
+ 12, // 9: janus.api.http:extendee -> google.protobuf.MethodOptions
+ 12, // 10: janus.api.method:extendee -> google.protobuf.MethodOptions
+ 13, // 11: janus.api.service_spec:extendee -> google.protobuf.ServiceOptions
+ 14, // 12: janus.api.rules:extendee -> google.protobuf.FieldOptions
+ 15, // 13: janus.api.http:type_name -> janus.api.HttpRule
+ 7, // 14: janus.api.method:type_name -> janus.api.ApiMethod
+ 8, // 15: janus.api.service_spec:type_name -> janus.api.ServiceSpec
+ 10, // 16: janus.api.rules:type_name -> janus.api.ValidationRules
+ 17, // [17:17] is the sub-list for method output_type
+ 17, // [17:17] is the sub-list for method input_type
+ 13, // [13:17] is the sub-list for extension type_name
+ 9, // [9:13] is the sub-list for extension extendee
+ 0, // [0:9] is the sub-list for field type_name
+}
+
+func init() { file_httpoptions_annotations_proto_init() }
+func file_httpoptions_annotations_proto_init() {
+ if File_httpoptions_annotations_proto != nil {
+ return
+ }
+ file_httpoptions_http_proto_init()
+ if !protoimpl.UnsafeEnabled {
+ file_httpoptions_annotations_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ApiMethod); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_httpoptions_annotations_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ServiceSpec); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_httpoptions_annotations_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ValidationRule); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_httpoptions_annotations_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ValidationRules); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_httpoptions_annotations_proto_rawDesc,
+ NumEnums: 7,
+ NumMessages: 4,
+ NumExtensions: 4,
+ NumServices: 0,
+ },
+ GoTypes: file_httpoptions_annotations_proto_goTypes,
+ DependencyIndexes: file_httpoptions_annotations_proto_depIdxs,
+ EnumInfos: file_httpoptions_annotations_proto_enumTypes,
+ MessageInfos: file_httpoptions_annotations_proto_msgTypes,
+ ExtensionInfos: file_httpoptions_annotations_proto_extTypes,
+ }.Build()
+ File_httpoptions_annotations_proto = out.File
+ file_httpoptions_annotations_proto_rawDesc = nil
+ file_httpoptions_annotations_proto_goTypes = nil
+ file_httpoptions_annotations_proto_depIdxs = nil
+}
diff --git a/httpoptions/annotations.proto b/httpoptions/annotations.proto
index 1842ee6..01a27cf 100644
--- a/httpoptions/annotations.proto
+++ b/httpoptions/annotations.proto
@@ -12,17 +12,20 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+// See `https://github.com/googleapis/googleapis/blob/master/google/api/annotations.proto`
syntax = "proto3";
-package ease.api;
+package janus.api;
import "google/protobuf/descriptor.proto";
import "httpoptions/http.proto";
import "data/data.proto";
+import "frontend/error.proto";
option java_multiple_files = true;
+option go_package = "github.com/binchencoder/janus-gateway/httpoptions;annotations";
option java_outer_classname = "AnnotationsProto";
-option java_package = "com.ease.api";
+option java_package = "com.janus.api";
option objc_class_prefix = "EAPI";
extend google.protobuf.MethodOptions {
@@ -63,13 +66,13 @@ message ApiMethod {
// Api regist gateway.
enum ApiSourceType {
- EASE_GATEWAY = 0; // ease-gateway apis.
+ JANUS_GATEWAY = 0; // janus-gateway apis.
OPEN_GATEWAY = 1; // open-gateway open apis.
}
// Auth token type.
enum AuthTokenType {
- EASE_AUTH_TOKEN = 0; // ease gateway auth type.
+ JANUS_AUTH_TOKEN = 0; // janus gateway auth type.
BASE_ACCESS_TOKEN = 1; // open platform baseAccessToken.
}
diff --git a/httpoptions/http.pb.go b/httpoptions/http.pb.go
new file mode 100755
index 0000000..1bd6d48
--- /dev/null
+++ b/httpoptions/http.pb.go
@@ -0,0 +1,446 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.27.1
+// protoc v3.19.4
+// source: httpoptions/http.proto
+
+package annotations
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type Http struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Rules []*HttpRule `protobuf:"bytes,1,rep,name=rules,proto3" json:"rules,omitempty"`
+ FullyDecodeReservedExpansion bool `protobuf:"varint,2,opt,name=fully_decode_reserved_expansion,json=fullyDecodeReservedExpansion,proto3" json:"fully_decode_reserved_expansion,omitempty"`
+}
+
+func (x *Http) Reset() {
+ *x = Http{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_httpoptions_http_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Http) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Http) ProtoMessage() {}
+
+func (x *Http) ProtoReflect() protoreflect.Message {
+ mi := &file_httpoptions_http_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Http.ProtoReflect.Descriptor instead.
+func (*Http) Descriptor() ([]byte, []int) {
+ return file_httpoptions_http_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Http) GetRules() []*HttpRule {
+ if x != nil {
+ return x.Rules
+ }
+ return nil
+}
+
+func (x *Http) GetFullyDecodeReservedExpansion() bool {
+ if x != nil {
+ return x.FullyDecodeReservedExpansion
+ }
+ return false
+}
+
+type HttpRule struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Selector string `protobuf:"bytes,1,opt,name=selector,proto3" json:"selector,omitempty"`
+ // Types that are assignable to Pattern:
+ // *HttpRule_Get
+ // *HttpRule_Put
+ // *HttpRule_Post
+ // *HttpRule_Delete
+ // *HttpRule_Patch
+ // *HttpRule_Custom
+ Pattern isHttpRule_Pattern `protobuf_oneof:"pattern"`
+ Body string `protobuf:"bytes,7,opt,name=body,proto3" json:"body,omitempty"`
+ ResponseBody string `protobuf:"bytes,12,opt,name=response_body,json=responseBody,proto3" json:"response_body,omitempty"`
+ AdditionalBindings []*HttpRule `protobuf:"bytes,11,rep,name=additional_bindings,json=additionalBindings,proto3" json:"additional_bindings,omitempty"`
+}
+
+func (x *HttpRule) Reset() {
+ *x = HttpRule{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_httpoptions_http_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *HttpRule) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*HttpRule) ProtoMessage() {}
+
+func (x *HttpRule) ProtoReflect() protoreflect.Message {
+ mi := &file_httpoptions_http_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use HttpRule.ProtoReflect.Descriptor instead.
+func (*HttpRule) Descriptor() ([]byte, []int) {
+ return file_httpoptions_http_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *HttpRule) GetSelector() string {
+ if x != nil {
+ return x.Selector
+ }
+ return ""
+}
+
+func (m *HttpRule) GetPattern() isHttpRule_Pattern {
+ if m != nil {
+ return m.Pattern
+ }
+ return nil
+}
+
+func (x *HttpRule) GetGet() string {
+ if x, ok := x.GetPattern().(*HttpRule_Get); ok {
+ return x.Get
+ }
+ return ""
+}
+
+func (x *HttpRule) GetPut() string {
+ if x, ok := x.GetPattern().(*HttpRule_Put); ok {
+ return x.Put
+ }
+ return ""
+}
+
+func (x *HttpRule) GetPost() string {
+ if x, ok := x.GetPattern().(*HttpRule_Post); ok {
+ return x.Post
+ }
+ return ""
+}
+
+func (x *HttpRule) GetDelete() string {
+ if x, ok := x.GetPattern().(*HttpRule_Delete); ok {
+ return x.Delete
+ }
+ return ""
+}
+
+func (x *HttpRule) GetPatch() string {
+ if x, ok := x.GetPattern().(*HttpRule_Patch); ok {
+ return x.Patch
+ }
+ return ""
+}
+
+func (x *HttpRule) GetCustom() *CustomHttpPattern {
+ if x, ok := x.GetPattern().(*HttpRule_Custom); ok {
+ return x.Custom
+ }
+ return nil
+}
+
+func (x *HttpRule) GetBody() string {
+ if x != nil {
+ return x.Body
+ }
+ return ""
+}
+
+func (x *HttpRule) GetResponseBody() string {
+ if x != nil {
+ return x.ResponseBody
+ }
+ return ""
+}
+
+func (x *HttpRule) GetAdditionalBindings() []*HttpRule {
+ if x != nil {
+ return x.AdditionalBindings
+ }
+ return nil
+}
+
+type isHttpRule_Pattern interface {
+ isHttpRule_Pattern()
+}
+
+type HttpRule_Get struct {
+ Get string `protobuf:"bytes,2,opt,name=get,proto3,oneof"`
+}
+
+type HttpRule_Put struct {
+ Put string `protobuf:"bytes,3,opt,name=put,proto3,oneof"`
+}
+
+type HttpRule_Post struct {
+ Post string `protobuf:"bytes,4,opt,name=post,proto3,oneof"`
+}
+
+type HttpRule_Delete struct {
+ Delete string `protobuf:"bytes,5,opt,name=delete,proto3,oneof"`
+}
+
+type HttpRule_Patch struct {
+ Patch string `protobuf:"bytes,6,opt,name=patch,proto3,oneof"`
+}
+
+type HttpRule_Custom struct {
+ Custom *CustomHttpPattern `protobuf:"bytes,8,opt,name=custom,proto3,oneof"`
+}
+
+func (*HttpRule_Get) isHttpRule_Pattern() {}
+
+func (*HttpRule_Put) isHttpRule_Pattern() {}
+
+func (*HttpRule_Post) isHttpRule_Pattern() {}
+
+func (*HttpRule_Delete) isHttpRule_Pattern() {}
+
+func (*HttpRule_Patch) isHttpRule_Pattern() {}
+
+func (*HttpRule_Custom) isHttpRule_Pattern() {}
+
+type CustomHttpPattern struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"`
+ Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"`
+}
+
+func (x *CustomHttpPattern) Reset() {
+ *x = CustomHttpPattern{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_httpoptions_http_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *CustomHttpPattern) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CustomHttpPattern) ProtoMessage() {}
+
+func (x *CustomHttpPattern) ProtoReflect() protoreflect.Message {
+ mi := &file_httpoptions_http_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use CustomHttpPattern.ProtoReflect.Descriptor instead.
+func (*CustomHttpPattern) Descriptor() ([]byte, []int) {
+ return file_httpoptions_http_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *CustomHttpPattern) GetKind() string {
+ if x != nil {
+ return x.Kind
+ }
+ return ""
+}
+
+func (x *CustomHttpPattern) GetPath() string {
+ if x != nil {
+ return x.Path
+ }
+ return ""
+}
+
+var File_httpoptions_http_proto protoreflect.FileDescriptor
+
+var file_httpoptions_http_proto_rawDesc = []byte{
+ 0x0a, 0x16, 0x68, 0x74, 0x74, 0x70, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x68, 0x74,
+ 0x74, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x61,
+ 0x70, 0x69, 0x22, 0x77, 0x0a, 0x04, 0x48, 0x74, 0x74, 0x70, 0x12, 0x28, 0x0a, 0x05, 0x72, 0x75,
+ 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x65, 0x61, 0x73, 0x65,
+ 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72,
+ 0x75, 0x6c, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x1f, 0x66, 0x75, 0x6c, 0x6c, 0x79, 0x5f, 0x64, 0x65,
+ 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x65, 0x78,
+ 0x70, 0x61, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x66,
+ 0x75, 0x6c, 0x6c, 0x79, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76,
+ 0x65, 0x64, 0x45, 0x78, 0x70, 0x61, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xd6, 0x02, 0x0a, 0x08,
+ 0x48, 0x74, 0x74, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x65,
+ 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x6c, 0x65,
+ 0x63, 0x74, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x03, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x09, 0x48, 0x00, 0x52, 0x03, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x03, 0x70, 0x75, 0x74, 0x18,
+ 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x70, 0x75, 0x74, 0x12, 0x14, 0x0a, 0x04,
+ 0x70, 0x6f, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x70, 0x6f,
+ 0x73, 0x74, 0x12, 0x18, 0x0a, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01,
+ 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x05,
+ 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x70,
+ 0x61, 0x74, 0x63, 0x68, 0x12, 0x35, 0x0a, 0x06, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x18, 0x08,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e,
+ 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x48, 0x74, 0x74, 0x70, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72,
+ 0x6e, 0x48, 0x00, 0x52, 0x06, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x62,
+ 0x6f, 0x64, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12,
+ 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x62, 0x6f, 0x64, 0x79,
+ 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+ 0x42, 0x6f, 0x64, 0x79, 0x12, 0x43, 0x0a, 0x13, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e,
+ 0x61, 0x6c, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28,
+ 0x0b, 0x32, 0x12, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x48, 0x74, 0x74,
+ 0x70, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x12, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61,
+ 0x6c, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x74,
+ 0x74, 0x65, 0x72, 0x6e, 0x22, 0x3b, 0x0a, 0x11, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x48, 0x74,
+ 0x74, 0x70, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e,
+ 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x12, 0x0a,
+ 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74,
+ 0x68, 0x42, 0x63, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x61, 0x70,
+ 0x69, 0x42, 0x09, 0x48, 0x74, 0x74, 0x70, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3c,
+ 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x69, 0x6e, 0x63, 0x68,
+ 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x65, 0x61, 0x73, 0x65, 0x2d, 0x67, 0x61, 0x74,
+ 0x65, 0x77, 0x61, 0x79, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+ 0x3b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0xf8, 0x01, 0x01, 0xa2,
+ 0x02, 0x04, 0x45, 0x41, 0x50, 0x49, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_httpoptions_http_proto_rawDescOnce sync.Once
+ file_httpoptions_http_proto_rawDescData = file_httpoptions_http_proto_rawDesc
+)
+
+func file_httpoptions_http_proto_rawDescGZIP() []byte {
+ file_httpoptions_http_proto_rawDescOnce.Do(func() {
+ file_httpoptions_http_proto_rawDescData = protoimpl.X.CompressGZIP(file_httpoptions_http_proto_rawDescData)
+ })
+ return file_httpoptions_http_proto_rawDescData
+}
+
+var file_httpoptions_http_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
+var file_httpoptions_http_proto_goTypes = []interface{}{
+ (*Http)(nil), // 0: janus.api.Http
+ (*HttpRule)(nil), // 1: janus.api.HttpRule
+ (*CustomHttpPattern)(nil), // 2: janus.api.CustomHttpPattern
+}
+var file_httpoptions_http_proto_depIdxs = []int32{
+ 1, // 0: janus.api.Http.rules:type_name -> janus.api.HttpRule
+ 2, // 1: janus.api.HttpRule.custom:type_name -> janus.api.CustomHttpPattern
+ 1, // 2: janus.api.HttpRule.additional_bindings:type_name -> janus.api.HttpRule
+ 3, // [3:3] is the sub-list for method output_type
+ 3, // [3:3] is the sub-list for method input_type
+ 3, // [3:3] is the sub-list for extension type_name
+ 3, // [3:3] is the sub-list for extension extendee
+ 0, // [0:3] is the sub-list for field type_name
+}
+
+func init() { file_httpoptions_http_proto_init() }
+func file_httpoptions_http_proto_init() {
+ if File_httpoptions_http_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_httpoptions_http_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Http); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_httpoptions_http_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*HttpRule); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_httpoptions_http_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*CustomHttpPattern); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ file_httpoptions_http_proto_msgTypes[1].OneofWrappers = []interface{}{
+ (*HttpRule_Get)(nil),
+ (*HttpRule_Put)(nil),
+ (*HttpRule_Post)(nil),
+ (*HttpRule_Delete)(nil),
+ (*HttpRule_Patch)(nil),
+ (*HttpRule_Custom)(nil),
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_httpoptions_http_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 3,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_httpoptions_http_proto_goTypes,
+ DependencyIndexes: file_httpoptions_http_proto_depIdxs,
+ MessageInfos: file_httpoptions_http_proto_msgTypes,
+ }.Build()
+ File_httpoptions_http_proto = out.File
+ file_httpoptions_http_proto_rawDesc = nil
+ file_httpoptions_http_proto_goTypes = nil
+ file_httpoptions_http_proto_depIdxs = nil
+}
diff --git a/httpoptions/http.proto b/httpoptions/http.proto
index 9c32667..499627e 100644
--- a/httpoptions/http.proto
+++ b/httpoptions/http.proto
@@ -11,34 +11,35 @@
// 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.
-//
-
+// See `https://github.com/googleapis/googleapis/blob/master/google/api/http.proto`
syntax = "proto3";
-package ease.api;
+package janus.api;
+option cc_enable_arenas = true;
+option go_package = "github.com/binchencoder/janus-gateway/httpoptions;annotations";
option java_multiple_files = true;
option java_outer_classname = "HttpProto";
-option java_package = "com.ease.api";
+option java_package = "com.janus.api";
option objc_class_prefix = "EAPI";
// Defines the HTTP configuration for an API service. It contains a list of
// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method
// to one or more HTTP REST API methods.
message Http {
- // A list of HTTP configuration rules that apply to individual API methods.
- //
- // **NOTE:** All service configuration rules follow "last one wins" order.
- repeated HttpRule rules = 1;
-
- // When set to true, URL path parameters will be fully URI-decoded except in
- // cases of single segment matches in reserved expansion, where "%2F" will be
- // left encoded.
- //
- // The default behavior is to not decode RFC 6570 reserved characters in multi
- // segment matches.
- bool fully_decode_reserved_expansion = 2;
-}
+ // A list of HTTP configuration rules that apply to individual API methods.
+ //
+ // **NOTE:** All service configuration rules follow "last one wins" order.
+ repeated HttpRule rules = 1;
+
+ // When set to true, URL path parameters will be fully URI-decoded except in
+ // cases of single segment matches in reserved expansion, where "%2F" will be
+ // left encoded.
+ //
+ // The default behavior is to not decode RFC 6570 reserved characters in multi
+ // segment matches.
+ bool fully_decode_reserved_expansion = 2;
+ }
// # gRPC Transcoding
//
diff --git a/httpoptions/pom.xml b/httpoptions/pom.xml
new file mode 100755
index 0000000..7f72b56
--- /dev/null
+++ b/httpoptions/pom.xml
@@ -0,0 +1,158 @@
+
+
+ 4.0.0
+ com.binchencoder.gateway
+ janus-options-protos
+ jar
+ 1.0-SNAPSHOT
+
+
+ Binchencoder
+ https://www.github.com/binchencoder
+
+
+
+ mvn-repo
+ https://raw.github.com/binchencoder/mvn-repo/master
+
+ true
+ always
+
+
+
+
+
+
+ 1.18.0
+
+ 3.6.1
+
+ 0.0.3
+
+ github
+
+
+
+
+ io.grpc
+ grpc-protobuf
+ ${grpc.version}
+ provided
+
+
+ io.grpc
+ grpc-stub
+ ${grpc.version}
+ provided
+
+
+
+ com.google.protobuf
+ protobuf-java
+ ${protobuf.version}
+ provided
+
+
+ com.google.api.grpc
+ googleapis-common-protos
+ ${googleapis.version}
+ provided
+
+
+ io.grpc
+ grpc-stub
+
+
+
+
+
+ com.binchencoder.gateway
+ data-proto
+ 1.0-SNAPSHOT
+
+
+ com.binchencoder.gateway
+ frontend-proto
+ 1.0-SNAPSHOT
+
+
+
+
+
+
+ kr.motd.maven
+ os-maven-plugin
+ 1.4.1.Final
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+ 2.8.1
+
+ internal.repo::default::file://${project.build.directory}/mvn-repo
+
+
+
+ com.github.github
+ site-maven-plugin
+ 0.12
+
+ Maven artifacts for ${project.version}
+ true
+ ${project.build.directory}/mvn-repo
+ refs/heads/master
+ true
+
+ **/*
+
+ mvn-repo
+ binchencoder
+
+
+
+
+ site
+
+ deploy
+
+
+
+
+ org.xolstice.maven.plugins
+ protobuf-maven-plugin
+ 0.5.0
+
+
+ com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}
+ grpc-java
+ io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
+ ../
+
+ httpoptions/*.proto
+
+
+
+
+
+ compile
+ compile-custom
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/integrate/BUILD.bazel b/integrate/BUILD.bazel
index 93b83c5..55c5ca2 100755
--- a/integrate/BUILD.bazel
+++ b/integrate/BUILD.bazel
@@ -8,21 +8,21 @@ go_library(
["*.go"],
exclude = ["*_test.go"],
),
- importpath = "github.com/binchencoder/ease-gateway/integrate",
+ importpath = "github.com/binchencoder/janus-gateway/integrate",
deps = [
- "//httpoptions:go_default_library",
- "//gateway/runtime:go_default_library",
+ "//httpoptions",
+ "//gateway/runtime",
"//integrate/metrics:go_default_library",
+ "//util:go_default_library",
"@com_github_binchencoder_gateway_proto//data:go_default_library",
"@com_github_binchencoder_gateway_proto//frontend:go_default_library",
- "//util:go_default_library",
"@com_github_binchencoder_letsgo//grpc:go_default_library",
"@com_github_binchencoder_letsgo//trace:go_default_library",
- "@com_github_golang_protobuf//proto:go_default_library",
"@com_github_klauspost_compress//gzip:go_default_library",
"@org_golang_google_grpc//:go_default_library",
"@org_golang_google_grpc//codes:go_default_library",
"@org_golang_google_grpc//metadata:go_default_library",
+ "@org_golang_google_protobuf//proto:go_default_library",
"@org_golang_x_net//context:go_default_library",
],
)
diff --git a/integrate/hook.go b/integrate/hook.go
index 6618fdd..31020f1 100755
--- a/integrate/hook.go
+++ b/integrate/hook.go
@@ -7,16 +7,16 @@ import (
"strconv"
"time"
- "github.com/golang/protobuf/proto"
"golang.org/x/net/context"
gr "google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
+ "google.golang.org/protobuf/proto"
- options "github.com/binchencoder/ease-gateway/httpoptions"
- "github.com/binchencoder/ease-gateway/gateway/runtime"
- "github.com/binchencoder/ease-gateway/integrate/metrics"
- "github.com/binchencoder/ease-gateway/util"
+ "github.com/binchencoder/janus-gateway/gateway/runtime"
+ options "github.com/binchencoder/janus-gateway/httpoptions"
+ "github.com/binchencoder/janus-gateway/integrate/metrics"
+ "github.com/binchencoder/janus-gateway/util"
"github.com/binchencoder/letsgo/grpc"
"github.com/binchencoder/letsgo/trace"
@@ -41,7 +41,7 @@ var (
)
// gatewayHook implements interface GatewayServiceHook in package
-// github.com/binchencoder/ease-gateway/gateway/runtime.
+// github.com/binchencoder/janus-gateway/gateway/runtime.
type gatewayHook struct {
mux *runtime.ServeMux
host string
@@ -149,13 +149,13 @@ func NewGatewayHook(mux *runtime.ServeMux, host string) runtime.GatewayServiceHo
}
}
-// addMetrics add metrics to prometheus for ease-gateway.
+// addMetrics add metrics to prometheus for janus-gateway.
func addMetrics(ctx context.Context, svc *runtime.Service, m *runtime.Method, code codes.Code, startTime time.Time, clt string) float64 {
rp := &metrics.ReporterParam{StartTime: startTime, ServiceName: svc.Spec.GetServiceName(), Url: m.Path, HttpMethod: m.HttpMethod, Code: strconv.FormatUint(uint64(code), 10), Client: clt}
return rp.RequestComplete()
}
-// getClient returns client value who request ease-gateway from Md.
+// getClient returns client value who request janus-gateway from Md.
func getClientFroMd(md metadata.MD) string {
if s, ok := md[XSource]; ok && len(s) > 0 && s[0] != ResourceClient {
return s[0]
diff --git a/integrate/hookexternal.go b/integrate/hookexternal.go
index 1bf12d0..a51ed42 100644
--- a/integrate/hookexternal.go
+++ b/integrate/hookexternal.go
@@ -1,4 +1,4 @@
-// Note: this file is for ease-gateway which are exposed to external users.
+// Note: this file is for janus-gateway which are exposed to external users.
package integrate
@@ -12,9 +12,9 @@ import (
gr "google.golang.org/grpc"
"google.golang.org/grpc/codes"
- "github.com/binchencoder/ease-gateway/gateway/runtime"
- options "github.com/binchencoder/ease-gateway/httpoptions"
- "github.com/binchencoder/ease-gateway/util"
+ "github.com/binchencoder/janus-gateway/gateway/runtime"
+ options "github.com/binchencoder/janus-gateway/httpoptions"
+ "github.com/binchencoder/janus-gateway/util"
vexpb "github.com/binchencoder/gateway-proto/data"
fpb "github.com/binchencoder/gateway-proto/frontend"
"github.com/binchencoder/letsgo/grpc"
@@ -217,7 +217,7 @@ func verifyHeader(ctx context.Context, header http.Header, svc *runtime.Service,
return nil
}
-// getClient returns client value who request ease-gateway from header.
+// getClient returns client value who request janus-gateway from header.
func getClientFromHeader(header http.Header) string {
xs := header.Get(XSource)
cl := header.Get(XClient)
@@ -326,11 +326,11 @@ func getHeader(h http.Header, key string) string {
}
func isGatewayApi(api *runtime.Method) bool {
- if runtime.CallerServiceId == vexpb.ServiceId_EASE_GATEWAY {
- return api.ApiSource == options.ApiSourceType_EASE_GATEWAY
+ if runtime.CallerServiceId == vexpb.ServiceId_JANUS_GATEWAY {
+ return api.ApiSource == options.ApiSourceType_JANUS_GATEWAY
}
- // else if runtime.CallerServiceId == vexpb.ServiceId_EASE_OPEN_GATEWAY {
- // return api.ApiSource == options.ApiSourceType_EASE_OPEN_GATEWAY ||
+ // else if runtime.CallerServiceId == vexpb.ServiceId_JANUS_OPEN_GATEWAY {
+ // return api.ApiSource == options.ApiSourceType_JANUS_OPEN_GATEWAY ||
// api.ApiSource == options.ApiSourceType_OPEN_GATEWAY_PRIVATE
// }
return false
diff --git a/integrate/metrics/BUILD b/integrate/metrics/BUILD
index a068559..dca50df 100755
--- a/integrate/metrics/BUILD
+++ b/integrate/metrics/BUILD
@@ -5,7 +5,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["reporter.go"],
- importpath = "github.com/binchencoder/ease-gateway/integrate/metrics",
+ importpath = "github.com/binchencoder/janus-gateway/integrate/metrics",
deps = [
"@com_github_binchencoder_letsgo//time:go_default_library",
"@com_github_prometheus_client_golang//prometheus:go_default_library",
diff --git a/integrate/metrics/reporter.go b/integrate/metrics/reporter.go
index 5f9f716..9de191e 100755
--- a/integrate/metrics/reporter.go
+++ b/integrate/metrics/reporter.go
@@ -9,7 +9,7 @@ import (
)
var (
- // Create a histogram for record response latency (milliseconds) of ease-gateway.
+ // Create a histogram for record response latency (milliseconds) of janus-gateway.
// And it will generate additional metric, for example:
// gateway_http_response_ms_count, it is the total number of request.
gatewayHandledHistogram = prometheus.NewHistogramVec(
@@ -23,7 +23,7 @@ var (
[]string{"client", "service_name", "url", "http_method", "code"},
)
- // Create a counter for record total system errors of ease-gateway.
+ // Create a counter for record total system errors of janus-gateway.
gatewayErrCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: "gateway",
diff --git a/integrate/middleware.go b/integrate/middleware.go
index 6c3fb21..40db393 100644
--- a/integrate/middleware.go
+++ b/integrate/middleware.go
@@ -4,7 +4,7 @@ import (
"flag"
"net/http"
- "github.com/binchencoder/ease-gateway/gateway/runtime"
+ "github.com/binchencoder/janus-gateway/gateway/runtime"
)
var (
diff --git a/proto/examples/BUILD.bazel b/proto/examplepb/BUILD.bazel
similarity index 67%
rename from proto/examples/BUILD.bazel
rename to proto/examplepb/BUILD.bazel
index a0099ed..4b2b9fe 100644
--- a/proto/examples/BUILD.bazel
+++ b/proto/examplepb/BUILD.bazel
@@ -1,6 +1,7 @@
+load("@rules_proto//proto:defs.bzl", "proto_library")
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
-load("//gateway/protoc-gen-swagger:defs.bzl", "protoc_gen_swagger")
+load("//gateway/protoc-gen-openapiv2:defs.bzl", "protoc_gen_openapiv2")
package(default_visibility = ["//visibility:public"])
@@ -25,39 +26,43 @@ proto_library(
go_proto_library(
name = "examplepb_go_proto",
compilers = [
- "@io_bazel_rules_go//proto:go_grpc",
+ "//:go_apiv2",
+ "//:go_grpc",
"//gateway/protoc-gen-grpc-gateway:go_gen_grpc_gateway", # keep
],
- importpath = "github.com/binchencoder/ease-gateway/proto/examples",
+ importpath = "github.com/binchencoder/janus-gateway/proto/examplepb",
proto = ":examplepb_proto",
deps = [
- "//httpoptions:go_default_library",
- "//gateway/runtime:go_default_library",
+ "//httpoptions",
+ "//gateway/runtime",
+ "//gateway/protoc-gen-openapiv2/options",
"@com_github_binchencoder_letsgo//grpc:go_default_library",
- "@com_github_binchencoder_skylb_api//balancer:go_default_library",
"@com_github_binchencoder_skylb_api//client:go_default_library",
- "@com_github_binchencoder_skylb_api//client/option:go_default_library",
"@com_github_binchencoder_skylb_api//proto:go_default_library",
- "@org_golang_google_grpc//naming:go_default_library",
],
)
go_library(
- name = "go_default_library",
+ name = "examplepb",
embed = [":examplepb_go_proto"],
- importpath = "github.com/binchencoder/ease-gateway/proto/examples",
+ importpath = "github.com/binchencoder/janus-gateway/proto/examplepb",
deps = [
- "//httpoptions:go_default_library",
- "//gateway/runtime:go_default_library",
+ "//httpoptions",
+ "//gateway/runtime",
+ "@com_github_grpc_ecosystem_grpc_gateway//utilities",
"@com_github_binchencoder_gateway_proto//data:go_default_library",
"@com_github_binchencoder_gateway_proto//frontend:go_default_library",
- "@com_github_binchencoder_skylb_api//balancer:go_default_library",
"@com_github_binchencoder_skylb_api//client:go_default_library",
],
)
-protoc_gen_swagger(
- name = "expamplepb_protoc_gen_swagger",
+protoc_gen_openapiv2(
+ name = "examplepb_protoc_gen_openapiv2",
proto = ":examplepb_proto",
single_output = False, # Outputs a single swagger.json file.
+)
+
+alias(
+ name = "go_default_library",
+ actual = ":examplepb",
)
\ No newline at end of file
diff --git a/proto/examples/echo_service.proto b/proto/examplepb/echo_service.proto
similarity index 61%
rename from proto/examples/echo_service.proto
rename to proto/examplepb/echo_service.proto
index 8331929..ebb4c08 100644
--- a/proto/examples/echo_service.proto
+++ b/proto/examplepb/echo_service.proto
@@ -1,14 +1,11 @@
syntax = "proto3";
-option go_package = "proto";
-option java_package = "com.binchencoder.easegw.examples";
-option java_outer_classname = "ExamplesProto";
+option go_package = "github.com/binchencoder/janus-gateway/gateway/proto/examplepb";
+
+package grpc.gateway.proto.examplepb;
-// Echo Service
-//
-// Echo Service API consists of a single service which returns
-// a message.
-package examples;
+option java_package = "com.binchencoder.janusgw.examplepb";
+option java_outer_classname = "ExamplesProto";
// import "google/api/annotations.proto";
import "httpoptions/annotations.proto";
@@ -25,38 +22,36 @@ message Embedded {
message SimpleMessage {
// Id represents the message identifier.
string id = 1
-// [
-// (ease.api.rules) = {
-// rules: {
-// type: STRING,
-// operator: NON_NIL,
-// },
-// rules: {
-// type: STRING,
-// function: TRIM,
-// operator: LEN_GT,
-// value: "2",
-// },
-// rules: {
-// type: STRING,
-// function: TRIM,
-// operator: LEN_LT,
-// value: "61",
-// }
-// }
-// ]
- ;
+ [
+ (janus.api.rules) = {
+ rules: {
+ type: STRING,
+ operator: NON_NIL,
+ },
+ rules: {
+ type: STRING,
+ function: TRIM,
+ operator: LEN_GT,
+ value: "2",
+ },
+ rules: {
+ type: STRING,
+ function: TRIM,
+ operator: LEN_LT,
+ value: "61",
+ }
+ }
+ ];
int64 num = 2
-// [
-// (ease.api.rules) = {
-// rules: {
-// type: NUMBER,
-// operator: GT,
-// value: "0",
-// }
-// }
-// ]
- ;
+ [
+ (janus.api.rules) = {
+ rules: {
+ type: NUMBER,
+ operator: GT,
+ value: "0",
+ }
+ }
+ ];
oneof code {
int64 line_num = 3;
string lang = 4;
@@ -70,8 +65,8 @@ message SimpleMessage {
// Echo service responds to incoming echo requests.
service EchoService {
- option (ease.api.service_spec) = {
- service_id: CUSTOM_EASE_GATEWAY_TEST
+ option (janus.api.service_spec) = {
+ service_id: CUSTOM_JANUS_GATEWAY_TEST
port_name : "grpc"
namespace : "default"
gen_controller: true
@@ -82,7 +77,7 @@ service EchoService {
// The message posted as the id parameter will also be
// returned.
rpc Echo(SimpleMessage) returns (SimpleMessage) {
- option (ease.api.http) = {
+ option (janus.api.http) = {
post: "/v1/example/echo/{id}"
additional_bindings {
get: "/v1/example/echo/{id}/{num}"
@@ -100,14 +95,14 @@ service EchoService {
}
// EchoBody method receives a simple message and returns it.
rpc EchoBody(SimpleMessage) returns (SimpleMessage) {
- option (ease.api.http) = {
+ option (janus.api.http) = {
post: "/v1/example/echo_body"
body: "*"
};
}
// EchoDelete method receives a simple message and returns it.
rpc EchoDelete(SimpleMessage) returns (SimpleMessage) {
- option (ease.api.http) = {
+ option (janus.api.http) = {
delete: "/v1/example/echo_delete"
};
}
diff --git a/proto/examples/echo_service.swagger.json b/proto/examplepb/echo_service.swagger.json
similarity index 93%
rename from proto/examples/echo_service.swagger.json
rename to proto/examplepb/echo_service.swagger.json
index d6f97ac..111bd6e 100755
--- a/proto/examples/echo_service.swagger.json
+++ b/proto/examplepb/echo_service.swagger.json
@@ -1,14 +1,9 @@
{
"swagger": "2.0",
"info": {
- "title": "Echo Service",
- "description": "Echo Service API consists of a single service which returns\na message.",
+ "title": "proto/examples/internal/echo_service.proto",
"version": "version not set"
},
- "schemes": [
- "http",
- "https"
- ],
"consumes": [
"application/json"
],
@@ -20,7 +15,7 @@
"post": {
"summary": "Echo method receives a simple message and returns it.",
"description": "The message posted as the id parameter will also be\nreturned.",
- "operationId": "Echo",
+ "operationId": "EchoService_Echo",
"responses": {
"200": {
"description": "A successful response.",
@@ -47,7 +42,7 @@
"get": {
"summary": "Echo method receives a simple message and returns it.",
"description": "The message posted as the id parameter will also be\nreturned.",
- "operationId": "Echo2",
+ "operationId": "EchoService_Echo2",
"responses": {
"200": {
"description": "A successful response.",
@@ -72,7 +67,7 @@
"format": "int64"
},
{
- "name": "line_num",
+ "name": "lineNum",
"in": "query",
"required": false,
"type": "string",
@@ -127,7 +122,7 @@
"get": {
"summary": "Echo method receives a simple message and returns it.",
"description": "The message posted as the id parameter will also be\nreturned.",
- "operationId": "Echo3",
+ "operationId": "EchoService_Echo3",
"responses": {
"200": {
"description": "A successful response.",
@@ -158,7 +153,7 @@
"type": "string"
},
{
- "name": "line_num",
+ "name": "lineNum",
"in": "query",
"required": false,
"type": "string",
@@ -203,11 +198,11 @@
]
}
},
- "/v1/example/echo1/{id}/{line_num}/{status.note}": {
+ "/v1/example/echo1/{id}/{lineNum}/{status.note}": {
"get": {
"summary": "Echo method receives a simple message and returns it.",
"description": "The message posted as the id parameter will also be\nreturned.",
- "operationId": "Echo4",
+ "operationId": "EchoService_Echo4",
"responses": {
"200": {
"description": "A successful response.",
@@ -225,7 +220,7 @@
"type": "string"
},
{
- "name": "line_num",
+ "name": "lineNum",
"in": "path",
"required": true,
"type": "string",
@@ -281,7 +276,7 @@
"get": {
"summary": "Echo method receives a simple message and returns it.",
"description": "The message posted as the id parameter will also be\nreturned.",
- "operationId": "Echo5",
+ "operationId": "EchoService_Echo5",
"responses": {
"200": {
"description": "A successful response.",
@@ -312,7 +307,7 @@
"format": "int64"
},
{
- "name": "line_num",
+ "name": "lineNum",
"in": "query",
"required": false,
"type": "string",
@@ -354,7 +349,7 @@
"/v1/example/echo_body": {
"post": {
"summary": "EchoBody method receives a simple message and returns it.",
- "operationId": "EchoBody",
+ "operationId": "EchoService_EchoBody",
"responses": {
"200": {
"description": "A successful response.",
@@ -381,7 +376,7 @@
"/v1/example/echo_delete": {
"delete": {
"summary": "EchoDelete method receives a simple message and returns it.",
- "operationId": "EchoDelete",
+ "operationId": "EchoService_EchoDelete",
"responses": {
"200": {
"description": "A successful response.",
@@ -406,7 +401,7 @@
"format": "int64"
},
{
- "name": "line_num",
+ "name": "lineNum",
"in": "query",
"required": false,
"type": "string",
@@ -479,10 +474,20 @@
"type": "string",
"rules": [
{
- "operator": 3,
+ "operator": 5,
+ "type": 2
+ },
+ {
+ "operator": 6,
"type": 2,
"value": "2",
"function": 1
+ },
+ {
+ "operator": 7,
+ "type": 2,
+ "value": "61",
+ "function": 1
}
],
"description": "Id represents the message identifier."
@@ -498,7 +503,7 @@
}
]
},
- "line_num": {
+ "lineNum": {
"type": "string",
"format": "int64"
},
diff --git a/proto/examples/pom.xml b/proto/examplepb/pom.xml
similarity index 81%
rename from proto/examples/pom.xml
rename to proto/examplepb/pom.xml
index 9cd89ee..95d132e 100755
--- a/proto/examples/pom.xml
+++ b/proto/examplepb/pom.xml
@@ -8,13 +8,22 @@
- com.binchencoder.easegw
- easegw-proto
+ com.binchencoder.gateway
+ janus-proto
1.0-SNAPSHOT
../pom.xml
+
+ com.binchencoder.gateway
+ janus-options-protos
+
+
+ com.binchencoder.gateway
+ data-proto
+
+
io.grpc
grpc-protobuf
@@ -32,11 +41,6 @@
com.google.api.grpc
googleapis-common-protos
-
-
- com.binchencoder.gateway
- data-proto
-
@@ -49,12 +53,10 @@
org.xolstice.maven.plugins
protobuf-maven-plugin
- ../../../
+ ../
- ease-gateway/proto/examples/*.proto
- ease-gateway/proto/examples/*/*.proto
- ease-gateway/gateway/options/http.proto
- ease-gateway/gateway/options/annotations.proto
+ proto/examples/internal/*.proto
+ proto/examples/internal/*/*.proto
diff --git a/proto/examples/echo_service.pb.go b/proto/examples/echo_service.pb.go
deleted file mode 100755
index 6848915..0000000
--- a/proto/examples/echo_service.pb.go
+++ /dev/null
@@ -1,434 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: proto/examples/echo_service.proto
-
-package proto
-
-import (
- _ "github.com/binchencoder/ease-gateway/httpoptions"
- context "context"
- fmt "fmt"
- proto "github.com/golang/protobuf/proto"
- grpc "google.golang.org/grpc"
- 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 Embedded struct {
- // Types that are valid to be assigned to Mark:
- // *Embedded_Progress
- // *Embedded_Note
- Mark isEmbedded_Mark `protobuf_oneof:"mark"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
-}
-
-func (m *Embedded) Reset() { *m = Embedded{} }
-func (m *Embedded) String() string { return proto.CompactTextString(m) }
-func (*Embedded) ProtoMessage() {}
-func (*Embedded) Descriptor() ([]byte, []int) {
- return fileDescriptor_50dd28de91ad0693, []int{0}
-}
-
-func (m *Embedded) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Embedded.Unmarshal(m, b)
-}
-func (m *Embedded) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Embedded.Marshal(b, m, deterministic)
-}
-func (m *Embedded) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Embedded.Merge(m, src)
-}
-func (m *Embedded) XXX_Size() int {
- return xxx_messageInfo_Embedded.Size(m)
-}
-func (m *Embedded) XXX_DiscardUnknown() {
- xxx_messageInfo_Embedded.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Embedded proto.InternalMessageInfo
-
-type isEmbedded_Mark interface {
- isEmbedded_Mark()
-}
-
-type Embedded_Progress struct {
- Progress int64 `protobuf:"varint,1,opt,name=progress,proto3,oneof"`
-}
-
-type Embedded_Note struct {
- Note string `protobuf:"bytes,2,opt,name=note,proto3,oneof"`
-}
-
-func (*Embedded_Progress) isEmbedded_Mark() {}
-
-func (*Embedded_Note) isEmbedded_Mark() {}
-
-func (m *Embedded) GetMark() isEmbedded_Mark {
- if m != nil {
- return m.Mark
- }
- return nil
-}
-
-func (m *Embedded) GetProgress() int64 {
- if x, ok := m.GetMark().(*Embedded_Progress); ok {
- return x.Progress
- }
- return 0
-}
-
-func (m *Embedded) GetNote() string {
- if x, ok := m.GetMark().(*Embedded_Note); ok {
- return x.Note
- }
- return ""
-}
-
-// XXX_OneofWrappers is for the internal use of the proto package.
-func (*Embedded) XXX_OneofWrappers() []interface{} {
- return []interface{}{
- (*Embedded_Progress)(nil),
- (*Embedded_Note)(nil),
- }
-}
-
-type SimpleMessage struct {
- Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
- Num int64 `protobuf:"varint,2,opt,name=num,proto3" json:"num,omitempty"`
- // Types that are valid to be assigned to Code:
- // *SimpleMessage_LineNum
- // *SimpleMessage_Lang
- Code isSimpleMessage_Code `protobuf_oneof:"code"`
- Status *Embedded `protobuf:"bytes,5,opt,name=status,proto3" json:"status,omitempty"`
- // Types that are valid to be assigned to Ext:
- // *SimpleMessage_En
- // *SimpleMessage_No
- Ext isSimpleMessage_Ext `protobuf_oneof:"ext"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
-}
-
-func (m *SimpleMessage) Reset() { *m = SimpleMessage{} }
-func (m *SimpleMessage) String() string { return proto.CompactTextString(m) }
-func (*SimpleMessage) ProtoMessage() {}
-func (*SimpleMessage) Descriptor() ([]byte, []int) {
- return fileDescriptor_50dd28de91ad0693, []int{1}
-}
-
-func (m *SimpleMessage) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_SimpleMessage.Unmarshal(m, b)
-}
-func (m *SimpleMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_SimpleMessage.Marshal(b, m, deterministic)
-}
-func (m *SimpleMessage) XXX_Merge(src proto.Message) {
- xxx_messageInfo_SimpleMessage.Merge(m, src)
-}
-func (m *SimpleMessage) XXX_Size() int {
- return xxx_messageInfo_SimpleMessage.Size(m)
-}
-func (m *SimpleMessage) XXX_DiscardUnknown() {
- xxx_messageInfo_SimpleMessage.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_SimpleMessage proto.InternalMessageInfo
-
-func (m *SimpleMessage) GetId() string {
- if m != nil {
- return m.Id
- }
- return ""
-}
-
-func (m *SimpleMessage) GetNum() int64 {
- if m != nil {
- return m.Num
- }
- return 0
-}
-
-type isSimpleMessage_Code interface {
- isSimpleMessage_Code()
-}
-
-type SimpleMessage_LineNum struct {
- LineNum int64 `protobuf:"varint,3,opt,name=line_num,json=lineNum,proto3,oneof"`
-}
-
-type SimpleMessage_Lang struct {
- Lang string `protobuf:"bytes,4,opt,name=lang,proto3,oneof"`
-}
-
-func (*SimpleMessage_LineNum) isSimpleMessage_Code() {}
-
-func (*SimpleMessage_Lang) isSimpleMessage_Code() {}
-
-func (m *SimpleMessage) GetCode() isSimpleMessage_Code {
- if m != nil {
- return m.Code
- }
- return nil
-}
-
-func (m *SimpleMessage) GetLineNum() int64 {
- if x, ok := m.GetCode().(*SimpleMessage_LineNum); ok {
- return x.LineNum
- }
- return 0
-}
-
-func (m *SimpleMessage) GetLang() string {
- if x, ok := m.GetCode().(*SimpleMessage_Lang); ok {
- return x.Lang
- }
- return ""
-}
-
-func (m *SimpleMessage) GetStatus() *Embedded {
- if m != nil {
- return m.Status
- }
- return nil
-}
-
-type isSimpleMessage_Ext interface {
- isSimpleMessage_Ext()
-}
-
-type SimpleMessage_En struct {
- En int64 `protobuf:"varint,6,opt,name=en,proto3,oneof"`
-}
-
-type SimpleMessage_No struct {
- No *Embedded `protobuf:"bytes,7,opt,name=no,proto3,oneof"`
-}
-
-func (*SimpleMessage_En) isSimpleMessage_Ext() {}
-
-func (*SimpleMessage_No) isSimpleMessage_Ext() {}
-
-func (m *SimpleMessage) GetExt() isSimpleMessage_Ext {
- if m != nil {
- return m.Ext
- }
- return nil
-}
-
-func (m *SimpleMessage) GetEn() int64 {
- if x, ok := m.GetExt().(*SimpleMessage_En); ok {
- return x.En
- }
- return 0
-}
-
-func (m *SimpleMessage) GetNo() *Embedded {
- if x, ok := m.GetExt().(*SimpleMessage_No); ok {
- return x.No
- }
- return nil
-}
-
-// XXX_OneofWrappers is for the internal use of the proto package.
-func (*SimpleMessage) XXX_OneofWrappers() []interface{} {
- return []interface{}{
- (*SimpleMessage_LineNum)(nil),
- (*SimpleMessage_Lang)(nil),
- (*SimpleMessage_En)(nil),
- (*SimpleMessage_No)(nil),
- }
-}
-
-func init() {
- proto.RegisterType((*Embedded)(nil), "examples.Embedded")
- proto.RegisterType((*SimpleMessage)(nil), "examples.SimpleMessage")
-}
-
-func init() { proto.RegisterFile("proto/examples/echo_service.proto", fileDescriptor_50dd28de91ad0693) }
-
-var fileDescriptor_50dd28de91ad0693 = []byte{
- // 544 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0x41, 0x6e, 0xd3, 0x40,
- 0x14, 0xed, 0xd8, 0x4e, 0xec, 0xfc, 0x2a, 0x52, 0x34, 0x02, 0xc5, 0x38, 0x04, 0xdc, 0xa8, 0x8b,
- 0x28, 0x0b, 0x9b, 0x04, 0x0b, 0x21, 0x96, 0x16, 0x41, 0xdd, 0x80, 0x90, 0xbb, 0x8b, 0x40, 0x91,
- 0x63, 0x7f, 0x12, 0x8b, 0x78, 0xc6, 0xb2, 0x9d, 0xd2, 0x2a, 0xca, 0x01, 0x38, 0x00, 0xd7, 0x60,
- 0x51, 0x24, 0x0e, 0x91, 0x13, 0x70, 0x80, 0xae, 0x58, 0xb0, 0xc9, 0x01, 0x8a, 0xc6, 0x89, 0x8b,
- 0xa0, 0x2d, 0x8b, 0xae, 0x3c, 0x7f, 0xde, 0xf3, 0xfb, 0xff, 0xbf, 0xa7, 0x81, 0x83, 0x24, 0xe5,
- 0x39, 0xb7, 0xf1, 0xd4, 0x8f, 0x93, 0x39, 0x66, 0x36, 0x06, 0x33, 0x3e, 0xce, 0x30, 0x3d, 0x89,
- 0x02, 0xb4, 0x0a, 0x8c, 0x6a, 0x25, 0x68, 0xb4, 0x67, 0x79, 0x9e, 0xf0, 0x24, 0x8f, 0x38, 0xcb,
- 0x6c, 0x9f, 0x31, 0x9e, 0xfb, 0xc5, 0x79, 0x4b, 0xec, 0xbc, 0x02, 0x6d, 0x18, 0x4f, 0x30, 0x0c,
- 0x31, 0xa4, 0x0f, 0x41, 0x4b, 0x52, 0x3e, 0x4d, 0x31, 0xcb, 0x74, 0x62, 0x92, 0xae, 0x7c, 0xb4,
- 0xe7, 0x5d, 0xdd, 0xd0, 0x7b, 0xa0, 0x30, 0x9e, 0xa3, 0x2e, 0x99, 0xa4, 0x5b, 0x3b, 0xda, 0xf3,
- 0x8a, 0xca, 0xad, 0x82, 0x12, 0xfb, 0xe9, 0xc7, 0xce, 0x67, 0x09, 0xea, 0xc7, 0x91, 0x68, 0xf9,
- 0x1a, 0xb3, 0xcc, 0x9f, 0x22, 0xed, 0x83, 0x14, 0x85, 0x85, 0x4e, 0xcd, 0x3d, 0x38, 0xbf, 0x70,
- 0xda, 0xa0, 0x68, 0x95, 0x86, 0x04, 0x35, 0xad, 0xda, 0x90, 0x0c, 0x32, 0x30, 0x09, 0x80, 0xa6,
- 0x36, 0x24, 0x43, 0x7a, 0xd6, 0x37, 0x89, 0x27, 0x45, 0x21, 0x7d, 0x0c, 0x32, 0x5b, 0xc4, 0x45,
- 0x07, 0xd9, 0xad, 0x9f, 0x5f, 0x38, 0x35, 0x50, 0x35, 0xd2, 0x20, 0x06, 0x79, 0xe2, 0x09, 0x84,
- 0xb6, 0x40, 0x9b, 0x47, 0x0c, 0xc7, 0x82, 0x25, 0xef, 0x26, 0x54, 0xc5, 0xcd, 0x9b, 0x45, 0x2c,
- 0x06, 0x9c, 0xfb, 0x6c, 0xaa, 0x2b, 0xe5, 0x80, 0xa2, 0xa2, 0x3d, 0xa8, 0x66, 0xb9, 0x9f, 0x2f,
- 0x32, 0xbd, 0x62, 0x92, 0xee, 0xfe, 0x80, 0x5a, 0xa5, 0x35, 0x56, 0xb9, 0xb8, 0xb7, 0x63, 0xd0,
- 0x06, 0x48, 0xc8, 0xf4, 0x6a, 0x21, 0x4c, 0x3c, 0x09, 0x19, 0x3d, 0x04, 0x89, 0x71, 0x5d, 0xbd,
- 0xed, 0x4f, 0xc1, 0x62, 0x5c, 0x98, 0x10, 0xf0, 0x10, 0xdd, 0x0a, 0xc8, 0x78, 0x9a, 0x0f, 0x7e,
- 0xc8, 0xb0, 0x3f, 0x0c, 0x66, 0xfc, 0x78, 0x1b, 0x09, 0xfd, 0x45, 0x40, 0x11, 0x35, 0x6d, 0xfe,
- 0x51, 0xf8, 0xcb, 0x2b, 0xe3, 0x36, 0xa0, 0xf3, 0x8d, 0xac, 0x37, 0xce, 0x57, 0xd2, 0xb9, 0x6f,
- 0x9f, 0xf4, 0xcb, 0xc0, 0x8b, 0xbc, 0xed, 0x65, 0x14, 0xae, 0x46, 0x6d, 0xda, 0xba, 0x11, 0xb0,
- 0x97, 0x6c, 0x11, 0xaf, 0x46, 0x87, 0xb4, 0xf3, 0x1f, 0xd8, 0x5e, 0x0a, 0x83, 0x56, 0xa3, 0x3e,
- 0xb5, 0xff, 0x65, 0xf5, 0x77, 0xb4, 0xd2, 0xec, 0x95, 0xbd, 0xdc, 0x5a, 0x64, 0x89, 0xd0, 0x6f,
- 0xec, 0x3b, 0xb0, 0x97, 0x8c, 0x6f, 0x61, 0xfa, 0x0e, 0x34, 0xb1, 0xaf, 0xcb, 0xc3, 0xb3, 0x3b,
- 0xec, 0xfc, 0x68, 0xbd, 0x71, 0x8c, 0xeb, 0x1b, 0x8f, 0x27, 0x3c, 0x3c, 0x7b, 0x41, 0x7a, 0xf4,
- 0x3d, 0x80, 0x50, 0x7f, 0x89, 0x73, 0xcc, 0xf1, 0x0e, 0xfa, 0xed, 0xf5, 0xc6, 0x79, 0xd0, 0x6b,
- 0x5e, 0xd3, 0x0f, 0x0b, 0x41, 0xa3, 0xf5, 0x73, 0xe3, 0x34, 0xb5, 0xef, 0x5f, 0x2e, 0x2f, 0x55,
- 0xaa, 0x4c, 0xd3, 0x24, 0x30, 0xd4, 0x10, 0x3f, 0xf8, 0x8b, 0x79, 0x6e, 0x12, 0xf7, 0x39, 0x98,
- 0x01, 0x8f, 0xad, 0x49, 0xc4, 0x82, 0x19, 0x32, 0x11, 0x7a, 0x6a, 0xa1, 0x9f, 0xe1, 0xf4, 0xd3,
- 0x55, 0x37, 0xb7, 0x3e, 0xdc, 0x9d, 0xde, 0x8a, 0x17, 0x36, 0xaa, 0x14, 0x0f, 0x6d, 0x52, 0x2d,
- 0x3e, 0x4f, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0x50, 0x55, 0xf3, 0xae, 0xbd, 0x03, 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
-
-// EchoServiceClient is the client API for EchoService service.
-//
-// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
-type EchoServiceClient interface {
- Echo(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error)
- EchoBody(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error)
- EchoDelete(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error)
-}
-
-type echoServiceClient struct {
- cc *grpc.ClientConn
-}
-
-func NewEchoServiceClient(cc *grpc.ClientConn) EchoServiceClient {
- return &echoServiceClient{cc}
-}
-
-func (c *echoServiceClient) Echo(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error) {
- out := new(SimpleMessage)
- err := c.cc.Invoke(ctx, "/examples.EchoService/Echo", in, out, opts...)
- if err != nil {
- return nil, err
- }
- return out, nil
-}
-
-func (c *echoServiceClient) EchoBody(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error) {
- out := new(SimpleMessage)
- err := c.cc.Invoke(ctx, "/examples.EchoService/EchoBody", in, out, opts...)
- if err != nil {
- return nil, err
- }
- return out, nil
-}
-
-func (c *echoServiceClient) EchoDelete(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error) {
- out := new(SimpleMessage)
- err := c.cc.Invoke(ctx, "/examples.EchoService/EchoDelete", in, out, opts...)
- if err != nil {
- return nil, err
- }
- return out, nil
-}
-
-// EchoServiceServer is the server API for EchoService service.
-type EchoServiceServer interface {
- Echo(context.Context, *SimpleMessage) (*SimpleMessage, error)
- EchoBody(context.Context, *SimpleMessage) (*SimpleMessage, error)
- EchoDelete(context.Context, *SimpleMessage) (*SimpleMessage, error)
-}
-
-func RegisterEchoServiceServer(s *grpc.Server, srv EchoServiceServer) {
- s.RegisterService(&_EchoService_serviceDesc, srv)
-}
-
-func _EchoService_Echo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
- in := new(SimpleMessage)
- if err := dec(in); err != nil {
- return nil, err
- }
- if interceptor == nil {
- return srv.(EchoServiceServer).Echo(ctx, in)
- }
- info := &grpc.UnaryServerInfo{
- Server: srv,
- FullMethod: "/examples.EchoService/Echo",
- }
- handler := func(ctx context.Context, req interface{}) (interface{}, error) {
- return srv.(EchoServiceServer).Echo(ctx, req.(*SimpleMessage))
- }
- return interceptor(ctx, in, info, handler)
-}
-
-func _EchoService_EchoBody_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
- in := new(SimpleMessage)
- if err := dec(in); err != nil {
- return nil, err
- }
- if interceptor == nil {
- return srv.(EchoServiceServer).EchoBody(ctx, in)
- }
- info := &grpc.UnaryServerInfo{
- Server: srv,
- FullMethod: "/examples.EchoService/EchoBody",
- }
- handler := func(ctx context.Context, req interface{}) (interface{}, error) {
- return srv.(EchoServiceServer).EchoBody(ctx, req.(*SimpleMessage))
- }
- return interceptor(ctx, in, info, handler)
-}
-
-func _EchoService_EchoDelete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
- in := new(SimpleMessage)
- if err := dec(in); err != nil {
- return nil, err
- }
- if interceptor == nil {
- return srv.(EchoServiceServer).EchoDelete(ctx, in)
- }
- info := &grpc.UnaryServerInfo{
- Server: srv,
- FullMethod: "/examples.EchoService/EchoDelete",
- }
- handler := func(ctx context.Context, req interface{}) (interface{}, error) {
- return srv.(EchoServiceServer).EchoDelete(ctx, req.(*SimpleMessage))
- }
- return interceptor(ctx, in, info, handler)
-}
-
-var _EchoService_serviceDesc = grpc.ServiceDesc{
- ServiceName: "examples.EchoService",
- HandlerType: (*EchoServiceServer)(nil),
- Methods: []grpc.MethodDesc{
- {
- MethodName: "Echo",
- Handler: _EchoService_Echo_Handler,
- },
- {
- MethodName: "EchoBody",
- Handler: _EchoService_EchoBody_Handler,
- },
- {
- MethodName: "EchoDelete",
- Handler: _EchoService_EchoDelete_Handler,
- },
- },
- Streams: []grpc.StreamDesc{},
- Metadata: "proto/examples/echo_service.proto",
-}
diff --git a/proto/examples/echo_service.pb.gw.go b/proto/examples/echo_service.pb.gw.go
deleted file mode 100755
index d17576d..0000000
--- a/proto/examples/echo_service.pb.gw.go
+++ /dev/null
@@ -1,1254 +0,0 @@
-// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
-// source: proto/examples/echo_service.proto
-
-/*
-Package proto is a reverse proxy.
-
-It translates gRPC into RESTful JSON APIs.
-*/
-package proto
-
-import (
- "context"
- "io"
- "net/http"
- "regexp"
- "strings"
- "sync"
- "unicode/utf8"
-
- "github.com/binchencoder/ease-gateway/gateway/runtime"
- vexpb "github.com/binchencoder/gateway-proto/data"
- fpb "github.com/binchencoder/gateway-proto/frontend"
- lgr "github.com/binchencoder/letsgo/grpc"
- "github.com/binchencoder/skylb-api/balancer"
- "github.com/binchencoder/skylb-api/client"
- "github.com/binchencoder/skylb-api/client/option"
- skypb "github.com/binchencoder/skylb-api/proto"
- "github.com/golang/protobuf/proto"
- "github.com/grpc-ecosystem/grpc-gateway/utilities"
- "google.golang.org/grpc"
- "google.golang.org/grpc/codes"
- "google.golang.org/grpc/naming"
- "google.golang.org/grpc/status"
-)
-
-// Suppress "imported and not used" errors
-var _ codes.Code
-var _ io.Reader
-var _ status.Status
-var _ = runtime.String
-var _ = utilities.NewDoubleArray
-
-// var _ = descriptor.ForMessage
-var _ sync.RWMutex
-var _ proto.Message
-var _ context.Context
-var _ grpc.ClientConn
-var _ client.ServiceCli
-var _ vexpb.ServiceId
-var _ = http.MethodGet
-var _ regexp.Regexp
-var _ = balancer.ConsistentHashing
-var _ option.BalancerCreator
-var _ naming.Resolver
-var _ strings.Reader
-var _ = utf8.UTFMax
-
-// TODO (jiezmo): check if there is any rule before create this var.
-var proto_examples_echo_service_error = lgr.ToGrpcError(codes.InvalidArgument, &fpb.Error{Code: fpb.ErrorCode_BADPARAM_ERROR, Params: []string{"Validation error"}})
-
-// Validation methods start
-
-func Validate__examples_SimpleMessage(v *SimpleMessage) error {
- if v == nil {
- return nil
- }
- // Validation for each Fields
-
- {
- vv2 := v.Id
-
- // Validation Field: Id
-
- // TODO(jiezmo): fail the build
- // Err
-
- if utf8.RuneCountInString(strings.TrimSpace(vv2)) <= 2 {
- return proto_examples_echo_service_error
- }
-
- if utf8.RuneCountInString(strings.TrimSpace(vv2)) >= 61 {
- return proto_examples_echo_service_error
- }
-
- }
-
- {
- vv2 := v.Num
-
- // Validation Field: Num
-
- if vv2 <= 0 {
- return proto_examples_echo_service_error
- }
-
- }
-
- // Validation Field: GetLineNum()
-
- // Validation Field: GetLang()
-
- // Validation Field: Status
-
- // Validation Field: GetEn()
-
- // Validation Field: GetNo()
-
- return nil
-}
-
-// Validation methods done
-
-var (
- filter_EchoService_Echo_0 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
-)
-
-func request_EchoService_Echo_0(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
- var protoReq SimpleMessage
- var metadata runtime.ServerMetadata
- spec := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec
-
- var (
- val string
- ok bool
- err error
- _ = err
- )
-
- val, ok = pathParams["id"]
- if !ok {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
- }
-
- protoReq.Id, err = runtime.String(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
- }
-
- if err := req.ParseForm(); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
- if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_Echo_0); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
-
- // Only hook up for non-stream call for now.
-
- // Validate
- // SimpleMessage
- if err := Validate__examples_SimpleMessage(&protoReq); err != nil {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, err
- }
-
- runtime.RequestParsed(ctx, spec, "EchoService", "Echo", &protoReq, &metadata)
- ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
- msg, err := client.Echo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
- // if err != nil {
- // grpclog.Errorf("client.%s returns error: %v", "Echo", err)
- // }
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", msg, &metadata, err)
- return msg, metadata, err
-
-}
-
-func local_request_EchoService_Echo_0(ctx context.Context, marshaler runtime.Marshaler, server EchoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
- var protoReq SimpleMessage
- var metadata runtime.ServerMetadata
-
- var (
- val string
- ok bool
- err error
- _ = err
- )
-
- val, ok = pathParams["id"]
- if !ok {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
- }
-
- protoReq.Id, err = runtime.String(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
- }
-
- if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_EchoService_Echo_0); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
-
- msg, err := server.Echo(ctx, &protoReq)
- return msg, metadata, err
-
-}
-
-var (
- filter_EchoService_Echo_1 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0, "num": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}}
-)
-
-func request_EchoService_Echo_1(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
- var protoReq SimpleMessage
- var metadata runtime.ServerMetadata
- spec := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec
-
- var (
- val string
- ok bool
- err error
- _ = err
- )
-
- val, ok = pathParams["id"]
- if !ok {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
- }
-
- protoReq.Id, err = runtime.String(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
- }
-
- val, ok = pathParams["num"]
- if !ok {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "num")
- }
-
- protoReq.Num, err = runtime.Int64(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "num", err)
- }
-
- if err := req.ParseForm(); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
- if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_Echo_1); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
-
- // Only hook up for non-stream call for now.
-
- // Validate
- // SimpleMessage
- if err := Validate__examples_SimpleMessage(&protoReq); err != nil {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, err
- }
-
- runtime.RequestParsed(ctx, spec, "EchoService", "Echo", &protoReq, &metadata)
- ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
- msg, err := client.Echo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
- // if err != nil {
- // grpclog.Errorf("client.%s returns error: %v", "Echo", err)
- // }
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", msg, &metadata, err)
- return msg, metadata, err
-
-}
-
-func local_request_EchoService_Echo_1(ctx context.Context, marshaler runtime.Marshaler, server EchoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
- var protoReq SimpleMessage
- var metadata runtime.ServerMetadata
-
- var (
- val string
- ok bool
- err error
- _ = err
- )
-
- val, ok = pathParams["id"]
- if !ok {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
- }
-
- protoReq.Id, err = runtime.String(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
- }
-
- val, ok = pathParams["num"]
- if !ok {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "num")
- }
-
- protoReq.Num, err = runtime.Int64(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "num", err)
- }
-
- if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_EchoService_Echo_1); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
-
- msg, err := server.Echo(ctx, &protoReq)
- return msg, metadata, err
-
-}
-
-var (
- filter_EchoService_Echo_2 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0, "num": 1, "lang": 2}, Base: []int{1, 1, 2, 3, 0, 0, 0}, Check: []int{0, 1, 1, 1, 2, 3, 4}}
-)
-
-func request_EchoService_Echo_2(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
- var protoReq SimpleMessage
- var metadata runtime.ServerMetadata
- spec := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec
-
- var (
- val string
- ok bool
- err error
- _ = err
- )
-
- val, ok = pathParams["id"]
- if !ok {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
- }
-
- protoReq.Id, err = runtime.String(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
- }
-
- val, ok = pathParams["num"]
- if !ok {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "num")
- }
-
- protoReq.Num, err = runtime.Int64(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "num", err)
- }
-
- val, ok = pathParams["lang"]
- if !ok {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "lang")
- }
-
- if protoReq.Code == nil {
- protoReq.Code = &SimpleMessage_Lang{}
- } else if _, ok := protoReq.Code.(*SimpleMessage_Lang); !ok {
- return nil, metadata, grpc.Errorf(codes.InvalidArgument, "expect type: *SimpleMessage_Lang, but: %t\n", protoReq.Code)
- }
- protoReq.Code.(*SimpleMessage_Lang).Lang, err = runtime.String(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "lang", err)
- }
-
- if err := req.ParseForm(); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
- if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_Echo_2); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
-
- // Only hook up for non-stream call for now.
-
- // Validate
- // SimpleMessage
- if err := Validate__examples_SimpleMessage(&protoReq); err != nil {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, err
- }
-
- runtime.RequestParsed(ctx, spec, "EchoService", "Echo", &protoReq, &metadata)
- ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
- msg, err := client.Echo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
- // if err != nil {
- // grpclog.Errorf("client.%s returns error: %v", "Echo", err)
- // }
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", msg, &metadata, err)
- return msg, metadata, err
-
-}
-
-func local_request_EchoService_Echo_2(ctx context.Context, marshaler runtime.Marshaler, server EchoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
- var protoReq SimpleMessage
- var metadata runtime.ServerMetadata
-
- var (
- val string
- ok bool
- err error
- _ = err
- )
-
- val, ok = pathParams["id"]
- if !ok {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
- }
-
- protoReq.Id, err = runtime.String(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
- }
-
- val, ok = pathParams["num"]
- if !ok {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "num")
- }
-
- protoReq.Num, err = runtime.Int64(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "num", err)
- }
-
- val, ok = pathParams["lang"]
- if !ok {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "lang")
- }
-
- if protoReq.Code == nil {
- protoReq.Code = &SimpleMessage_Lang{}
- } else if _, ok := protoReq.Code.(*SimpleMessage_Lang); !ok {
- return nil, metadata, grpc.Errorf(codes.InvalidArgument, "expect type: *SimpleMessage_Lang, but: %t\n", protoReq.Code)
- }
- protoReq.Code.(*SimpleMessage_Lang).Lang, err = runtime.String(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "lang", err)
- }
-
- if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_EchoService_Echo_2); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
-
- msg, err := server.Echo(ctx, &protoReq)
- return msg, metadata, err
-
-}
-
-var (
- filter_EchoService_Echo_3 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0, "line_num": 1, "status": 2, "note": 3}, Base: []int{1, 1, 2, 1, 3, 0, 0, 0}, Check: []int{0, 1, 1, 1, 4, 2, 3, 5}}
-)
-
-func request_EchoService_Echo_3(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
- var protoReq SimpleMessage
- var metadata runtime.ServerMetadata
- spec := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec
-
- var (
- val string
- ok bool
- err error
- _ = err
- )
-
- val, ok = pathParams["id"]
- if !ok {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
- }
-
- protoReq.Id, err = runtime.String(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
- }
-
- val, ok = pathParams["line_num"]
- if !ok {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "line_num")
- }
-
- if protoReq.Code == nil {
- protoReq.Code = &SimpleMessage_LineNum{}
- } else if _, ok := protoReq.Code.(*SimpleMessage_LineNum); !ok {
- return nil, metadata, grpc.Errorf(codes.InvalidArgument, "expect type: *SimpleMessage_LineNum, but: %t\n", protoReq.Code)
- }
- protoReq.Code.(*SimpleMessage_LineNum).LineNum, err = runtime.Int64(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "line_num", err)
- }
-
- val, ok = pathParams["status.note"]
- if !ok {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "status.note")
- }
-
- err = runtime.PopulateFieldFromPath(&protoReq, "status.note", val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "status.note", err)
- }
-
- if err := req.ParseForm(); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
- if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_Echo_3); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
-
- // Only hook up for non-stream call for now.
-
- // Validate
- // SimpleMessage
- if err := Validate__examples_SimpleMessage(&protoReq); err != nil {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, err
- }
-
- runtime.RequestParsed(ctx, spec, "EchoService", "Echo", &protoReq, &metadata)
- ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
- msg, err := client.Echo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
- // if err != nil {
- // grpclog.Errorf("client.%s returns error: %v", "Echo", err)
- // }
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", msg, &metadata, err)
- return msg, metadata, err
-
-}
-
-func local_request_EchoService_Echo_3(ctx context.Context, marshaler runtime.Marshaler, server EchoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
- var protoReq SimpleMessage
- var metadata runtime.ServerMetadata
-
- var (
- val string
- ok bool
- err error
- _ = err
- )
-
- val, ok = pathParams["id"]
- if !ok {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
- }
-
- protoReq.Id, err = runtime.String(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
- }
-
- val, ok = pathParams["line_num"]
- if !ok {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "line_num")
- }
-
- if protoReq.Code == nil {
- protoReq.Code = &SimpleMessage_LineNum{}
- } else if _, ok := protoReq.Code.(*SimpleMessage_LineNum); !ok {
- return nil, metadata, grpc.Errorf(codes.InvalidArgument, "expect type: *SimpleMessage_LineNum, but: %t\n", protoReq.Code)
- }
- protoReq.Code.(*SimpleMessage_LineNum).LineNum, err = runtime.Int64(val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "line_num", err)
- }
-
- val, ok = pathParams["status.note"]
- if !ok {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "status.note")
- }
-
- err = runtime.PopulateFieldFromPath(&protoReq, "status.note", val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "status.note", err)
- }
-
- if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_EchoService_Echo_3); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
-
- msg, err := server.Echo(ctx, &protoReq)
- return msg, metadata, err
-
-}
-
-var (
- filter_EchoService_Echo_4 = &utilities.DoubleArray{Encoding: map[string]int{"no": 0, "note": 1}, Base: []int{1, 1, 1, 0}, Check: []int{0, 1, 2, 3}}
-)
-
-func request_EchoService_Echo_4(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
- var protoReq SimpleMessage
- var metadata runtime.ServerMetadata
- spec := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec
-
- var (
- val string
- ok bool
- err error
- _ = err
- )
-
- val, ok = pathParams["no.note"]
- if !ok {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "no.note")
- }
-
- err = runtime.PopulateFieldFromPath(&protoReq, "no.note", val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "no.note", err)
- }
-
- if err := req.ParseForm(); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
- if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_Echo_4); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
-
- // Only hook up for non-stream call for now.
-
- // Validate
- // SimpleMessage
- if err := Validate__examples_SimpleMessage(&protoReq); err != nil {
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", nil, &metadata, err)
- return nil, metadata, err
- }
-
- runtime.RequestParsed(ctx, spec, "EchoService", "Echo", &protoReq, &metadata)
- ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
- msg, err := client.Echo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
- // if err != nil {
- // grpclog.Errorf("client.%s returns error: %v", "Echo", err)
- // }
- runtime.RequestHandled(ctx, spec, "EchoService", "Echo", msg, &metadata, err)
- return msg, metadata, err
-
-}
-
-func local_request_EchoService_Echo_4(ctx context.Context, marshaler runtime.Marshaler, server EchoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
- var protoReq SimpleMessage
- var metadata runtime.ServerMetadata
-
- var (
- val string
- ok bool
- err error
- _ = err
- )
-
- val, ok = pathParams["no.note"]
- if !ok {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "no.note")
- }
-
- err = runtime.PopulateFieldFromPath(&protoReq, "no.note", val)
-
- if err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "no.note", err)
- }
-
- if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_EchoService_Echo_4); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
-
- msg, err := server.Echo(ctx, &protoReq)
- return msg, metadata, err
-
-}
-
-func request_EchoService_EchoBody_0(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
- var protoReq SimpleMessage
- var metadata runtime.ServerMetadata
- spec := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec
-
- newReader, berr := utilities.IOReaderFactory(req.Body)
- if berr != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
- }
- if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
- runtime.RequestHandled(ctx, spec, "EchoService", "EchoBody", nil, &metadata, err)
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
-
- // Only hook up for non-stream call for now.
-
- // Validate
- // SimpleMessage
- if err := Validate__examples_SimpleMessage(&protoReq); err != nil {
- runtime.RequestHandled(ctx, spec, "EchoService", "EchoBody", nil, &metadata, err)
- return nil, metadata, err
- }
-
- runtime.RequestParsed(ctx, spec, "EchoService", "EchoBody", &protoReq, &metadata)
- ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
- msg, err := client.EchoBody(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
- // if err != nil {
- // grpclog.Errorf("client.%s returns error: %v", "EchoBody", err)
- // }
- runtime.RequestHandled(ctx, spec, "EchoService", "EchoBody", msg, &metadata, err)
- return msg, metadata, err
-
-}
-
-func local_request_EchoService_EchoBody_0(ctx context.Context, marshaler runtime.Marshaler, server EchoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
- var protoReq SimpleMessage
- var metadata runtime.ServerMetadata
-
- newReader, berr := utilities.IOReaderFactory(req.Body)
- if berr != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
- }
- if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
-
- msg, err := server.EchoBody(ctx, &protoReq)
- return msg, metadata, err
-
-}
-
-var (
- filter_EchoService_EchoDelete_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
-)
-
-func request_EchoService_EchoDelete_0(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
- var protoReq SimpleMessage
- var metadata runtime.ServerMetadata
- spec := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec
-
- if err := req.ParseForm(); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
- if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_EchoService_EchoDelete_0); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
-
- // Only hook up for non-stream call for now.
-
- // Validate
- // SimpleMessage
- if err := Validate__examples_SimpleMessage(&protoReq); err != nil {
- runtime.RequestHandled(ctx, spec, "EchoService", "EchoDelete", nil, &metadata, err)
- return nil, metadata, err
- }
-
- runtime.RequestParsed(ctx, spec, "EchoService", "EchoDelete", &protoReq, &metadata)
- ctx = runtime.PreLoadBalance(ctx, "ROUND_ROBIN", "", &protoReq)
- msg, err := client.EchoDelete(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
- // if err != nil {
- // grpclog.Errorf("client.%s returns error: %v", "EchoDelete", err)
- // }
- runtime.RequestHandled(ctx, spec, "EchoService", "EchoDelete", msg, &metadata, err)
- return msg, metadata, err
-
-}
-
-func local_request_EchoService_EchoDelete_0(ctx context.Context, marshaler runtime.Marshaler, server EchoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
- var protoReq SimpleMessage
- var metadata runtime.ServerMetadata
-
- if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_EchoService_EchoDelete_0); err != nil {
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
- }
-
- msg, err := server.EchoDelete(ctx, &protoReq)
- return msg, metadata, err
-
-}
-
-// Register itself to runtime.
-func init() {
- var s *runtime.Service
- var spec *skypb.ServiceSpec
-
- _ = s
- _ = spec
-
- spec = internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec
- s = &runtime.Service{
- Spec: *spec,
- Name: "EchoService",
- Register: RegisterEchoServiceHandlerFromEndpoint,
- Enable: EnableEchoService_Service,
- Disable: DisableEchoService_Service,
- }
-
- runtime.AddService(s, Enable_CUSTOM_EASE_GATEWAY_TEST__default__grpc_ServiceGroup, Disable_CUSTOM_EASE_GATEWAY_TEST__default__grpc_ServiceGroup)
-
-}
-
-// RegisterEchoServiceHandlerFromEndpoint is same as RegisterEchoServiceHandler but
-// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
-func RegisterEchoServiceHandlerFromEndpoint(mux *runtime.ServeMux) (err error) {
- // conn, err := grpc.Dial(endpoint, opts...)
- // if err != nil {
- // return err
- // }
- // defer func() {
- // if err != nil {
- // if cerr := conn.Close(); cerr != nil {
- // grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
- // }
- // return
- // }
- // go func() {
- // <-ctx.Done()
- // if cerr := conn.Close(); cerr != nil {
- // grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
- // }
- // }()
- // }()
-
- // return RegisterEchoServiceHandler(ctx, mux, conn)
- return RegisterEchoServiceHandler(nil, mux, nil)
-}
-
-// RegisterEchoServiceHandler registers the http handlers for service EchoService to "mux".
-// The handlers forward requests to the grpc endpoint over "conn".
-func RegisterEchoServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
- return RegisterEchoServiceHandlerClient(ctx, mux, NewEchoServiceClient(conn))
-}
-
-// RegisterEchoServiceHandlerClient registers the http handlers for service EchoService
-// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "EchoServiceClient".
-// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "EchoServiceClient"
-// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
-// "EchoServiceClient" to call the correct interceptors.
-func RegisterEchoServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client EchoServiceClient) error {
- spec := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec
-
- runtime.AddMethod(spec, "EchoService", "Echo", "/v1/example/echo/{id}", "POST", true, false, false, "UNSPECIFIED", "EASE_GATEWAY", "EASE_AUTH_TOKEN", "")
- mux.Handle("POST", pattern_EchoService_Echo_0, vexpb.ServiceId_CUSTOM_EASE_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
- // TODO(mojz): review all locking/unlocking logic.
- // internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RLock()
- // defer internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RUnlock()
- cli := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_client
- if cli == nil {
- runtime.DefaultOtherErrorHandler(w, req, "service disabled", http.StatusInternalServerError)
- return
- }
-
- ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec, "EchoService", "Echo", w, req)
- if err != nil {
- // grpclog.Errorf("runtime.RequestAccepted returns error: %v", err)
- runtime.HTTPError(ctx, nil, &runtime.JSONBuiltin{}, w, req, err)
- return
- }
- ctx, cancel := context.WithCancel(req.Context())
- defer cancel()
- if cn, ok := w.(http.CloseNotifier); ok {
- go func(done <-chan struct{}, closed <-chan bool) {
- select {
- case <-done:
- case <-closed:
- cancel()
- }
- }(ctx.Done(), cn.CloseNotify())
- }
- inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
- rctx, err := runtime.AnnotateContext(ctx, mux, req)
- if err != nil {
- // grpclog.Errorf("runtime.AnnotateContext returns error: %v", err)
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
- resp, md, err := request_EchoService_Echo_0(rctx, inboundMarshaler, cli, req, pathParams)
- ctx = runtime.NewServerMetadataContext(ctx, md)
- if err != nil {
- // grpclog.Errorf("request_%s_%s_%s returns error: %v", "EchoService", "Echo", "0", err)
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
-
- forward_EchoService_Echo_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
- })
-
- runtime.AddMethod(spec, "EchoService", "Echo", "/v1/example/echo/{id}/{num}", "GET", true, false, false, "UNSPECIFIED", "EASE_GATEWAY", "EASE_AUTH_TOKEN", "")
- mux.Handle("GET", pattern_EchoService_Echo_1, vexpb.ServiceId_CUSTOM_EASE_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
- // TODO(mojz): review all locking/unlocking logic.
- // internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RLock()
- // defer internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RUnlock()
- cli := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_client
- if cli == nil {
- runtime.DefaultOtherErrorHandler(w, req, "service disabled", http.StatusInternalServerError)
- return
- }
-
- ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec, "EchoService", "Echo", w, req)
- if err != nil {
- // grpclog.Errorf("runtime.RequestAccepted returns error: %v", err)
- runtime.HTTPError(ctx, nil, &runtime.JSONBuiltin{}, w, req, err)
- return
- }
- ctx, cancel := context.WithCancel(req.Context())
- defer cancel()
- if cn, ok := w.(http.CloseNotifier); ok {
- go func(done <-chan struct{}, closed <-chan bool) {
- select {
- case <-done:
- case <-closed:
- cancel()
- }
- }(ctx.Done(), cn.CloseNotify())
- }
- inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
- rctx, err := runtime.AnnotateContext(ctx, mux, req)
- if err != nil {
- // grpclog.Errorf("runtime.AnnotateContext returns error: %v", err)
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
- resp, md, err := request_EchoService_Echo_1(rctx, inboundMarshaler, cli, req, pathParams)
- ctx = runtime.NewServerMetadataContext(ctx, md)
- if err != nil {
- // grpclog.Errorf("request_%s_%s_%s returns error: %v", "EchoService", "Echo", "1", err)
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
-
- forward_EchoService_Echo_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
- })
-
- runtime.AddMethod(spec, "EchoService", "Echo", "/v1/example/echo/{id}/{num}/{lang}", "GET", true, false, false, "UNSPECIFIED", "EASE_GATEWAY", "EASE_AUTH_TOKEN", "")
- mux.Handle("GET", pattern_EchoService_Echo_2, vexpb.ServiceId_CUSTOM_EASE_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
- // TODO(mojz): review all locking/unlocking logic.
- // internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RLock()
- // defer internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RUnlock()
- cli := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_client
- if cli == nil {
- runtime.DefaultOtherErrorHandler(w, req, "service disabled", http.StatusInternalServerError)
- return
- }
-
- ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec, "EchoService", "Echo", w, req)
- if err != nil {
- // grpclog.Errorf("runtime.RequestAccepted returns error: %v", err)
- runtime.HTTPError(ctx, nil, &runtime.JSONBuiltin{}, w, req, err)
- return
- }
- ctx, cancel := context.WithCancel(req.Context())
- defer cancel()
- if cn, ok := w.(http.CloseNotifier); ok {
- go func(done <-chan struct{}, closed <-chan bool) {
- select {
- case <-done:
- case <-closed:
- cancel()
- }
- }(ctx.Done(), cn.CloseNotify())
- }
- inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
- rctx, err := runtime.AnnotateContext(ctx, mux, req)
- if err != nil {
- // grpclog.Errorf("runtime.AnnotateContext returns error: %v", err)
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
- resp, md, err := request_EchoService_Echo_2(rctx, inboundMarshaler, cli, req, pathParams)
- ctx = runtime.NewServerMetadataContext(ctx, md)
- if err != nil {
- // grpclog.Errorf("request_%s_%s_%s returns error: %v", "EchoService", "Echo", "2", err)
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
-
- forward_EchoService_Echo_2(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
- })
-
- runtime.AddMethod(spec, "EchoService", "Echo", "/v1/example/echo1/{id}/{line_num}/{status.note}", "GET", true, false, false, "UNSPECIFIED", "EASE_GATEWAY", "EASE_AUTH_TOKEN", "")
- mux.Handle("GET", pattern_EchoService_Echo_3, vexpb.ServiceId_CUSTOM_EASE_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
- // TODO(mojz): review all locking/unlocking logic.
- // internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RLock()
- // defer internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RUnlock()
- cli := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_client
- if cli == nil {
- runtime.DefaultOtherErrorHandler(w, req, "service disabled", http.StatusInternalServerError)
- return
- }
-
- ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec, "EchoService", "Echo", w, req)
- if err != nil {
- // grpclog.Errorf("runtime.RequestAccepted returns error: %v", err)
- runtime.HTTPError(ctx, nil, &runtime.JSONBuiltin{}, w, req, err)
- return
- }
- ctx, cancel := context.WithCancel(req.Context())
- defer cancel()
- if cn, ok := w.(http.CloseNotifier); ok {
- go func(done <-chan struct{}, closed <-chan bool) {
- select {
- case <-done:
- case <-closed:
- cancel()
- }
- }(ctx.Done(), cn.CloseNotify())
- }
- inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
- rctx, err := runtime.AnnotateContext(ctx, mux, req)
- if err != nil {
- // grpclog.Errorf("runtime.AnnotateContext returns error: %v", err)
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
- resp, md, err := request_EchoService_Echo_3(rctx, inboundMarshaler, cli, req, pathParams)
- ctx = runtime.NewServerMetadataContext(ctx, md)
- if err != nil {
- // grpclog.Errorf("request_%s_%s_%s returns error: %v", "EchoService", "Echo", "3", err)
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
-
- forward_EchoService_Echo_3(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
- })
-
- runtime.AddMethod(spec, "EchoService", "Echo", "/v1/example/echo2/{no.note}", "GET", true, false, false, "UNSPECIFIED", "EASE_GATEWAY", "EASE_AUTH_TOKEN", "")
- mux.Handle("GET", pattern_EchoService_Echo_4, vexpb.ServiceId_CUSTOM_EASE_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
- // TODO(mojz): review all locking/unlocking logic.
- // internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RLock()
- // defer internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RUnlock()
- cli := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_client
- if cli == nil {
- runtime.DefaultOtherErrorHandler(w, req, "service disabled", http.StatusInternalServerError)
- return
- }
-
- ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec, "EchoService", "Echo", w, req)
- if err != nil {
- // grpclog.Errorf("runtime.RequestAccepted returns error: %v", err)
- runtime.HTTPError(ctx, nil, &runtime.JSONBuiltin{}, w, req, err)
- return
- }
- ctx, cancel := context.WithCancel(req.Context())
- defer cancel()
- if cn, ok := w.(http.CloseNotifier); ok {
- go func(done <-chan struct{}, closed <-chan bool) {
- select {
- case <-done:
- case <-closed:
- cancel()
- }
- }(ctx.Done(), cn.CloseNotify())
- }
- inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
- rctx, err := runtime.AnnotateContext(ctx, mux, req)
- if err != nil {
- // grpclog.Errorf("runtime.AnnotateContext returns error: %v", err)
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
- resp, md, err := request_EchoService_Echo_4(rctx, inboundMarshaler, cli, req, pathParams)
- ctx = runtime.NewServerMetadataContext(ctx, md)
- if err != nil {
- // grpclog.Errorf("request_%s_%s_%s returns error: %v", "EchoService", "Echo", "4", err)
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
-
- forward_EchoService_Echo_4(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
- })
-
- runtime.AddMethod(spec, "EchoService", "EchoBody", "/v1/example/echo_body", "POST", true, false, false, "UNSPECIFIED", "EASE_GATEWAY", "EASE_AUTH_TOKEN", "")
- mux.Handle("POST", pattern_EchoService_EchoBody_0, vexpb.ServiceId_CUSTOM_EASE_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
- // TODO(mojz): review all locking/unlocking logic.
- // internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RLock()
- // defer internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RUnlock()
- cli := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_client
- if cli == nil {
- runtime.DefaultOtherErrorHandler(w, req, "service disabled", http.StatusInternalServerError)
- return
- }
-
- ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec, "EchoService", "EchoBody", w, req)
- if err != nil {
- // grpclog.Errorf("runtime.RequestAccepted returns error: %v", err)
- runtime.HTTPError(ctx, nil, &runtime.JSONBuiltin{}, w, req, err)
- return
- }
- ctx, cancel := context.WithCancel(req.Context())
- defer cancel()
- if cn, ok := w.(http.CloseNotifier); ok {
- go func(done <-chan struct{}, closed <-chan bool) {
- select {
- case <-done:
- case <-closed:
- cancel()
- }
- }(ctx.Done(), cn.CloseNotify())
- }
- inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
- rctx, err := runtime.AnnotateContext(ctx, mux, req)
- if err != nil {
- // grpclog.Errorf("runtime.AnnotateContext returns error: %v", err)
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
- resp, md, err := request_EchoService_EchoBody_0(rctx, inboundMarshaler, cli, req, pathParams)
- ctx = runtime.NewServerMetadataContext(ctx, md)
- if err != nil {
- // grpclog.Errorf("request_%s_%s_%s returns error: %v", "EchoService", "EchoBody", "0", err)
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
-
- forward_EchoService_EchoBody_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
- })
-
- runtime.AddMethod(spec, "EchoService", "EchoDelete", "/v1/example/echo_delete", "DELETE", true, false, false, "UNSPECIFIED", "EASE_GATEWAY", "EASE_AUTH_TOKEN", "")
- mux.Handle("DELETE", pattern_EchoService_EchoDelete_0, vexpb.ServiceId_CUSTOM_EASE_GATEWAY_TEST, func(inctx context.Context, w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
- // TODO(mojz): review all locking/unlocking logic.
- // internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RLock()
- // defer internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.RUnlock()
- cli := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_client
- if cli == nil {
- runtime.DefaultOtherErrorHandler(w, req, "service disabled", http.StatusInternalServerError)
- return
- }
-
- ctx, err := runtime.RequestAccepted(inctx, internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec, "EchoService", "EchoDelete", w, req)
- if err != nil {
- // grpclog.Errorf("runtime.RequestAccepted returns error: %v", err)
- runtime.HTTPError(ctx, nil, &runtime.JSONBuiltin{}, w, req, err)
- return
- }
- ctx, cancel := context.WithCancel(req.Context())
- defer cancel()
- if cn, ok := w.(http.CloseNotifier); ok {
- go func(done <-chan struct{}, closed <-chan bool) {
- select {
- case <-done:
- case <-closed:
- cancel()
- }
- }(ctx.Done(), cn.CloseNotify())
- }
- inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
- rctx, err := runtime.AnnotateContext(ctx, mux, req)
- if err != nil {
- // grpclog.Errorf("runtime.AnnotateContext returns error: %v", err)
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
- resp, md, err := request_EchoService_EchoDelete_0(rctx, inboundMarshaler, cli, req, pathParams)
- ctx = runtime.NewServerMetadataContext(ctx, md)
- if err != nil {
- // grpclog.Errorf("request_%s_%s_%s returns error: %v", "EchoService", "EchoDelete", "0", err)
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
- return
- }
-
- forward_EchoService_EchoDelete_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
- })
-
- return nil
-}
-
-func Disable_CUSTOM_EASE_GATEWAY_TEST__default__grpc_ServiceGroup() {
- // internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.Lock()
- // defer internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.Unlock()
- if internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_skycli != nil {
- spec := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec
- sg := runtime.GetServiceGroup(spec)
- for _, svc := range sg.Services {
- svc.Disable()
- }
-
- internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_client = nil
- internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_skycli.Shutdown()
- internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_skycli = nil
- }
-}
-
-func Enable_CUSTOM_EASE_GATEWAY_TEST__default__grpc_ServiceGroup() {
- // internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.Lock()
- // defer internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock.Unlock()
-
- internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_skycli = client.NewServiceCli(runtime.CallerServiceId)
-
- // Resolve service
- spec := internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec
-
- internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_skycli.Resolve(spec)
-
- internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_skycli.EnableResolveFullEps()
- internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_skycli.Start(func(spec *skypb.ServiceSpec, conn *grpc.ClientConn) {
- sg := runtime.GetServiceGroup(spec)
- for _, svc := range sg.Services {
- svc.Enable(spec, conn)
- }
- })
-}
-
-func EnableEchoService_Service(spec *skypb.ServiceSpec, conn *grpc.ClientConn) {
- internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_client = NewEchoServiceClient(conn)
-}
-
-func DisableEchoService_Service() {
- internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_client = nil
-}
-
-var (
- pattern_EchoService_Echo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "example", "echo", "id"}, "", runtime.AssumeColonVerbOpt(true)))
-
- pattern_EchoService_Echo_1 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4}, []string{"v1", "example", "echo", "id", "num"}, "", runtime.AssumeColonVerbOpt(true)))
-
- pattern_EchoService_Echo_2 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"v1", "example", "echo", "id", "num", "lang"}, "", runtime.AssumeColonVerbOpt(true)))
-
- pattern_EchoService_Echo_3 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"v1", "example", "echo1", "id", "line_num", "status.note"}, "", runtime.AssumeColonVerbOpt(true)))
-
- pattern_EchoService_Echo_4 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "example", "echo2", "no.note"}, "", runtime.AssumeColonVerbOpt(true)))
-
- pattern_EchoService_EchoBody_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "example", "echo_body"}, "", runtime.AssumeColonVerbOpt(true)))
-
- pattern_EchoService_EchoDelete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "example", "echo_delete"}, "", runtime.AssumeColonVerbOpt(true)))
-)
-
-var (
- forward_EchoService_Echo_0 = runtime.ForwardResponseMessage
-
- forward_EchoService_Echo_1 = runtime.ForwardResponseMessage
-
- forward_EchoService_Echo_2 = runtime.ForwardResponseMessage
-
- forward_EchoService_Echo_3 = runtime.ForwardResponseMessage
-
- forward_EchoService_Echo_4 = runtime.ForwardResponseMessage
-
- forward_EchoService_EchoBody_0 = runtime.ForwardResponseMessage
-
- forward_EchoService_EchoDelete_0 = runtime.ForwardResponseMessage
-)
-
-var (
- internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_spec = client.NewServiceSpec("default", vexpb.ServiceId_CUSTOM_EASE_GATEWAY_TEST, "grpc")
- internal_EchoService_CUSTOM_EASE_GATEWAY_TEST_client EchoServiceClient
-
- internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_skycli client.ServiceCli
-
- internal_CUSTOM_EASE_GATEWAY_TEST__default__grpc_lock = sync.RWMutex{}
-)
diff --git a/proto/pom.xml b/proto/pom.xml
index bd06821..9724b50 100755
--- a/proto/pom.xml
+++ b/proto/pom.xml
@@ -2,8 +2,8 @@
4.0.0
- com.binchencoder.easegw
- easegw-proto
+ com.binchencoder.gateway
+ janus-proto
pom
1.0-SNAPSHOT
@@ -39,6 +39,18 @@
+
+ com.binchencoder.gateway
+ data-proto
+ 1.0-SNAPSHOT
+
+
+ com.binchencoder.gateway
+ janus-options-protos
+ 1.0-SNAPSHOT
+ provided
+
+
io.grpc
grpc-protobuf
@@ -70,12 +82,6 @@
-
-
- com.binchencoder.gateway
- data-proto
- 1.0-SNAPSHOT
-
@@ -140,10 +146,10 @@
com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}
grpc-java
io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
- ../../
+ ../
- ease-gateway/proto/*/*.proto
- ease-gateway/proto/*/*/*.proto
+ proto/*/*.proto
+ proto/*/*/*.proto
diff --git a/renovate.json b/renovate.json
new file mode 100644
index 0000000..b731f05
--- /dev/null
+++ b/renovate.json
@@ -0,0 +1,53 @@
+{
+ "extends": [
+ "config:base"
+ ],
+ "baseBranches": [
+ "v1",
+ "master"
+ ],
+ "postUpdateOptions": [
+ "gomodTidy"
+ ],
+ "packageRules": [
+ {
+ "updateTypes": [
+ "minor",
+ "patch",
+ "pin",
+ "digest"
+ ],
+ "automerge": true
+ },
+ {
+ "baseBranchList": [
+ "v1"
+ ],
+ "packageNames": [
+ "github.com/golang/protobuf",
+ "google.golang.org/genproto",
+ "io_bazel_rules_go",
+ "golang.org/x/oauth2",
+ "google.golang.org/grpc"
+ ],
+ "enabled": false
+ },
+ {
+ "baseBranchList": [
+ "master"
+ ],
+ "packageNames": [
+ "github.com/golang/protobuf",
+ "google.golang.org/protobuf"
+ ],
+ "groupName": "golang/protobuf"
+ },
+ {
+ "packagePatterns": [
+ "jekyll.*",
+ "github-pages"
+ ],
+ "enabled": false
+ }
+ ]
+}
diff --git a/repositories.bzl b/repositories.bzl
index 2484216..299ddda 100644
--- a/repositories.bzl
+++ b/repositories.bzl
@@ -1,42 +1,47 @@
load("@bazel_gazelle//:deps.bzl", "go_repository")
def go_repositories():
+ go_repository(
+ name = "com_github_binchencoder_janus_gateway",
+ importpath = "github.com/binchencoder/janus-gateway",
+ sum = "h1:wYZv8TO4TGO2U8HjEO5Odf8OYWQjfrXS8ddfGZWQfHI=",
+ version = "v1.0.3",
+ )
go_repository(
name = "com_github_binchencoder_letsgo",
importpath = "github.com/binchencoder/letsgo",
- sum = "h1:hEDDOeGdX9R/JPYMdVo9N/9iQa5BeBLluTssrNYy/ng=",
- version = "v0.0.3",
+ sum = "h1:wYZv8TO4TGO2U8HjEO5Odf8OYWQjfrXS8ddfGZWQfHI=",
+ version = "v0.0.5",
)
go_repository(
name = "com_github_binchencoder_skylb_api",
importpath = "github.com/binchencoder/skylb-api",
- sum = "h1:NnlPmEjTgOjH+s9TK3rBEY4Kn9aEzZkuEBUV2aR8UTM=",
- version = "v0.0.3",
+ sum = "h1:CUhectaG+rrLs9pnfS9lvg6LqLD8Il4GyRTlNXNmS8Q=",
+ version = "v0.3.1",
)
go_repository(
name = "com_github_binchencoder_gateway_proto",
importpath = "github.com/binchencoder/gateway-proto",
- sum = "h1:xU2ZVx5Zjub5P/WIl12FeCII1vGdV2THWtfm7fUR7z8=",
- version = "v0.0.3",
+ sum = "h1:+B4hxnqdYOP2DErADRLNpP0tTxEqYxAugQ0EDMpPxZc=",
+ version = "v0.0.9",
)
-
go_repository(
- name = "com_github_grpc_ecosystem_grpc_gateway",
- importpath = "github.com/grpc-ecosystem/grpc-gateway",
- sum = "h1:zCy2xE9ablevUOrUZc3Dl72Dt+ya2FNAvC2yLYMHzi4=",
- version = "v1.12.1",
+ name = "com_github_armon_circbuf",
+ importpath = "github.com/armon/circbuf",
+ sum = "h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA=",
+ version = "v0.0.0-20150827004946-bbbad097214e",
)
go_repository(
- name = "com_github_grpc_ecosystem_grpc_opentracing",
- importpath = "github.com/grpc-ecosystem/grpc-opentracing",
- sum = "h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU=",
- version = "v0.0.0-20180507213350-8e809c8a8645",
+ name = "com_github_armon_go_metrics",
+ importpath = "github.com/armon/go-metrics",
+ sum = "h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I=",
+ version = "v0.0.0-20180917152333-f0300d1749da",
)
go_repository(
- name = "com_github_grpc_ecosystem_go_grpc_middleware",
- importpath = "github.com/grpc-ecosystem/go-grpc-middleware",
- sum = "h1:0IKlLyQ3Hs9nDaiK5cSHAGmcQEIC8l2Ts1u6x5Dfrqg=",
- version = "v1.2.0",
+ name = "com_github_armon_go_radix",
+ importpath = "github.com/armon/go-radix",
+ sum = "h1:BUAU3CGlLvorLI26FmByPp2eC2qla6E1Tw+scpcg/to=",
+ version = "v0.0.0-20180808171621-7fddfc383310",
)
go_repository(
name = "com_github_beorn7_perks",
@@ -53,9 +58,16 @@ def go_repositories():
go_repository(
name = "com_github_fatih_color",
importpath = "github.com/fatih/color",
- sum = "h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=",
- version = "v1.9.0",
+ sum = "h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=",
+ version = "v1.7.0",
)
+ go_repository(
+ name = "com_github_fsnotify_fsnotify",
+ importpath = "github.com/fsnotify/fsnotify",
+ sum = "h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=",
+ version = "v1.4.7",
+ )
+
go_repository(
name = "com_github_ghodss_yaml",
importpath = "github.com/ghodss/yaml",
@@ -65,15 +77,42 @@ def go_repositories():
go_repository(
name = "com_github_golang_glog",
importpath = "github.com/golang/glog",
- sum = "h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=",
- version = "v0.0.0-20160126235308-23def4e6c14b",
+ sum = "h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=",
+ version = "v1.0.0",
)
+
go_repository(
- name = "com_github_google_uuid",
- importpath = "github.com/google/uuid",
- sum = "h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=",
- version = "v1.1.1",
+ name = "com_github_golang_groupcache",
+ importpath = "github.com/golang/groupcache",
+ sum = "h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=",
+ version = "v0.0.0-20200121045136-8c9f03a8e57e",
+ )
+ go_repository(
+ name = "com_github_golang_mock",
+ importpath = "github.com/golang/mock",
+ sum = "h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=",
+ version = "v1.4.4",
)
+ go_repository(
+ name = "com_github_golang_protobuf",
+ importpath = "github.com/golang/protobuf",
+ sum = "h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=",
+ version = "v1.5.2",
+ )
+
+ go_repository(
+ name = "com_github_google_btree",
+ importpath = "github.com/google/btree",
+ sum = "h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=",
+ version = "v1.0.0",
+ )
+ go_repository(
+ name = "com_github_google_go_cmp",
+ importpath = "github.com/google/go-cmp",
+ sum = "h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=",
+ version = "v0.5.7",
+ )
+
go_repository(
name = "com_github_klauspost_cpuid",
importpath = "github.com/klauspost/cpuid",
@@ -93,11 +132,36 @@ def go_repositories():
version = "v0.1.7",
)
go_repository(
- name = "com_github_pborman_uuid",
- importpath = "github.com/pborman/uuid",
- sum = "h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=",
+ name = "com_github_google_uuid",
+ importpath = "github.com/google/uuid",
+ sum = "h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=",
+ version = "v1.1.2",
+ )
+
+ go_repository(
+ name = "com_github_grpc_ecosystem_go_grpc_middleware",
+ importpath = "github.com/grpc-ecosystem/go-grpc-middleware",
+ sum = "h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c=",
+ version = "v1.0.0",
+ )
+ go_repository(
+ name = "com_github_grpc_ecosystem_go_grpc_prometheus",
+ importpath = "github.com/grpc-ecosystem/go-grpc-prometheus",
+ sum = "h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=",
version = "v1.2.0",
)
+ go_repository(
+ name = "com_github_grpc_ecosystem_grpc_gateway",
+ importpath = "github.com/grpc-ecosystem/grpc-gateway/v2",
+ sum = "h1:SLkFeyLhrg86Ny5Wme4MGGace7EHfgsb07uWX/QUGEQ=",
+ version = "v2.9.0",
+ )
+ go_repository(
+ name = "com_github_grpc_ecosystem_grpc_opentracing",
+ importpath = "github.com/grpc-ecosystem/grpc-opentracing",
+ sum = "h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU=",
+ version = "v0.0.0-20180507213350-8e809c8a8645",
+ )
go_repository(
name = "com_github_go_kit_kit",
importpath = "github.com/go-kit/kit",
@@ -110,17 +174,11 @@ def go_repositories():
sum = "h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=",
version = "v0.9.1",
)
- go_repository(
- name = "com_github_vividcortex_gohistogram",
- importpath = "github.com/VividCortex/gohistogram",
- sum = "h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=",
- version = "v1.0.0",
- )
go_repository(
name = "com_github_klauspost_compress",
importpath = "github.com/klauspost/compress",
- sum = "h1:a/y8CglcM7gLGYmlbP/stPE5sR3hbhFRUjCBfd/0B3I=",
- version = "v1.10.10",
+ sum = "h1:0hzRabrMN4tSTvMfnL3SCv1ZGeAP23ynzodBgaHeMeg=",
+ version = "v1.11.7",
)
go_repository(
name = "com_github_opentracing_opentracing_go",
@@ -129,16 +187,60 @@ def go_repositories():
version = "v1.2.0",
)
go_repository(
- name = "com_github_matttproud_golang_protobuf_extension",
+ name = "com_github_matttproud_golang_protobuf_extensions",
importpath = "github.com/matttproud/golang_protobuf_extensions",
sum = "h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=",
version = "v1.0.1",
)
+
go_repository(
- name = "com_github_stretchr_testify",
- importpath = "github.com/stretchr/testify",
- sum = "h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=",
- version = "v1.6.1",
+ name = "com_github_pborman_uuid",
+ importpath = "github.com/pborman/uuid",
+ sum = "h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=",
+ version = "v1.2.0",
+ )
+ # Prometheus
+ go_repository(
+ name = "com_github_prometheus_client_golang",
+ importpath = "github.com/prometheus/client_golang",
+ sum = "h1:Y8E/JaaPbmFSW2V81Ab/d8yZFYQQGbni1b1jPcG9Y6A=",
+ version = "v0.9.4",
+ )
+ go_repository(
+ name = "com_github_prometheus_client_model",
+ importpath = "github.com/prometheus/client_model",
+ sum = "h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=",
+ version = "v0.2.0",
+ )
+ go_repository(
+ name = "com_github_prometheus_common",
+ importpath = "github.com/prometheus/common",
+ sum = "h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc=",
+ version = "v0.10.0",
+ )
+ go_repository(
+ name = "com_github_prometheus_procfs",
+ importpath = "github.com/prometheus/procfs",
+ sum = "h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=",
+ version = "v0.1.3",
+ )
+ go_repository(
+ name = "com_github_prometheus_tsdb",
+ importpath = "github.com/prometheus/tsdb",
+ sum = "h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA=",
+ version = "v0.7.1",
+ )
+ go_repository(
+ name = "com_github_smartystreets_assertions",
+ importpath = "github.com/smartystreets/assertions",
+ sum = "h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=",
+ version = "v0.0.0-20180927180507-b2de0cb4f26d",
+ )
+ go_repository(
+ name = "com_github_smartystreets_goconvey",
+ importpath = "github.com/smartystreets/goconvey",
+ sum = "h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=",
+ version = "v1.6.4",
)
go_repository(
name = "com_github_soheilhy_cmux",
@@ -159,57 +261,196 @@ def go_repositories():
version = "v2.2.0+incompatible",
)
go_repository(
- name = "com_github_prometheus_client_golang",
- importpath = "github.com/prometheus/client_golang",
- sum = "h1:Y8E/JaaPbmFSW2V81Ab/d8yZFYQQGbni1b1jPcG9Y6A=",
- version = "v0.9.4",
+ name = "com_github_rogpeppe_fastuuid",
+ importpath = "github.com/rogpeppe/fastuuid",
+ sum = "h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s=",
+ version = "v1.2.0",
)
go_repository(
- name = "com_github_prometheus_client_model",
- importpath = "github.com/prometheus/client_model",
- sum = "h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=",
- version = "v0.2.0",
+ name = "com_github_stretchr_objx",
+ importpath = "github.com/stretchr/objx",
+ sum = "h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=",
+ version = "v0.1.0",
)
go_repository(
- name = "com_github_prometheus_common",
- importpath = "github.com/prometheus/common",
- sum = "h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc=",
- version = "v0.10.0",
+ name = "com_github_stretchr_testify",
+ importpath = "github.com/stretchr/testify",
+ sum = "h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=",
+ version = "v1.7.0",
)
go_repository(
- name = "com_github_prometheus_procfs",
- importpath = "github.com/prometheus/procfs",
- sum = "h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=",
- version = "v0.1.3",
+ name = "com_github_vividcortex_gohistogram",
+ importpath = "github.com/VividCortex/gohistogram",
+ sum = "h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=",
+ version = "v1.0.0",
)
+
go_repository(
name = "in_gopkg_yaml_v2",
importpath = "gopkg.in/yaml.v2",
- sum = "h1:uUkhRGrsEyx/laRdeS6YIQKIys8pg+lRSRdVMTYjivs=",
- version = "v2.0.0",
+ sum = "h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=",
+ version = "v2.4.0",
)
go_repository(
name = "in_gopkg_yaml_v3",
importpath = "gopkg.in/yaml.v3",
- sum = "h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=",
- version = "v3.0.0-20200615113413-eeeca48fe776",
+ sum = "h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=",
+ version = "v3.0.0-20200313102051-9f266ea9e77c",
+ )
+ go_repository(
+ name = "io_etcd_go_bbolt",
+ importpath = "go.etcd.io/bbolt",
+ sum = "h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk=",
+ version = "v1.3.2",
+ )
+ go_repository(
+ name = "io_k8s_sigs_yaml",
+ importpath = "sigs.k8s.io/yaml",
+ sum = "h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=",
+ version = "v1.3.0",
)
+ go_repository(
+ name = "org_golang_google_genproto",
+ importpath = "google.golang.org/genproto",
+ sum = "h1:0m9wktIpOxGw+SSKmydXWB3Z3GTfcPP6+q75HCQa6HI=",
+ version = "v0.0.0-20220324131243-acbaeb5b85eb",
+ )
go_repository(
name = "org_golang_google_grpc",
importpath = "google.golang.org/grpc",
- sum = "h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=",
- version = "v1.27.1",
+ sum = "h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M=",
+ version = "v1.45.0",
+ )
+
+ go_repository(
+ name = "org_golang_google_grpc_cmd_protoc_gen_go_grpc",
+ importpath = "google.golang.org/grpc/cmd/protoc-gen-go-grpc",
+ sum = "h1:lQ+dE99pFsb8osbJB3oRfE5eW4Hx6a/lZQr8Jh+eoT4=",
+ version = "v1.0.0",
+ )
+ go_repository(
+ name = "org_golang_google_protobuf",
+ importpath = "google.golang.org/protobuf",
+ sum = "h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=",
+ version = "v1.28.0",
+ )
+ go_repository(
+ name = "org_golang_x_crypto",
+ importpath = "golang.org/x/crypto",
+ sum = "h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=",
+ version = "v0.0.0-20200622213623-75b288015ac9",
+ )
+ go_repository(
+ name = "org_golang_x_exp",
+ importpath = "golang.org/x/exp",
+ sum = "h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y=",
+ version = "v0.0.0-20200224162631-6cc2880d07d6",
+ )
+
+ go_repository(
+ name = "org_golang_x_image",
+ importpath = "golang.org/x/image",
+ sum = "h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4=",
+ version = "v0.0.0-20190802002840-cff245a6509b",
+ )
+ go_repository(
+ name = "org_golang_x_lint",
+ importpath = "golang.org/x/lint",
+ sum = "h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=",
+ version = "v0.0.0-20200302205851-738671d3881b",
+ )
+
+ go_repository(
+ name = "org_golang_x_mobile",
+ importpath = "golang.org/x/mobile",
+ sum = "h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs=",
+ version = "v0.0.0-20190719004257-d2bd2a29d028",
+ )
+ go_repository(
+ name = "org_golang_x_mod",
+ importpath = "golang.org/x/mod",
+ sum = "h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=",
+ version = "v0.3.0",
+ )
+ go_repository(
+ name = "org_golang_x_net",
+ importpath = "golang.org/x/net",
+ sum = "h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=",
+ version = "v0.0.0-20220127200216-cd36cc0744dd",
)
go_repository(
name = "org_golang_x_oauth2",
importpath = "golang.org/x/oauth2",
- sum = "h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=",
- version = "v0.0.0-20200107190931-bf48bf16ab8d",
+ sum = "h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM=",
+ version = "v0.0.0-20220309155454-6242fa91716a",
+ )
+ go_repository(
+ name = "org_golang_x_sync",
+ importpath = "golang.org/x/sync",
+ sum = "h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=",
+ version = "v0.0.0-20200625203802-6e8e738ad208",
+ )
+ go_repository(
+ name = "org_golang_x_sys",
+ importpath = "golang.org/x/sys",
+ sum = "h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=",
+ version = "v0.0.0-20211216021012-1d35b9e2eb4e",
+ )
+ go_repository(
+ name = "org_golang_x_term",
+ importpath = "golang.org/x/term",
+ sum = "h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=",
+ version = "v0.0.0-20210927222741-03fcf44c2211",
+ )
+
+ go_repository(
+ name = "org_golang_x_text",
+ importpath = "golang.org/x/text",
+ sum = "h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=",
+ version = "v0.3.7",
+ )
+
+ go_repository(
+ name = "org_golang_x_time",
+ importpath = "golang.org/x/time",
+ sum = "h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=",
+ version = "v0.0.0-20191024005414-555d28b269f0",
+ )
+ go_repository(
+ name = "org_golang_x_tools",
+ importpath = "golang.org/x/tools",
+ sum = "h1:W07d4xkoAUSNOkOzdzXCdFGxT7o2rW4q8M34tB2i//k=",
+ version = "v0.0.0-20200825202427-b303f430e36d",
+ )
+
+ go_repository(
+ name = "org_golang_x_xerrors",
+ importpath = "golang.org/x/xerrors",
+ sum = "h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=",
+ version = "v0.0.0-20200804184101-5ec99f83aff1",
)
go_repository(
name = "org_uber_go_atomic",
importpath = "go.uber.org/atomic",
- sum = "h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=",
+ sum = "h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=",
+ version = "v1.7.0",
+ )
+ go_repository(
+ name = "org_uber_go_multierr",
+ importpath = "go.uber.org/multierr",
+ sum = "h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=",
version = "v1.6.0",
+ )
+ go_repository(
+ name = "org_uber_go_tools",
+ importpath = "go.uber.org/tools",
+ sum = "h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=",
+ version = "v0.0.0-20190618225709-2cfd321de3ee",
+ )
+ go_repository(
+ name = "org_uber_go_zap",
+ importpath = "go.uber.org/zap",
+ sum = "h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM=",
+ version = "v1.16.0",
)
\ No newline at end of file
diff --git a/util/BUILD.bazel b/util/BUILD.bazel
index 6de1b86..2a8810e 100755
--- a/util/BUILD.bazel
+++ b/util/BUILD.bazel
@@ -10,7 +10,7 @@ go_library(
["*.go"],
exclude = ["*_test.go"],
),
- importpath = "github.com/binchencoder/ease-gateway/util",
+ importpath = "github.com/binchencoder/janus-gateway/util",
deps = [
"//util/glog:go_default_library",
"@com_github_fatih_color//:go_default_library",
diff --git a/util/glog/BUILD.bazel b/util/glog/BUILD.bazel
index d6888fb..56b648e 100755
--- a/util/glog/BUILD.bazel
+++ b/util/glog/BUILD.bazel
@@ -8,7 +8,7 @@ go_library(
["*.go"],
exclude = ["*_test.go"],
),
- importpath = "github.com/binchencoder/ease-gateway/util/glog",
+ importpath = "github.com/binchencoder/janus-gateway/util/glog",
deps = [
"@com_github_binchencoder_letsgo//trace:go_default_library",
"@org_golang_x_net//context:go_default_library",
diff --git a/util/glog/cmd/BUILD.bazel b/util/glog/cmd/BUILD.bazel
index 97c7aca..2b3c7f0 100644
--- a/util/glog/cmd/BUILD.bazel
+++ b/util/glog/cmd/BUILD.bazel
@@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
go_library(
name = "go_default_library",
srcs = ["main.go"],
- importpath = "github.com/binchencoder/ease-gateway/util/glog/cmd",
+ importpath = "github.com/binchencoder/janus-gateway/util/glog/cmd",
visibility = ["//visibility:private"],
deps = ["//util/glog:go_default_library"],
)
diff --git a/util/glog/cmd/main.go b/util/glog/cmd/main.go
index b0285e2..75c9145 100755
--- a/util/glog/cmd/main.go
+++ b/util/glog/cmd/main.go
@@ -3,7 +3,7 @@ package main
import (
"flag"
- "github.com/binchencoder/ease-gateway/util/glog"
+ "github.com/binchencoder/janus-gateway/util/glog"
)
func main() {
diff --git a/util/log.go b/util/log.go
index 0fc7645..750137e 100755
--- a/util/log.go
+++ b/util/log.go
@@ -3,7 +3,7 @@ package util
import (
col "github.com/fatih/color"
- "github.com/binchencoder/ease-gateway/util/glog"
+ "github.com/binchencoder/janus-gateway/util/glog"
)
func init() {
@@ -12,7 +12,7 @@ func init() {
// gateway-rest日志
var (
- // ease-gateway 请求和响应详情日志. 支持格式包括:
+ // janus-gateway 请求和响应详情日志. 支持格式包括:
// 1. RequestRestFormat
// 2. ResponseRestFormat
RestLogger = glog.Context(nil, glog.FileName{Name: "gateway-rest"})
@@ -30,13 +30,13 @@ var (
// gateway-config日志
var (
- // ease-gateway 配置操作相关日志.
+ // janus-gateway 配置操作相关日志.
ConfigLogger = glog.Context(nil, glog.FileName{Name: "gateway-config"})
)
// gateway-stat日志
var (
- // ease-gateway 访问统计日志. 支持格式包括:
+ // janus-gateway 访问统计日志. 支持格式包括:
// 1. StatFormat
StatLogger = glog.Context(nil, glog.FileName{Name: "gateway-stat"})