diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 0000000..a314905 --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,18 @@ +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2021-03-25T21:15:43Z by kres 424ae88-dirty. + +codecov: +require_ci_to_pass: false + +coverage: +status: + project: + default: + target: 50% + threshold: 0.5% + base: auto + if_ci_failed: success + patch: off + +comment: false diff --git a/.conform.yaml b/.conform.yaml new file mode 100644 index 0000000..d686576 --- /dev/null +++ b/.conform.yaml @@ -0,0 +1,22 @@ +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2021-03-25T21:16:46Z by kres 424ae88-dirty. + +policies: +- type: commit + spec: + dco: true + gpg: false + spellcheck: + locale: US + maximumOfOneCommit: true + header: + length: 89 + imperative: true + case: lower + invalidLastCharacters: . + body: + required: true + conventional: + types: ["chore","docs","perf","refactor","style","test","release"] + scopes: ["*"] \ No newline at end of file diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..2b853a8 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,12 @@ +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2021-03-25T21:15:43Z by kres 424ae88-dirty. + +** +!proxy +!testservice +!go.mod +!go.sum +!.golangci.yml +!README.md +!.markdownlint.json diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..9bc48ad --- /dev/null +++ b/.drone.yml @@ -0,0 +1,194 @@ +--- +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2021-03-25T21:15:43Z by kres 424ae88-dirty. + +kind: pipeline +type: kubernetes +name: default + +platform: + os: linux + arch: amd64 + +steps: +- name: setup-ci + pull: always + image: autonomy/build-container:latest + commands: + - sleep 5 + - git fetch --tags + - install-ci-key + - docker buildx create --driver docker-container --platform linux/amd64 --name local --use unix:///var/outer-run/docker.sock + - docker buildx inspect --bootstrap + environment: + SSH_KEY: + from_secret: ssh_key + volumes: + - name: outer-docker-socket + path: /var/outer-run + - name: docker-socket + path: /var/run + - name: buildx + path: /root/.docker/buildx + - name: ssh + path: /root/.ssh + +- name: base + pull: always + image: autonomy/build-container:latest + commands: + - make base + volumes: + - name: outer-docker-socket + path: /var/outer-run + - name: docker-socket + path: /var/run + - name: buildx + path: /root/.docker/buildx + - name: ssh + path: /root/.ssh + depends_on: + - setup-ci + +- name: unit-tests + pull: always + image: autonomy/build-container:latest + commands: + - make unit-tests + volumes: + - name: outer-docker-socket + path: /var/outer-run + - name: docker-socket + path: /var/run + - name: buildx + path: /root/.docker/buildx + - name: ssh + path: /root/.ssh + depends_on: + - base + +- name: unit-tests-race + pull: always + image: autonomy/build-container:latest + commands: + - make unit-tests-race + volumes: + - name: outer-docker-socket + path: /var/outer-run + - name: docker-socket + path: /var/run + - name: buildx + path: /root/.docker/buildx + - name: ssh + path: /root/.ssh + depends_on: + - base + +- name: coverage + pull: always + image: autonomy/build-container:latest + commands: + - make coverage + environment: + CODECOV_TOKEN: + from_secret: CODECOV_TOKEN + volumes: + - name: outer-docker-socket + path: /var/outer-run + - name: docker-socket + path: /var/run + - name: buildx + path: /root/.docker/buildx + - name: ssh + path: /root/.ssh + depends_on: + - unit-tests + +- name: lint + pull: always + image: autonomy/build-container:latest + commands: + - make lint + volumes: + - name: outer-docker-socket + path: /var/outer-run + - name: docker-socket + path: /var/run + - name: buildx + path: /root/.docker/buildx + - name: ssh + path: /root/.ssh + depends_on: + - base + +services: +- name: docker + image: docker:19.03-dind + entrypoint: + - dockerd + commands: + - --dns=8.8.8.8 + - --dns=8.8.4.4 + - --mtu=1500 + - --log-level=error + privileged: true + volumes: + - name: outer-docker-socket + path: /var/outer-run + - name: docker-socket + path: /var/run + - name: buildx + path: /root/.docker/buildx + - name: ssh + path: /root/.ssh + +volumes: +- name: outer-docker-socket + host: + path: /var/ci-docker +- name: docker-socket + temp: + medium: memory +- name: buildx + temp: + medium: memory +- name: ssh + temp: + medium: memory + +--- +kind: pipeline +type: kubernetes +name: notify + +platform: + os: linux + arch: amd64 + +clone: + disable: true + +steps: +- name: slack + image: plugins/slack + settings: + channel: proj-talos-maintainers + link_names: true + template: "{{#if build.pull }}\n*{{#success build.status}}✓ Success{{else}}✕ Fail{{/success}}*: {{ repo.owner }}/{{ repo.name }} - \n{{else}}\n*{{#success build.status}}✓ Success{{else}}✕ Fail{{/success}}: {{ repo.owner }}/{{ repo.name }} - Build #{{ build.number }}* (type: `{{ build.event }}`)\n{{/if}}\nCommit: \nBranch: \nAuthor: {{ build.author }}\n<{{ build.link }}|Visit build page>" + webhook: + from_secret: slack_webhook + when: + status: + - success + - failure + +trigger: + status: + - success + - failure + +depends_on: +- default + +... diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml deleted file mode 100644 index 12bff73..0000000 --- a/.github/workflows/go.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: Go -on: - - push - - pull_request -jobs: - - build: - name: Build - runs-on: ubuntu-latest - steps: - - - name: Set up Go 1.13 - uses: actions/setup-go@v1 - with: - go-version: 1.13 - id: go - - - name: Check out code into the Go module directory - uses: actions/checkout@v1 - - - name: Get dependencies - run: | - go mod download - go mod verify - go list -mod=readonly all >/dev/null - - - name: Test - run: | - go test -v -coverprofile coverage.txt -covermode=atomic ./... - - - name: Test Race - run: | - go test -v -race ./... - - - name: Upload Coverage report to CodeCov - uses: codecov/codecov-action@v1.0.0 - with: - token: ${{secrets.CODECOV_TOKEN}} - file: ./coverage.txt - if: github.event_name == 'push' - - lint: - name: Lint - runs-on: ubuntu-latest - steps: - - name: Check out code into the Go module directory - uses: actions/checkout@v1 - - - name: Run GolangCI-Lint - uses: actions-contrib/golangci-lint@master - with: - args: run diff --git a/.gitignore b/.gitignore index 0152f2c..f63299f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,26 +1,5 @@ -.idea +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2021-03-25T21:15:43Z by kres 424ae88-dirty. -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof \ No newline at end of file +_out diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..d5c3d2c --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,150 @@ +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2021-03-25T21:15:43Z by kres 424ae88-dirty. + + +# options for analysis running +run: + timeout: 10m + issues-exit-code: 1 + tests: true + build-tags: [] + skip-dirs: [] + skip-dirs-use-default: true + skip-files: [] + modules-download-mode: readonly + +# output configuration options +output: + format: colored-line-number + print-issued-lines: true + print-linter-name: true + uniq-by-line: true + path-prefix: "" + + +# all available settings of specific linters +linters-settings: + dogsled: + max-blank-identifiers: 2 + dupl: + threshold: 150 + errcheck: + check-type-assertions: true + check-blank: true + exhaustive: + default-signifies-exhaustive: false + funlen: + lines: 60 + statements: 40 + gci: + local-prefixes: github.com/talos-systems/grpc-proxy + gocognit: + min-complexity: 30 + nestif: + min-complexity: 5 + goconst: + min-len: 3 + min-occurrences: 3 + gocritic: + disabled-checks: [] + gocyclo: + min-complexity: 20 + godot: + check-all: false + godox: + keywords: # default keywords are TODO, BUG, and FIXME, these can be overwritten by this setting + - NOTE + - OPTIMIZE # marks code that should be optimized before merging + - HACK # marks hack-arounds that should be removed before merging + gofmt: + simplify: true + goimports: + local-prefixes: github.com/talos-systems/grpc-proxy + golint: + min-confidence: 0.8 + gomnd: + settings: {} + gomodguard: {} + govet: + check-shadowing: true + enable-all: true + depguard: + list-type: blacklist + include-go-root: false + lll: + line-length: 200 + tab-width: 4 + misspell: + locale: US + ignore-words: [] + nakedret: + max-func-lines: 30 + prealloc: + simple: true + range-loops: true # Report preallocation suggestions on range loops, true by default + for-loops: false # Report preallocation suggestions on for loops, false by default + nolintlint: + allow-unused: false + allow-leading-space: false + allow-no-explanation: [] + require-explanation: false + require-specific: true + rowserrcheck: {} + testpackage: + unparam: + check-exported: false + unused: + check-exported: false + whitespace: + multi-if: false # Enforces newlines (or comments) after every multi-line if statement + multi-func: false # Enforces newlines (or comments) after every multi-line function signature + wsl: + strict-append: true + allow-assign-and-call: true + allow-multiline-assign: true + allow-cuddle-declarations: false + allow-trailing-comment: false + force-case-trailing-whitespace: 0 + force-err-cuddling: false + allow-separated-leading-comment: false + gofumpt: + extra-rules: false + cyclop: + # the maximal code complexity to report + max-complexity: 20 + +linters: + enable-all: true + disable: + - gas + - typecheck + - gochecknoglobals + - gochecknoinits + - funlen + - godox + - gomnd + - goerr113 + - nestif + - wrapcheck + - paralleltest + - exhaustivestruct + - forbidigo + disable-all: false + fast: false + + +issues: + exclude: [] + exclude-rules: [] + exclude-use-default: false + exclude-case-sensitive: false + max-issues-per-linter: 10 + max-same-issues: 3 + + new: false + +severity: + default-severity: error + + case-sensitive: false diff --git a/.kres.yaml b/.kres.yaml new file mode 100644 index 0000000..d7905c5 --- /dev/null +++ b/.kres.yaml @@ -0,0 +1,10 @@ +kind: common.Repository +spec: + conformLicenseCheck: false + enableLicense: false +--- +kind: golang.Protobuf +spec: + baseSpecPath: /testservice + specs: + - source: testservice/api/test.proto diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 0000000..f69f929 --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,9 @@ +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2021-03-25T21:15:43Z by kres 424ae88-dirty. + +{ + "MD013": false, + "MD033": false, + "default": true + } diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..98d871a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,87 @@ +# syntax = docker/dockerfile-upstream:1.2.0-labs + +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2021-03-25T21:36:57Z by kres 424ae88-dirty. + +ARG TOOLCHAIN + +# runs markdownlint +FROM node:14.8.0-alpine AS lint-markdown +RUN npm i -g markdownlint-cli@0.23.2 +RUN npm i sentences-per-line@0.2.1 +WORKDIR /src +COPY .markdownlint.json . +COPY ./README.md ./README.md +RUN markdownlint --ignore "**/node_modules/**" --ignore '**/hack/chglog/**' --rules /node_modules/sentences-per-line/index.js . + +# collects proto specs +FROM scratch AS proto-specs +ADD testservice/api/test.proto /testservice/ + +# base toolchain image +FROM ${TOOLCHAIN} AS toolchain +RUN apk --update --no-cache add bash curl build-base protoc protobuf-dev + +# build tools +FROM toolchain AS tools +ENV GO111MODULE on +ENV CGO_ENABLED 0 +ENV GOPATH /go +RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b /bin v1.38.0 +ARG GOFUMPT_VERSION +RUN cd $(mktemp -d) \ + && go mod init tmp \ + && go get mvdan.cc/gofumpt/gofumports@${GOFUMPT_VERSION} \ + && mv /go/bin/gofumports /bin/gofumports +ARG PROTOBUF_GO_VERSION +RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v${PROTOBUF_GO_VERSION} +RUN mv /go/bin/protoc-gen-go /bin +ARG GRPC_GO_VERSION +RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v${GRPC_GO_VERSION} +RUN mv /go/bin/protoc-gen-go-grpc /bin + +# tools and sources +FROM tools AS base +WORKDIR /src +COPY ./go.mod . +COPY ./go.sum . +RUN --mount=type=cache,target=/go/pkg go mod download +RUN --mount=type=cache,target=/go/pkg go mod verify +COPY ./proxy ./proxy +COPY ./testservice ./testservice +RUN --mount=type=cache,target=/go/pkg go list -mod=readonly all >/dev/null + +# runs protobuf compiler +FROM tools AS proto-compile +COPY --from=proto-specs / / +RUN protoc -I/testservice --go_out=paths=source_relative:/testservice --go-grpc_out=paths=source_relative:/testservice /testservice/test.proto + +# runs gofumpt +FROM base AS lint-gofumpt +RUN find . -name '*.pb.go' | xargs -r rm +RUN FILES="$(gofumports -l -local github.com/talos-systems/grpc-proxy .)" && test -z "${FILES}" || (echo -e "Source code is not formatted with 'gofumports -w -local github.com/talos-systems/grpc-proxy .':\n${FILES}"; exit 1) + +# runs golangci-lint +FROM base AS lint-golangci-lint +COPY .golangci.yml . +ENV GOGC 50 +RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/root/.cache/golangci-lint --mount=type=cache,target=/go/pkg golangci-lint run --config .golangci.yml + +# runs unit-tests with race detector +FROM base AS unit-tests-race +ARG TESTPKGS +RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg --mount=type=cache,target=/tmp CGO_ENABLED=1 go test -v -race -count 1 ${TESTPKGS} + +# runs unit-tests +FROM base AS unit-tests-run +ARG TESTPKGS +RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg --mount=type=cache,target=/tmp go test -v -covermode=atomic -coverprofile=coverage.txt -count 1 ${TESTPKGS} + +# cleaned up specs and compiled versions +FROM scratch AS generate +COPY --from=proto-compile /testservice/ /testservice/ + +FROM scratch AS unit-tests +COPY --from=unit-tests-run /src/coverage.txt /coverage.txt + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b18a1cf --- /dev/null +++ b/Makefile @@ -0,0 +1,136 @@ +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2021-03-25T21:36:57Z by kres 424ae88-dirty. + +# common variables + +SHA := $(shell git describe --match=none --always --abbrev=8 --dirty) +TAG := $(shell git describe --tag --always --dirty) +BRANCH := $(shell git rev-parse --abbrev-ref HEAD) +ARTIFACTS := _out +REGISTRY ?= ghcr.io +USERNAME ?= talos-systems +REGISTRY_AND_USERNAME ?= $(REGISTRY)/$(USERNAME) +GOFUMPT_VERSION ?= abc0db2c416aca0f60ea33c23c76665f6e7ba0b6 +GO_VERSION ?= 1.14 +PROTOBUF_GO_VERSION ?= 1.25.0 +GRPC_GO_VERSION ?= 1.1.0 +TESTPKGS ?= ./... +KRES_IMAGE ?= ghcr.io/talos-systems/kres:latest + +# docker build settings + +BUILD := docker buildx build +PLATFORM ?= linux/amd64 +PROGRESS ?= auto +PUSH ?= false +CI_ARGS ?= +COMMON_ARGS = --file=Dockerfile +COMMON_ARGS += --progress=$(PROGRESS) +COMMON_ARGS += --platform=$(PLATFORM) +COMMON_ARGS += --push=$(PUSH) +COMMON_ARGS += --build-arg=ARTIFACTS=$(ARTIFACTS) +COMMON_ARGS += --build-arg=SHA=$(SHA) +COMMON_ARGS += --build-arg=TAG=$(TAG) +COMMON_ARGS += --build-arg=USERNAME=$(USERNAME) +COMMON_ARGS += --build-arg=TOOLCHAIN=$(TOOLCHAIN) +COMMON_ARGS += --build-arg=GOFUMPT_VERSION=$(GOFUMPT_VERSION) +COMMON_ARGS += --build-arg=PROTOBUF_GO_VERSION=$(PROTOBUF_GO_VERSION) +COMMON_ARGS += --build-arg=GRPC_GO_VERSION=$(GRPC_GO_VERSION) +COMMON_ARGS += --build-arg=TESTPKGS=$(TESTPKGS) +TOOLCHAIN ?= docker.io/golang:1.16-alpine + +# help menu + +export define HELP_MENU_HEADER +# Getting Started + +To build this project, you must have the following installed: + +- git +- make +- docker (19.03 or higher) + +## Creating a Builder Instance + +The build process makes use of experimental Docker features (buildx). +To enable experimental features, add 'experimental: "true"' to '/etc/docker/daemon.json' on +Linux or enable experimental features in Docker GUI for Windows or Mac. + +To create a builder instance, run: + + docker buildx create --name local --use + + +If you already have a compatible builder instance, you may use that instead. + +## Artifacts + +All artifacts will be output to ./$(ARTIFACTS). Images will be tagged with the +registry "$(REGISTRY)", username "$(USERNAME)", and a dynamic tag (e.g. $(IMAGE):$(TAG)). +The registry and username can be overridden by exporting REGISTRY, and USERNAME +respectively. + +endef + +all: unit-tests lint + +.PHONY: clean +clean: ## Cleans up all artifacts. + @rm -rf $(ARTIFACTS) + +target-%: ## Builds the specified target defined in the Dockerfile. The build result will only remain in the build cache. + @$(BUILD) --target=$* $(COMMON_ARGS) $(TARGET_ARGS) $(CI_ARGS) . + +local-%: ## Builds the specified target defined in the Dockerfile using the local output type. The build result will be output to the specified local destination. + @$(MAKE) target-$* TARGET_ARGS="--output=type=local,dest=$(DEST) $(TARGET_ARGS)" + +lint-golangci-lint: ## Runs golangci-lint linter. + @$(MAKE) target-$@ + +lint-gofumpt: ## Runs gofumpt linter. + @$(MAKE) target-$@ + +.PHONY: fmt +fmt: ## Formats the source code + @docker run --rm -it -v $(PWD):/src -w /src golang:$(GO_VERSION) \ + bash -c "export GO111MODULE=on; export GOPROXY=https://proxy.golang.org; \ + cd /tmp && go mod init tmp && go get mvdan.cc/gofumpt/gofumports@$(GOFUMPT_VERSION) && \ + cd - && gofumports -w -local github.com/talos-systems/grpc-proxy ." + +generate: ## Generate .proto definitions. + @$(MAKE) local-$@ DEST=./ + +.PHONY: base +base: ## Prepare base toolchain + @$(MAKE) target-$@ + +.PHONY: unit-tests +unit-tests: ## Performs unit tests + @$(MAKE) local-$@ DEST=$(ARTIFACTS) + +.PHONY: unit-tests-race +unit-tests-race: ## Performs unit tests with race detection enabled. + @$(MAKE) target-$@ + +.PHONY: coverage +coverage: ## Upload coverage data to codecov.io. + bash -c "bash <(curl -s https://codecov.io/bash) -f $(ARTIFACTS)/coverage.txt -X fix" + +.PHONY: lint-markdown +lint-markdown: ## Runs markdownlint. + @$(MAKE) target-$@ + +.PHONY: lint +lint: lint-golangci-lint lint-gofumpt lint-markdown ## Run all linters for the project. + +.PHONY: rekres +rekres: + @docker pull $(KRES_IMAGE) + @docker run --rm -v $(PWD):/src -w /src -e GITHUB_TOKEN $(KRES_IMAGE) + +.PHONY: help +help: ## This help menu. + @echo "$$HELP_MENU_HEADER" + @grep -E '^[a-zA-Z%_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + diff --git a/README.md b/README.md index 686574b..e6d74a6 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,13 @@ for one to many proxying added. ## Project Goal Build a transparent reverse proxy for gRPC targets that will make it easy to expose gRPC services -over the internet. This includes: - * no needed knowledge of the semantics of requests exchanged in the call (independent rollouts) - * easy, declarative definition of backends and their mappings to frontends - * simple round-robin load balancing of inbound requests from a single connection to multiple backends +over the internet. + +This includes: + +* no needed knowledge of the semantics of requests exchanged in the call (independent rollouts) +* easy, declarative definition of backends and their mappings to frontends +* simple round-robin load balancing of inbound requests from a single connection to multiple backends ## Proxying Modes @@ -23,15 +26,17 @@ There are two proxying modes supported: * one to one: in this mode data passed back and forth is transmitted as is without any modifications; * one to many: one client connection is mapped into multiple upstream connections, results might be aggregated -(for unary calls), errors translated into response messages; this mode requires special layout of protobuf messages. + (for unary calls), errors translated into response messages; this mode requires special layout of protobuf messages. ## Proxy Handler The package [`proxy`](proxy/) contains a generic gRPC reverse proxy handler that allows a gRPC server to -not know about registered handlers or their data types. Please consult the docs, here's an example usage. +not know about registered handlers or their data types. +Please consult the package documentation. +Here you can find an example usage. -First, define `Backend` implementation to identify specific upstream. For one to one proxying, `SingleBackend` -might be used: +First, define `Backend` implementation to identify specific upstream. +For one to one proxying, `SingleBackend` might be used: ```go backend := &proxy.SingleBackend{ @@ -49,6 +54,7 @@ backend := &proxy.SingleBackend{ ``` Defining a `StreamDirector` that decides where (if at all) to send the request + ```go director = func(ctx context.Context, fullMethodName string) (context.Context, *grpc.ClientConn, error) { // Make sure we never forward internal services. @@ -68,8 +74,9 @@ director = func(ctx context.Context, fullMethodName string) (context.Context, *g return nil, grpc.Errorf(codes.Unimplemented, "Unknown method") } ``` -Then you need to register it with a `grpc.Server`. The server may have other handlers that will be served -locally: + +Then you need to register it with a `grpc.Server`. +The server may have other handlers that will be served locally: ```go server := grpc.NewServer( @@ -84,15 +91,16 @@ pb_test.RegisterTestServiceServer(server, &testImpl{}) ## One to Many Proxying In one to many proxying mode, it's critical to identify source of each message proxied back from the upstreams. -Also upstream error shouldn't fail whole request and instead return errors as messages back. In order to achieve -this goal, protobuf response message should follow the same structure: +Also upstream error shouldn't fail whole request and instead return errors as messages back. +In order to achieve this goal, protobuf response message should follow the same structure: -1. Every response should be `repeated` list of response messages, so that responses from multiple upstreams might be -concatenated to build combined response from all the upstreams. +1. Every response should be `repeated` list of response messages so that responses from multiple upstreams might be +concatenated to build a combined response from all the upstreams. 2. Response should contain common metadata fields which allow grpc-proxy to inject source information and error information into response. ## License -`grpc-proxy` is released under the Apache 2.0 license. See [LICENSE.txt](LICENSE.txt). +`grpc-proxy` is released under the Apache 2.0 license. +See [LICENSE.txt](LICENSE.txt). diff --git a/fixup.sh b/fixup.sh deleted file mode 100755 index 3ce0058..0000000 --- a/fixup.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - - generate_markdown() { - echo "Generating markdown" - oldpwd=$(pwd) - for i in $(find . -iname 'doc.go'); do - dir=${i%/*} - echo "$dir" - cd ${dir} - ${GOPATH}/bin/godocdown -heading=Title -o DOC.md - ln -s DOC.md README.md 2> /dev/null # can fail - cd ${oldpwd} - done -} - -generate_markdown -echo "returning $?" diff --git a/go.mod b/go.mod index ba8fcdd..7f5f688 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,11 @@ module github.com/talos-systems/grpc-proxy -go 1.13 +go 1.16 require ( - github.com/golang/protobuf v1.3.2 - github.com/hashicorp/go-multierror v1.0.0 - github.com/stretchr/testify v1.4.0 - google.golang.org/grpc v1.25.1 + github.com/golang/protobuf v1.5.1 + github.com/hashicorp/go-multierror v1.1.1 + github.com/stretchr/testify v1.7.0 + google.golang.org/grpc v1.36.1 + google.golang.org/protobuf v1.26.0 ) diff --git a/go.sum b/go.sum index c168273..082421c 100644 --- a/go.sum +++ b/go.sum @@ -2,27 +2,46 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -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/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1 h1:jAbXjIeW2ZSW2AwFxlGTDoc2CjI2XujLkV3ArsZFCvc= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -46,18 +65,36 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1 h1:wdKvqQk7IttEw92GoRyKG2IDrUIpgpj6H6m81yfeMW0= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.36.1 h1:cmUfbeGKnz9+2DD/UYsMQXeqbHZqZDs4eQwW0sFOpBY= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/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 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/hack/git-chglog/CHANGELOG.tpl.md b/hack/git-chglog/CHANGELOG.tpl.md new file mode 100644 index 0000000..dbb23af --- /dev/null +++ b/hack/git-chglog/CHANGELOG.tpl.md @@ -0,0 +1,26 @@ + + + + +{{ range .Versions }} + +## {{ if .Tag.Previous }}[{{ .Tag.Name }}]({{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }}){{ else }}{{ .Tag.Name }}{{ end }} ({{ datetime "2006-01-02" .Tag.Date }}) + +{{ range .CommitGroups -}} +### {{ .Title }} + +{{ range .Commits -}} +* {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} +{{ end }} +{{ end -}} + +{{- if .NoteGroups -}} +{{ range .NoteGroups -}} +### {{ .Title }} + +{{ range .Notes }} +{{ .Body }} +{{ end }} +{{ end -}} +{{ end -}} +{{ end -}} diff --git a/hack/git-chglog/config.yaml b/hack/git-chglog/config.yaml new file mode 100644 index 0000000..9754a5f --- /dev/null +++ b/hack/git-chglog/config.yaml @@ -0,0 +1,32 @@ +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2021-03-25T21:15:43Z by kres 424ae88-dirty. + +style: github +template: CHANGELOG.tpl.md +info: + title: CHANGELOG + repository_url: https://github.com/talos-systems/grpc-proxy +options: + commits: + # filters: + # Type: + # - feat + # - fix + # - perf + # - refactor + commit_groups: + # title_maps: + # feat: Features + # fix: Bug Fixes + # perf: Performance Improvements + # refactor: Code Refactoring + header: + pattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$" + pattern_maps: + - Type + - Scope + - Subject + notes: + keywords: + - BREAKING CHANGE diff --git a/hack/release.sh b/hack/release.sh new file mode 100755 index 0000000..f373561 --- /dev/null +++ b/hack/release.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2021-03-25T21:15:43Z by kres 424ae88-dirty. + + +set -e + +function changelog { + if [ "$#" -eq 1 ]; then + git-chglog --output CHANGELOG.md -c ./hack/git-chglog/config.yaml --tag-filter-pattern "^${1}" "${1}.0-alpha.0.." + elif [ "$#" -eq 0 ]; then + git-chglog --output CHANGELOG.md -c ./hack/git-chglog/config.yaml + else + echo 1>&2 "Usage: $0 changelog [tag]" + exit 1 + fi +} + +function release-notes { + git-chglog --output ${1} -c ./hack/git-chglog/config.yaml "${2}" +} + +function cherry-pick { + if [ $# -ne 2 ]; then + echo 1>&2 "Usage: $0 cherry-pick " + exit 1 + fi + + git checkout $2 + git fetch + git rebase upstream/$2 + git cherry-pick -x $1 +} + +function commit { + if [ $# -ne 1 ]; then + echo 1>&2 "Usage: $0 commit " + exit 1 + fi + + git commit -s -m "release($1): prepare release" -m "This is the official $1 release." +} + +if declare -f "$1" > /dev/null +then + cmd="$1" + shift + $cmd "$@" +else + cat <serverStream may continue pumping though. for i := range backendConnections { @@ -40,7 +40,6 @@ func (s *handler) handlerOne2Many(fullMethodName string, serverStream grpc.Serve backendConnections[i].clientStream.CloseSend() //nolint: errcheck } } - break } else { // however, we may have gotten a receive error (stream disconnected, a read error etc) in which case we need // to cancel the clientStream to the backend, let all of its goroutines be freed up by the CancelFunc and @@ -49,16 +48,18 @@ func (s *handler) handlerOne2Many(fullMethodName string, serverStream grpc.Serve } case c2sErr := <-c2sErrChan: // c2sErr will contain RPC error from client code. If not io.EOF return the RPC error as server stream error. - if c2sErr != io.EOF { + if !errors.Is(c2sErr, io.EOF) { return c2sErr } + return nil } } + return status.Errorf(codes.Internal, "gRPC proxying should never reach this stage.") } -// formatError tries to format error from upstream as message to the client +// formatError tries to format error from upstream as message to the client. func (s *handler) formatError(streaming bool, src *backendConnection, backendErr error) ([]byte, error) { payload, err := src.backend.BuildError(streaming, backendErr) if err != nil { @@ -72,17 +73,18 @@ func (s *handler) formatError(streaming bool, src *backendConnection, backendErr return payload, err } -// sendError tries to deliver error back to the client via dst +// sendError tries to deliver error back to the client via dst. // -// if sendError fails to deliver the error, error is returned -// if sendError successfully delivers the error, nil is returned +// If sendError fails to deliver the error, error is returned. +// If sendError successfully delivers the error, nil is returned. func (s *handler) sendError(src *backendConnection, dst grpc.ServerStream, backendErr error) error { payload, err := s.formatError(true, src, backendErr) if err != nil { return err } - f := &frame{payload: payload} + f := NewFrame(payload) + if err = dst.SendMsg(f); err != nil { if errors.Is(err, context.Canceled) { return nil @@ -99,6 +101,7 @@ func (s *handler) sendError(src *backendConnection, dst grpc.ServerStream, backe } // one:many proxying, unary call version (merging results) +//nolint: gocognit func (s *handler) forwardClientsToServerMultiUnary(sources []backendConnection, dst grpc.ServerStream) chan error { ret := make(chan error, 1) @@ -115,40 +118,50 @@ func (s *handler) forwardClientsToServerMultiUnary(sources []backendConnection, } payloadCh <- payload + return nil } f := &frame{} + for j := 0; ; j++ { if err := src.clientStream.RecvMsg(f); err != nil { - if err == io.EOF { + if errors.Is(err, io.EOF) { // This happens when the clientStream has nothing else to offer (io.EOF), returned a gRPC error. In those two // cases we may have received Trailers as part of the call. In case of other errors (stream closed) the trailers // will be nil. dst.SetTrailer(src.clientStream.Trailer()) + return nil } - payload, err := s.formatError(false, src, err) + var payload []byte + + payload, err = s.formatError(false, src, err) if err != nil { return err } payloadCh <- payload + return nil } + if j == 0 { // This is a bit of a hack, but client to server headers are only readable after first client msg is // received but must be written to server stream before the first msg is flushed. // This is the only place to do it nicely. md, err := src.clientStream.Header() if err != nil { - payload, err := s.formatError(false, src, err) + var payload []byte + + payload, err = s.formatError(false, src, err) if err != nil { return err } payloadCh <- payload + return nil } @@ -158,6 +171,7 @@ func (s *handler) forwardClientsToServerMultiUnary(sources []backendConnection, } var err error + f.payload, err = src.backend.AppendInfo(false, f.payload) if err != nil { return fmt.Errorf("error appending info for %s: %w", src.backend, err) @@ -178,6 +192,7 @@ func (s *handler) forwardClientsToServerMultiUnary(sources []backendConnection, if multiErr.ErrorOrNil() != nil { ret <- multiErr.ErrorOrNil() + return } @@ -188,13 +203,15 @@ func (s *handler) forwardClientsToServerMultiUnary(sources []backendConnection, merged = append(merged, b...) } - ret <- dst.SendMsg(&frame{payload: merged}) + ret <- dst.SendMsg(NewFrame(merged)) }() return ret } -// one:many proxying, streaming version (no merge) +// one:many proxying, streaming version (no merge). +// +//nolint: gocognit func (s *handler) forwardClientsToServerMultiStreaming(sources []backendConnection, dst grpc.ServerStream) chan error { ret := make(chan error, 1) @@ -208,15 +225,18 @@ func (s *handler) forwardClientsToServerMultiStreaming(sources []backendConnecti } f := &frame{} + for j := 0; ; j++ { if err := src.clientStream.RecvMsg(f); err != nil { - if err == io.EOF { + if errors.Is(err, io.EOF) { // This happens when the clientStream has nothing else to offer (io.EOF), returned a gRPC error. In those two // cases we may have received Trailers as part of the call. In case of other errors (stream closed) the trailers // will be nil. dst.SetTrailer(src.clientStream.Trailer()) + return nil } + return s.sendError(src, dst, err) } if j == 0 { @@ -242,7 +262,6 @@ func (s *handler) forwardClientsToServerMultiStreaming(sources []backendConnecti return fmt.Errorf("error sending back to server from %s: %w", src.backend, err) } } - }() }(&sources[i]) } @@ -262,11 +281,14 @@ func (s *handler) forwardClientsToServerMultiStreaming(sources []backendConnecti func (s *handler) forwardServerToClientsMulti(src grpc.ServerStream, destinations []backendConnection) chan error { ret := make(chan error, 1) + go func() { - f := &frame{} + f := NewFrame(nil) + for { if err := src.RecvMsg(f); err != nil { ret <- err + return } @@ -276,7 +298,7 @@ func (s *handler) forwardServerToClientsMulti(src grpc.ServerStream, destination go func(dst *backendConnection) { errCh <- func() error { if dst.clientStream == nil || dst.connError != nil { - return nil // skip it + return nil //nolint: nilerr // skip it } return dst.clientStream.SendMsg(f) @@ -285,6 +307,7 @@ func (s *handler) forwardServerToClientsMulti(src grpc.ServerStream, destination } liveDestinations := 0 + for range destinations { if err := <-errCh; err == nil { liveDestinations++ @@ -293,9 +316,11 @@ func (s *handler) forwardServerToClientsMulti(src grpc.ServerStream, destination if liveDestinations == 0 { ret <- errors.New("no backend connections to forward to are available") + return } } }() + return ret } diff --git a/proxy/handler_one2many_test.go b/proxy/handler_one2many_test.go index 3374ef3..633bb74 100644 --- a/proxy/handler_one2many_test.go +++ b/proxy/handler_one2many_test.go @@ -6,6 +6,7 @@ package proxy_test import ( "context" + "errors" "fmt" "io" "log" @@ -17,16 +18,16 @@ import ( "testing" "time" - "github.com/golang/protobuf/proto" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" - "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/encoding/protowire" + "google.golang.org/protobuf/proto" "github.com/talos-systems/grpc-proxy/proxy" pb "github.com/talos-systems/grpc-proxy/testservice" @@ -36,8 +37,10 @@ const ( numUpstreams = 5 ) -// asserting service is implemented on the server side and serves as a handler for stuff +// asserting service is implemented on the server side and serves as a handler for stuff. type assertingMultiService struct { + pb.UnimplementedMultiServiceServer + t *testing.T server string } @@ -48,6 +51,7 @@ func (s *assertingMultiService) PingEmpty(ctx context.Context, _ *pb.Empty) (*pb assert.True(s.t, ok, "PingEmpty call must have metadata in context") _, ok = md[clientMdKey] assert.True(s.t, ok, "PingEmpty call must have clients's custom headers in metadata") + return &pb.MultiPingReply{ Response: []*pb.MultiPingResponse{ { @@ -63,6 +67,7 @@ func (s *assertingMultiService) Ping(ctx context.Context, ping *pb.PingRequest) // Send user trailers and headers. grpc.SendHeader(ctx, metadata.Pairs(serverHeaderMdKey, "I like turtles.")) //nolint: errcheck grpc.SetTrailer(ctx, metadata.Pairs(serverTrailerMdKey, "I like ending turtles.")) //nolint: errcheck + return &pb.MultiPingReply{ Response: []*pb.MultiPingResponse{ { @@ -81,6 +86,7 @@ func (s *assertingMultiService) PingError(ctx context.Context, ping *pb.PingRequ func (s *assertingMultiService) PingList(ping *pb.PingRequest, stream pb.MultiService_PingListServer) error { // Send user trailers and headers. stream.SendHeader(metadata.Pairs(serverHeaderMdKey, "I like turtles.")) //nolint: errcheck + for i := 0; i < countListResponses; i++ { stream.Send(&pb.MultiPingResponse{ //nolint: errcheck Value: ping.Value, @@ -88,32 +94,43 @@ func (s *assertingMultiService) PingList(ping *pb.PingRequest, stream pb.MultiSe Server: s.server, }) } - stream.SetTrailer(metadata.Pairs(serverTrailerMdKey, "I like ending turtles.")) //nolint: errcheck + + stream.SetTrailer(metadata.Pairs(serverTrailerMdKey, "I like ending turtles.")) + return nil } func (s *assertingMultiService) PingStream(stream pb.MultiService_PingStreamServer) error { - stream.SendHeader(metadata.Pairs(serverHeaderMdKey, "I like turtles.")) // nolint: errcheck + stream.SendHeader(metadata.Pairs(serverHeaderMdKey, "I like turtles.")) //nolint: errcheck + counter := int32(0) + for { ping, err := stream.Recv() - if err == io.EOF { + + if errors.Is(err, io.EOF) { break } else if err != nil { require.NoError(s.t, err, "can't fail reading stream") + return err } + pong := &pb.MultiPingResponse{ Value: ping.Value, Counter: counter, Server: s.server, } + if err := stream.Send(pong); err != nil { require.NoError(s.t, err, "can't fail sending back a pong") } - counter += 1 + + counter++ } + stream.SetTrailer(metadata.Pairs(serverTrailerMdKey, "I like ending turtles.")) + return nil } @@ -122,11 +139,12 @@ func (s *assertingMultiService) PingStreamError(stream pb.MultiService_PingStrea } type assertingBackend struct { + conn *grpc.ClientConn + addr string i int - mu sync.Mutex - conn *grpc.ClientConn + mu sync.Mutex } func (b *assertingBackend) String() string { @@ -144,12 +162,13 @@ func (b *assertingBackend) GetConnection(ctx context.Context) (context.Context, b.mu.Lock() defer b.mu.Unlock() + if b.conn != nil { return outCtx, b.conn, nil } var err error - b.conn, err = grpc.DialContext(ctx, b.addr, grpc.WithInsecure(), grpc.WithCodec(proxy.Codec())) // nolint: staticcheck + b.conn, err = grpc.DialContext(ctx, b.addr, grpc.WithInsecure(), grpc.WithCodec(proxy.Codec())) //nolint: staticcheck return outCtx, b.conn, err } @@ -166,8 +185,8 @@ func (b *assertingBackend) AppendInfo(streaming bool, resp []byte) ([]byte, erro } // decode protobuf embedded header - typ, n1 := proto.DecodeVarint(resp) - _, n2 := proto.DecodeVarint(resp[n1:]) // length + typ, n1 := protowire.ConsumeVarint(resp) + _, n2 := protowire.ConsumeVarint(resp[n1:]) // length if typ != (1<<3)|2 { // type: 2, field_number: 1 return nil, fmt.Errorf("unexpected message format: %d", typ) @@ -176,7 +195,7 @@ func (b *assertingBackend) AppendInfo(streaming bool, resp []byte) ([]byte, erro // cut off embedded message header resp = resp[n1+n2:] // build new embedded message header - prefix := append(proto.EncodeVarint((1<<3)|2), proto.EncodeVarint(uint64(len(resp)+len(payload)))...) + prefix := protowire.AppendVarint(protowire.AppendVarint(nil, (1<<3)|2), uint64(len(resp)+len(payload))) resp = append(prefix, resp...) return append(resp, payload...), err @@ -201,7 +220,7 @@ func (b *assertingBackend) BuildError(streaming bool, err error) ([]byte, error) return proto.Marshal(resp) } -type ProxyOne2ManySuite struct { +type ProxyOne2ManySuite struct { //nolint: govet suite.Suite serverListeners []net.Listener @@ -228,6 +247,7 @@ func (s *ProxyOne2ManySuite) TestPingEmptyCarriesClientMetadata() { } s.Require().Len(out.Response, numUpstreams) + for _, resp := range out.Response { s.Require().Equal(pingDefaultValue, resp.Value) s.Require().EqualValues(42, resp.Counter) @@ -267,6 +287,7 @@ func (s *ProxyOne2ManySuite) TestPingEmptyTargets() { } s.Require().Len(out.Response, len(expectedUpstreams)) + for _, resp := range out.Response { s.Require().Equal(pingDefaultValue, resp.Value) s.Require().EqualValues(42, resp.Counter) @@ -280,6 +301,7 @@ func (s *ProxyOne2ManySuite) TestPingEmptyTargets() { s.Require().Empty(expectedUpstreams) } } + func (s *ProxyOne2ManySuite) TestPingEmptyConnError() { targets := []string{"0", "-1", "2"} md := metadata.Pairs(clientMdKey, "true") @@ -295,6 +317,7 @@ func (s *ProxyOne2ManySuite) TestPingEmptyConnError() { } s.Require().Len(out.Response, len(expectedUpstreams)) + for _, resp := range out.Response { delete(expectedUpstreams, resp.Metadata.Hostname) @@ -320,6 +343,7 @@ func (s *ProxyOne2ManySuite) TestPingCarriesServerHeadersAndTrailers() { require.NoError(s.T(), err, "Ping should succeed without errors") s.Require().Len(out.Response, numUpstreams) + for _, resp := range out.Response { s.Require().Equal("foo", resp.Value) s.Require().EqualValues(42, resp.Counter) @@ -337,6 +361,7 @@ func (s *ProxyOne2ManySuite) TestPingErrorPropagatesAppError() { s.Require().NoError(err, "error should be encapsulated in the response") s.Require().Len(out.Response, numUpstreams) + for _, resp := range out.Response { s.Require().NotEmpty(resp.Metadata.UpstreamError) s.Require().NotEmpty(resp.Metadata.Hostname) @@ -349,7 +374,9 @@ func (s *ProxyOne2ManySuite) TestPingStreamErrorPropagatesAppError() { s.Require().NoError(err, "error should be encapsulated in the response") for j := 0; j < numUpstreams; j++ { - resp, err := stream.Recv() + var resp *pb.MultiPingResponse + + resp, err = stream.Recv() s.Require().NoError(err) s.Assert().Equal("rpc error: code = FailedPrecondition desc = Userspace error.", resp.Metadata.UpstreamError) @@ -404,7 +431,8 @@ func (s *ProxyOne2ManySuite) TestPingStream_FullDuplexWorks() { // each upstream should send back response for j := 0; j < numUpstreams; j++ { - resp, err := stream.Recv() + var resp *pb.MultiPingResponse + resp, err = stream.Recv() s.Require().NoError(err) s.Assert().EqualValues(i, resp.Counter, "ping roundtrip must succeed with the correct id") @@ -417,7 +445,8 @@ func (s *ProxyOne2ManySuite) TestPingStream_FullDuplexWorks() { if i == 0 { // Check that the header arrives before all entries. - headerMd, err := stream.Header() + var headerMd metadata.MD + headerMd, err = stream.Header() require.NoError(s.T(), err, "PingStream headers should not error.") assert.Contains(s.T(), headerMd, serverHeaderMdKey, "PingStream response headers user contain metadata") } @@ -430,6 +459,7 @@ func (s *ProxyOne2ManySuite) TestPingStream_FullDuplexWorks() { assert.Len(s.T(), trailerMd, 1, "PingList trailer headers user contain metadata") } +//nolint: gocognit func (s *ProxyOne2ManySuite) TestPingStream_FullDuplexConcurrent() { stream, err := s.testClient.PingStream(s.ctx) require.NoError(s.T(), err, "PingStream request should be successful.") @@ -446,7 +476,7 @@ func (s *ProxyOne2ManySuite) TestPingStream_FullDuplexConcurrent() { errCh <- func() error { for i := 0; i < countListResponses; i++ { ping := &pb.PingRequest{Value: fmt.Sprintf("foo:%d", i)} - if err := stream.Send(ping); err != nil { + if err = stream.Send(ping); err != nil { return err } } @@ -458,7 +488,9 @@ func (s *ProxyOne2ManySuite) TestPingStream_FullDuplexConcurrent() { go func() { errCh <- func() error { for i := 0; i < countListResponses*numUpstreams; i++ { - resp, err := stream.Recv() + var resp *pb.MultiPingResponse + + resp, err = stream.Recv() if err != nil { return err } @@ -511,6 +543,7 @@ func (s *ProxyOne2ManySuite) TearDownTest() { s.ctxCancel() } +//nolint: gocognit func (s *ProxyOne2ManySuite) SetupSuite() { var err error @@ -561,7 +594,9 @@ func (s *ProxyOne2ManySuite) SetupSuite() { if mdTargets, exists := md["targets"]; exists { for _, strTarget := range mdTargets { - t, err := strconv.Atoi(strTarget) + var t int + + t, err = strconv.Atoi(strTarget) if err != nil { return proxy.One2Many, nil, err } @@ -591,7 +626,7 @@ func (s *ProxyOne2ManySuite) SetupSuite() { } s.proxy = grpc.NewServer( - grpc.CustomCodec(proxy.Codec()), + grpc.CustomCodec(proxy.Codec()), //nolint: staticcheck grpc.UnknownServiceHandler(proxy.TransparentHandler(director)), ) // Ping handler is handled as an explicit registration and not as a TransparentHandler. @@ -604,17 +639,21 @@ func (s *ProxyOne2ManySuite) SetupSuite() { // Start the serving loops. for i := range s.servers { s.T().Logf("starting grpc.Server at: %v", s.serverListeners[i].Addr().String()) + go func(i int) { - s.servers[i].Serve(s.serverListeners[i]) // nolint: errcheck + s.servers[i].Serve(s.serverListeners[i]) //nolint: errcheck }(i) } + s.T().Logf("starting grpc.Proxy at: %v", s.proxyListener.Addr().String()) + go func() { - s.proxy.Serve(s.proxyListener) // nolint: errcheck + s.proxy.Serve(s.proxyListener) //nolint: errcheck }() ctx, ctxCancel := context.WithTimeout(context.Background(), 1*time.Second) defer ctxCancel() + clientConn, err := grpc.DialContext(ctx, strings.Replace(s.proxyListener.Addr().String(), "127.0.0.1", "localhost", 1), grpc.WithInsecure()) require.NoError(s.T(), err, "must not error on deferred client Dial") s.testClient = pb.NewMultiServiceClient(clientConn) @@ -622,17 +661,19 @@ func (s *ProxyOne2ManySuite) SetupSuite() { func (s *ProxyOne2ManySuite) TearDownSuite() { if s.client != nil { - s.client.Close() + s.Assert().NoError(s.client.Close()) } + if s.serverClientConn != nil { - s.serverClientConn.Close() + s.Assert().NoError(s.serverClientConn.Close()) } + // Close all transports so the logs don't get spammy. time.Sleep(10 * time.Millisecond) if s.proxy != nil { s.proxy.Stop() - s.proxyListener.Close() + s.proxyListener.Close() //nolint: errcheck } for _, server := range s.servers { @@ -643,14 +684,15 @@ func (s *ProxyOne2ManySuite) TearDownSuite() { for _, serverListener := range s.serverListeners { if serverListener != nil { - serverListener.Close() + serverListener.Close() //nolint: errcheck } } } + func TestProxyOne2ManySuite(t *testing.T) { suite.Run(t, &ProxyOne2ManySuite{}) } func init() { - grpclog.SetLogger(log.New(os.Stderr, "grpc: ", log.LstdFlags)) // nolint: staticcheck + grpclog.SetLogger(log.New(os.Stderr, "grpc: ", log.LstdFlags)) //nolint: staticcheck } diff --git a/proxy/handler_one2one.go b/proxy/handler_one2one.go index dff9d5a..c634c64 100644 --- a/proxy/handler_one2one.go +++ b/proxy/handler_one2one.go @@ -5,6 +5,7 @@ package proxy import ( + "errors" "io" "google.golang.org/grpc" @@ -12,7 +13,7 @@ import ( "google.golang.org/grpc/status" ) -func (s *handler) handlerOne2One(fullMethodName string, serverStream grpc.ServerStream, backendConnections []backendConnection) error { +func (s *handler) handlerOne2One(serverStream grpc.ServerStream, backendConnections []backendConnection) error { // case of proxying one to one: if backendConnections[0].connError != nil { return backendConnections[0].connError @@ -27,12 +28,11 @@ func (s *handler) handlerOne2One(fullMethodName string, serverStream grpc.Server for i := 0; i < 2; i++ { select { case s2cErr := <-s2cErrChan: - if s2cErr == io.EOF { + if errors.Is(s2cErr, io.EOF) { // this is the happy case where the sender has encountered io.EOF, and won't be sending anymore./ // the clientStream>serverStream may continue pumping though. //nolint: errcheck backendConnections[0].clientStream.CloseSend() - break } else { // however, we may have gotten a receive error (stream disconnected, a read error etc) in which case we need // to cancel the clientStream to the backend, let all of its goroutines be freed up by the CancelFunc and @@ -45,22 +45,27 @@ func (s *handler) handlerOne2One(fullMethodName string, serverStream grpc.Server // will be nil. serverStream.SetTrailer(backendConnections[0].clientStream.Trailer()) // c2sErr will contain RPC error from client code. If not io.EOF return the RPC error as server stream error. - if c2sErr != io.EOF { + if !errors.Is(c2sErr, io.EOF) { return c2sErr } + return nil } } + return status.Errorf(codes.Internal, "gRPC proxying should never reach this stage.") } func (s *handler) forwardClientToServer(src *backendConnection, dst grpc.ServerStream) chan error { ret := make(chan error, 1) + go func() { - f := &frame{} + f := NewFrame(nil) + for i := 0; ; i++ { if err := src.clientStream.RecvMsg(f); err != nil { ret <- err // this can be io.EOF which is happy case + break } @@ -71,36 +76,48 @@ func (s *handler) forwardClientToServer(src *backendConnection, dst grpc.ServerS md, err := src.clientStream.Header() if err != nil { ret <- err + break } + if err := dst.SendHeader(md); err != nil { ret <- err + break } } + if err := dst.SendMsg(f); err != nil { ret <- err + break } } }() + return ret } func (s *handler) forwardServerToClient(src grpc.ServerStream, dst *backendConnection) chan error { ret := make(chan error, 1) + go func() { - f := &frame{} - for i := 0; ; i++ { + f := NewFrame(nil) + + for { if err := src.RecvMsg(f); err != nil { ret <- err // this can be io.EOF which is happy case + break } + if err := dst.clientStream.SendMsg(f); err != nil { ret <- err + break } } }() + return ret } diff --git a/proxy/handler_one2one_test.go b/proxy/handler_one2one_test.go index e2e05fd..d8ca173 100644 --- a/proxy/handler_one2one_test.go +++ b/proxy/handler_one2one_test.go @@ -5,6 +5,8 @@ package proxy_test import ( "context" + "errors" + "fmt" "io" "net" "strings" @@ -18,8 +20,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" - - "fmt" + "google.golang.org/protobuf/proto" "github.com/talos-systems/grpc-proxy/proxy" pb "github.com/talos-systems/grpc-proxy/testservice" @@ -36,8 +37,10 @@ const ( countListResponses = 20 ) -// asserting service is implemented on the server side and serves as a handler for stuff +// asserting service is implemented on the server side and serves as a handler for stuff. type assertingService struct { + pb.UnimplementedTestServiceServer + t *testing.T } @@ -47,6 +50,7 @@ func (s *assertingService) PingEmpty(ctx context.Context, _ *pb.Empty) (*pb.Ping assert.True(s.t, ok, "PingEmpty call must have metadata in context") _, ok = md[clientMdKey] assert.True(s.t, ok, "PingEmpty call must have clients's custom headers in metadata") + return &pb.PingResponse{Value: pingDefaultValue, Counter: 42}, nil } @@ -54,6 +58,7 @@ func (s *assertingService) Ping(ctx context.Context, ping *pb.PingRequest) (*pb. // Send user trailers and headers. grpc.SendHeader(ctx, metadata.Pairs(serverHeaderMdKey, "I like turtles.")) //nolint: errcheck grpc.SetTrailer(ctx, metadata.Pairs(serverTrailerMdKey, "I like ending turtles.")) //nolint: errcheck + return &pb.PingResponse{Value: ping.Value, Counter: 42}, nil } @@ -64,31 +69,42 @@ func (s *assertingService) PingError(ctx context.Context, ping *pb.PingRequest) func (s *assertingService) PingList(ping *pb.PingRequest, stream pb.TestService_PingListServer) error { // Send user trailers and headers. stream.SendHeader(metadata.Pairs(serverHeaderMdKey, "I like turtles.")) //nolint: errcheck + for i := 0; i < countListResponses; i++ { stream.Send(&pb.PingResponse{Value: ping.Value, Counter: int32(i)}) //nolint: errcheck } - stream.SetTrailer(metadata.Pairs(serverTrailerMdKey, "I like ending turtles.")) //nolint: errcheck + + stream.SetTrailer(metadata.Pairs(serverTrailerMdKey, "I like ending turtles.")) + return nil } func (s *assertingService) PingStream(stream pb.TestService_PingStreamServer) error { - stream.SendHeader(metadata.Pairs(serverHeaderMdKey, "I like turtles.")) // nolint: errcheck + stream.SendHeader(metadata.Pairs(serverHeaderMdKey, "I like turtles.")) //nolint: errcheck + counter := int32(0) + for { ping, err := stream.Recv() - if err == io.EOF { + if errors.Is(err, io.EOF) { break } else if err != nil { require.NoError(s.t, err, "can't fail reading stream") + return err } + pong := &pb.PingResponse{Value: ping.Value, Counter: counter} + if err := stream.Send(pong); err != nil { require.NoError(s.t, err, "can't fail sending back a pong") } - counter += 1 + + counter++ } + stream.SetTrailer(metadata.Pairs(serverTrailerMdKey, "I like ending turtles.")) + return nil } @@ -121,7 +137,7 @@ func (s *ProxyOne2OneSuite) TestPingEmptyCarriesClientMetadata() { ctx := metadata.NewOutgoingContext(s.ctx, metadata.Pairs(clientMdKey, "true")) out, err := s.testClient.PingEmpty(ctx, &pb.Empty{}) require.NoError(s.T(), err, "PingEmpty should succeed without errors") - require.Equal(s.T(), &pb.PingResponse{Value: pingDefaultValue, Counter: 42}, out) + require.True(s.T(), proto.Equal(&pb.PingResponse{Value: pingDefaultValue, Counter: 42}, out)) } func (s *ProxyOne2OneSuite) TestPingEmpty_StressTest() { @@ -136,7 +152,7 @@ func (s *ProxyOne2OneSuite) TestPingCarriesServerHeadersAndTrailers() { // This is an awkward calling convention... but meh. out, err := s.testClient.Ping(s.ctx, &pb.PingRequest{Value: "foo"}, grpc.Header(&headerMd), grpc.Trailer(&trailerMd)) require.NoError(s.T(), err, "Ping should succeed without errors") - require.Equal(s.T(), &pb.PingResponse{Value: "foo", Counter: 42}, out) + require.True(s.T(), proto.Equal(&pb.PingResponse{Value: "foo", Counter: 42}, out)) assert.Contains(s.T(), headerMd, serverHeaderMdKey, "server response headers must contain server data") assert.Len(s.T(), trailerMd, 1, "server response trailers must contain server data") } @@ -164,16 +180,22 @@ func (s *ProxyOne2OneSuite) TestPingStream_FullDuplexWorks() { for i := 0; i < countListResponses; i++ { ping := &pb.PingRequest{Value: fmt.Sprintf("foo:%d", i)} require.NoError(s.T(), stream.Send(ping), "sending to PingStream must not fail") - resp, err := stream.Recv() - if err == io.EOF { + + var resp *pb.PingResponse + + resp, err = stream.Recv() + if errors.Is(err, io.EOF) { break } + if i == 0 { // Check that the header arrives before all entries. - headerMd, err := stream.Header() + var headerMd metadata.MD + headerMd, err = stream.Header() require.NoError(s.T(), err, "PingStream headers should not error.") assert.Contains(s.T(), headerMd, serverHeaderMdKey, "PingStream response headers user contain metadata") } + assert.EqualValues(s.T(), i, resp.Counter, "ping roundtrip must succeed with the correct id") } require.NoError(s.T(), stream.CloseSend(), "no error on close send") @@ -202,8 +224,9 @@ func (s *ProxyOne2OneSuite) SetupSuite() { pb.RegisterTestServiceServer(s.server, &assertingService{t: s.T()}) // Setup of the proxy's Director. - s.serverClientConn, err = grpc.Dial(s.serverListener.Addr().String(), grpc.WithInsecure(), grpc.WithCodec(proxy.Codec())) // nolint: staticcheck + s.serverClientConn, err = grpc.Dial(s.serverListener.Addr().String(), grpc.WithInsecure(), grpc.WithCodec(proxy.Codec())) //nolint: staticcheck require.NoError(s.T(), err, "must not error on deferred client Dial") + director := func(ctx context.Context, fullName string) (proxy.Mode, []proxy.Backend, error) { md, ok := metadata.FromIncomingContext(ctx) if ok { @@ -218,15 +241,18 @@ func (s *ProxyOne2OneSuite) SetupSuite() { md, _ := metadata.FromIncomingContext(ctx) // Explicitly copy the metadata, otherwise the tests will fail. outCtx := metadata.NewOutgoingContext(ctx, md.Copy()) + return outCtx, s.serverClientConn, nil }, }, }, nil } + s.proxy = grpc.NewServer( - grpc.CustomCodec(proxy.Codec()), + grpc.CustomCodec(proxy.Codec()), //nolint: staticcheck grpc.UnknownServiceHandler(proxy.TransparentHandler(director)), ) + // Ping handler is handled as an explicit registration and not as a TransparentHandler. proxy.RegisterService(s.proxy, director, "talos.testproto.TestService", @@ -235,16 +261,20 @@ func (s *ProxyOne2OneSuite) SetupSuite() { // Start the serving loops. s.T().Logf("starting grpc.Server at: %v", s.serverListener.Addr().String()) + go func() { - s.server.Serve(s.serverListener) // nolint: errcheck + s.server.Serve(s.serverListener) //nolint: errcheck }() + s.T().Logf("starting grpc.Proxy at: %v", s.proxyListener.Addr().String()) + go func() { - s.proxy.Serve(s.proxyListener) // nolint: errcheck + s.proxy.Serve(s.proxyListener) //nolint: errcheck }() ctx, ctxCancel := context.WithTimeout(context.Background(), 1*time.Second) defer ctxCancel() + clientConn, err := grpc.DialContext(ctx, strings.Replace(s.proxyListener.Addr().String(), "127.0.0.1", "localhost", 1), grpc.WithInsecure()) require.NoError(s.T(), err, "must not error on deferred client Dial") s.testClient = pb.NewTestServiceClient(clientConn) @@ -252,20 +282,24 @@ func (s *ProxyOne2OneSuite) SetupSuite() { func (s *ProxyOne2OneSuite) TearDownSuite() { if s.client != nil { - s.client.Close() + s.client.Close() //nolint: errcheck } + if s.serverClientConn != nil { - s.serverClientConn.Close() + s.serverClientConn.Close() //nolint: errcheck } + // Close all transports so the logs don't get spammy. time.Sleep(10 * time.Millisecond) + if s.proxy != nil { s.proxy.Stop() - s.proxyListener.Close() + s.proxyListener.Close() //nolint: errcheck } + if s.serverListener != nil { s.server.Stop() - s.serverListener.Close() + s.serverListener.Close() //nolint: errcheck } } diff --git a/proxy/proxy.go b/proxy/proxy.go index acdc612..9c11389 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -18,7 +18,7 @@ const ( // StreamedDetectorFunc reports is gRPC is doing streaming (only for one2many proxying). type StreamedDetectorFunc func(fullMethodName string) bool -// Option configures gRPC proxy +// Option configures gRPC proxy. type Option func(*handlerOptions) // WithMethodNames configures list of method names to proxy for non-transparent handler. @@ -61,7 +61,7 @@ func WithStreamedDetector(detector StreamedDetectorFunc) Option { // The behavior is the same as if you were registering a handler method, e.g. from a codegenerated pb.go file. // // This can *only* be used if the `server` also uses grpc.CustomCodec() ServerOption. -func RegisterService(server *grpc.Server, director StreamDirector, serviceName string, options ...Option) { +func RegisterService(server grpc.ServiceRegistrar, director StreamDirector, serviceName string, options ...Option) { streamer := &handler{ director: director, options: handlerOptions{ @@ -77,6 +77,7 @@ func RegisterService(server *grpc.Server, director StreamDirector, serviceName s ServiceName: serviceName, HandlerType: (*interface{})(nil), } + for _, m := range streamer.options.methodNames { streamDesc := grpc.StreamDesc{ StreamName: m, @@ -86,6 +87,7 @@ func RegisterService(server *grpc.Server, director StreamDirector, serviceName s } fakeDesc.Streams = append(fakeDesc.Streams, streamDesc) } + server.RegisterService(fakeDesc, streamer) } diff --git a/proxy/serverstream.go b/proxy/serverstream.go index 84dc88a..f9e9cbd 100644 --- a/proxy/serverstream.go +++ b/proxy/serverstream.go @@ -10,7 +10,7 @@ import ( "google.golang.org/grpc/metadata" ) -// ServerStreamWrapper wraps grpc.ServerStream and adds locking to send path +// ServerStreamWrapper wraps grpc.ServerStream and adds locking to the send path. type ServerStreamWrapper struct { grpc.ServerStream @@ -32,6 +32,7 @@ func (wrapper *ServerStreamWrapper) SetHeader(md metadata.MD) error { // hack: swallow grpc.internal.transport.ErrIllegalHeaderWrite err = nil } + return err } @@ -47,6 +48,7 @@ func (wrapper *ServerStreamWrapper) SendHeader(md metadata.MD) error { // hack: swallow grpc.internal.transport.ErrIllegalHeaderWrite err = nil } + return err } diff --git a/testservice/Makefile b/testservice/Makefile deleted file mode 100644 index f2c9558..0000000 --- a/testservice/Makefile +++ /dev/null @@ -1,11 +0,0 @@ - -all: test_go - -test_go: test.proto - PATH="${GOPATH}/bin:${PATH}" protoc \ - -I. \ - -I${GOPATH}/src \ - --go_out=plugins=grpc:. \ - test.proto - - diff --git a/testservice/api/test.proto b/testservice/api/test.proto new file mode 100644 index 0000000..9653a2c --- /dev/null +++ b/testservice/api/test.proto @@ -0,0 +1,58 @@ +syntax = "proto3"; + +package talos.testproto; + +message Empty {} + +message PingRequest { string value = 1; } + +message PingResponse { + string Value = 1; + int32 counter = 2; +} + +service TestService { + rpc PingEmpty(Empty) returns (PingResponse) {} + + rpc Ping(PingRequest) returns (PingResponse) {} + + rpc PingError(PingRequest) returns (Empty) {} + + rpc PingList(PingRequest) returns (stream PingResponse) {} + + rpc PingStream(stream PingRequest) returns (stream PingResponse) {} +} + +message ResponseMetadata { + string hostname = 99; + string upstream_error = 100; +} + +message ResponseMetadataPrepender { ResponseMetadata metadata = 99; } + +message MultiPingResponse { + ResponseMetadata metadata = 99; + string Value = 1; + int32 counter = 2; + string server = 3; +} + +message MultiPingReply { repeated MultiPingResponse response = 1; } + +message EmptyReply { repeated EmptyResponse response = 1; } + +message EmptyResponse { ResponseMetadata metadata = 99; } + +service MultiService { + rpc PingEmpty(Empty) returns (MultiPingReply) {} + + rpc Ping(PingRequest) returns (MultiPingReply) {} + + rpc PingError(PingRequest) returns (EmptyReply) {} + + rpc PingList(PingRequest) returns (stream MultiPingResponse) {} + + rpc PingStream(stream PingRequest) returns (stream MultiPingResponse) {} + + rpc PingStreamError(stream PingRequest) returns (stream MultiPingResponse) {} +} diff --git a/testservice/test.pb.go b/testservice/test.pb.go index f16a783..e5adfac 100644 --- a/testservice/test.pb.go +++ b/testservice/test.pb.go @@ -1,1083 +1,779 @@ // Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0 +// protoc v3.13.0 // source: test.proto package talos_testproto import ( - context "context" - fmt "fmt" proto "github.com/golang/protobuf/proto" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" - math "math" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf +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 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 +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 type Empty struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } -func (m *Empty) Reset() { *m = Empty{} } -func (m *Empty) String() string { return proto.CompactTextString(m) } -func (*Empty) ProtoMessage() {} -func (*Empty) Descriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{0} +func (x *Empty) Reset() { + *x = Empty{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Empty) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Empty.Unmarshal(m, b) -} -func (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Empty.Marshal(b, m, deterministic) -} -func (m *Empty) XXX_Merge(src proto.Message) { - xxx_messageInfo_Empty.Merge(m, src) -} -func (m *Empty) XXX_Size() int { - return xxx_messageInfo_Empty.Size(m) -} -func (m *Empty) XXX_DiscardUnknown() { - xxx_messageInfo_Empty.DiscardUnknown(m) +func (x *Empty) String() string { + return protoimpl.X.MessageStringOf(x) } -var xxx_messageInfo_Empty proto.InternalMessageInfo +func (*Empty) ProtoMessage() {} -type PingRequest struct { - Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *PingRequest) Reset() { *m = PingRequest{} } -func (m *PingRequest) String() string { return proto.CompactTextString(m) } -func (*PingRequest) ProtoMessage() {} -func (*PingRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{1} -} - -func (m *PingRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PingRequest.Unmarshal(m, b) -} -func (m *PingRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PingRequest.Marshal(b, m, deterministic) -} -func (m *PingRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_PingRequest.Merge(m, src) -} -func (m *PingRequest) XXX_Size() int { - return xxx_messageInfo_PingRequest.Size(m) -} -func (m *PingRequest) XXX_DiscardUnknown() { - xxx_messageInfo_PingRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_PingRequest proto.InternalMessageInfo - -func (m *PingRequest) GetValue() string { - if m != nil { - return m.Value +func (x *Empty) ProtoReflect() protoreflect.Message { + mi := &file_test_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 "" + return mi.MessageOf(x) } -type PingResponse struct { - Value string `protobuf:"bytes,1,opt,name=Value,proto3" json:"Value,omitempty"` - Counter int32 `protobuf:"varint,2,opt,name=counter,proto3" json:"counter,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` +// Deprecated: Use Empty.ProtoReflect.Descriptor instead. +func (*Empty) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{0} } -func (m *PingResponse) Reset() { *m = PingResponse{} } -func (m *PingResponse) String() string { return proto.CompactTextString(m) } -func (*PingResponse) ProtoMessage() {} -func (*PingResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{2} -} +type PingRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *PingResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PingResponse.Unmarshal(m, b) -} -func (m *PingResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PingResponse.Marshal(b, m, deterministic) -} -func (m *PingResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_PingResponse.Merge(m, src) -} -func (m *PingResponse) XXX_Size() int { - return xxx_messageInfo_PingResponse.Size(m) + Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` } -func (m *PingResponse) XXX_DiscardUnknown() { - xxx_messageInfo_PingResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_PingResponse proto.InternalMessageInfo -func (m *PingResponse) GetValue() string { - if m != nil { - return m.Value +func (x *PingRequest) Reset() { + *x = PingRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } - return "" } -func (m *PingResponse) GetCounter() int32 { - if m != nil { - return m.Counter - } - return 0 -} - -type ResponseMetadata struct { - Hostname string `protobuf:"bytes,99,opt,name=hostname,proto3" json:"hostname,omitempty"` - UpstreamError string `protobuf:"bytes,100,opt,name=upstream_error,json=upstreamError,proto3" json:"upstream_error,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` +func (x *PingRequest) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *ResponseMetadata) Reset() { *m = ResponseMetadata{} } -func (m *ResponseMetadata) String() string { return proto.CompactTextString(m) } -func (*ResponseMetadata) ProtoMessage() {} -func (*ResponseMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{3} -} +func (*PingRequest) ProtoMessage() {} -func (m *ResponseMetadata) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ResponseMetadata.Unmarshal(m, b) -} -func (m *ResponseMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ResponseMetadata.Marshal(b, m, deterministic) -} -func (m *ResponseMetadata) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResponseMetadata.Merge(m, src) -} -func (m *ResponseMetadata) XXX_Size() int { - return xxx_messageInfo_ResponseMetadata.Size(m) -} -func (m *ResponseMetadata) XXX_DiscardUnknown() { - xxx_messageInfo_ResponseMetadata.DiscardUnknown(m) +func (x *PingRequest) ProtoReflect() protoreflect.Message { + mi := &file_test_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) } -var xxx_messageInfo_ResponseMetadata proto.InternalMessageInfo - -func (m *ResponseMetadata) GetHostname() string { - if m != nil { - return m.Hostname - } - return "" +// Deprecated: Use PingRequest.ProtoReflect.Descriptor instead. +func (*PingRequest) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{1} } -func (m *ResponseMetadata) GetUpstreamError() string { - if m != nil { - return m.UpstreamError +func (x *PingRequest) GetValue() string { + if x != nil { + return x.Value } return "" } -type ResponseMetadataPrepender struct { - Metadata *ResponseMetadata `protobuf:"bytes,99,opt,name=metadata,proto3" json:"metadata,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ResponseMetadataPrepender) Reset() { *m = ResponseMetadataPrepender{} } -func (m *ResponseMetadataPrepender) String() string { return proto.CompactTextString(m) } -func (*ResponseMetadataPrepender) ProtoMessage() {} -func (*ResponseMetadataPrepender) Descriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{4} -} +type PingResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *ResponseMetadataPrepender) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ResponseMetadataPrepender.Unmarshal(m, b) -} -func (m *ResponseMetadataPrepender) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ResponseMetadataPrepender.Marshal(b, m, deterministic) -} -func (m *ResponseMetadataPrepender) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResponseMetadataPrepender.Merge(m, src) -} -func (m *ResponseMetadataPrepender) XXX_Size() int { - return xxx_messageInfo_ResponseMetadataPrepender.Size(m) + Value string `protobuf:"bytes,1,opt,name=Value,proto3" json:"Value,omitempty"` + Counter int32 `protobuf:"varint,2,opt,name=counter,proto3" json:"counter,omitempty"` } -func (m *ResponseMetadataPrepender) XXX_DiscardUnknown() { - xxx_messageInfo_ResponseMetadataPrepender.DiscardUnknown(m) -} - -var xxx_messageInfo_ResponseMetadataPrepender proto.InternalMessageInfo -func (m *ResponseMetadataPrepender) GetMetadata() *ResponseMetadata { - if m != nil { - return m.Metadata +func (x *PingResponse) Reset() { + *x = PingResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } - return nil } -type MultiPingResponse struct { - Metadata *ResponseMetadata `protobuf:"bytes,99,opt,name=metadata,proto3" json:"metadata,omitempty"` - Value string `protobuf:"bytes,1,opt,name=Value,proto3" json:"Value,omitempty"` - Counter int32 `protobuf:"varint,2,opt,name=counter,proto3" json:"counter,omitempty"` - Server string `protobuf:"bytes,3,opt,name=server,proto3" json:"server,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` +func (x *PingResponse) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *MultiPingResponse) Reset() { *m = MultiPingResponse{} } -func (m *MultiPingResponse) String() string { return proto.CompactTextString(m) } -func (*MultiPingResponse) ProtoMessage() {} -func (*MultiPingResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{5} -} +func (*PingResponse) ProtoMessage() {} -func (m *MultiPingResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_MultiPingResponse.Unmarshal(m, b) -} -func (m *MultiPingResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_MultiPingResponse.Marshal(b, m, deterministic) -} -func (m *MultiPingResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_MultiPingResponse.Merge(m, src) -} -func (m *MultiPingResponse) XXX_Size() int { - return xxx_messageInfo_MultiPingResponse.Size(m) -} -func (m *MultiPingResponse) XXX_DiscardUnknown() { - xxx_messageInfo_MultiPingResponse.DiscardUnknown(m) +func (x *PingResponse) ProtoReflect() protoreflect.Message { + mi := &file_test_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) } -var xxx_messageInfo_MultiPingResponse proto.InternalMessageInfo - -func (m *MultiPingResponse) GetMetadata() *ResponseMetadata { - if m != nil { - return m.Metadata - } - return nil +// Deprecated: Use PingResponse.ProtoReflect.Descriptor instead. +func (*PingResponse) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{2} } -func (m *MultiPingResponse) GetValue() string { - if m != nil { - return m.Value +func (x *PingResponse) GetValue() string { + if x != nil { + return x.Value } return "" } -func (m *MultiPingResponse) GetCounter() int32 { - if m != nil { - return m.Counter +func (x *PingResponse) GetCounter() int32 { + if x != nil { + return x.Counter } return 0 } -func (m *MultiPingResponse) GetServer() string { - if m != nil { - return m.Server - } - return "" -} - -type MultiPingReply struct { - Response []*MultiPingResponse `protobuf:"bytes,1,rep,name=response,proto3" json:"response,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *MultiPingReply) Reset() { *m = MultiPingReply{} } -func (m *MultiPingReply) String() string { return proto.CompactTextString(m) } -func (*MultiPingReply) ProtoMessage() {} -func (*MultiPingReply) Descriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{6} -} +type ResponseMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *MultiPingReply) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_MultiPingReply.Unmarshal(m, b) -} -func (m *MultiPingReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_MultiPingReply.Marshal(b, m, deterministic) -} -func (m *MultiPingReply) XXX_Merge(src proto.Message) { - xxx_messageInfo_MultiPingReply.Merge(m, src) -} -func (m *MultiPingReply) XXX_Size() int { - return xxx_messageInfo_MultiPingReply.Size(m) + Hostname string `protobuf:"bytes,99,opt,name=hostname,proto3" json:"hostname,omitempty"` + UpstreamError string `protobuf:"bytes,100,opt,name=upstream_error,json=upstreamError,proto3" json:"upstream_error,omitempty"` } -func (m *MultiPingReply) XXX_DiscardUnknown() { - xxx_messageInfo_MultiPingReply.DiscardUnknown(m) -} - -var xxx_messageInfo_MultiPingReply proto.InternalMessageInfo -func (m *MultiPingReply) GetResponse() []*MultiPingResponse { - if m != nil { - return m.Response +func (x *ResponseMetadata) Reset() { + *x = ResponseMetadata{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } - return nil -} - -type EmptyReply struct { - Response []*EmptyResponse `protobuf:"bytes,1,rep,name=response,proto3" json:"response,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EmptyReply) Reset() { *m = EmptyReply{} } -func (m *EmptyReply) String() string { return proto.CompactTextString(m) } -func (*EmptyReply) ProtoMessage() {} -func (*EmptyReply) Descriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{7} } -func (m *EmptyReply) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EmptyReply.Unmarshal(m, b) -} -func (m *EmptyReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EmptyReply.Marshal(b, m, deterministic) -} -func (m *EmptyReply) XXX_Merge(src proto.Message) { - xxx_messageInfo_EmptyReply.Merge(m, src) -} -func (m *EmptyReply) XXX_Size() int { - return xxx_messageInfo_EmptyReply.Size(m) -} -func (m *EmptyReply) XXX_DiscardUnknown() { - xxx_messageInfo_EmptyReply.DiscardUnknown(m) +func (x *ResponseMetadata) String() string { + return protoimpl.X.MessageStringOf(x) } -var xxx_messageInfo_EmptyReply proto.InternalMessageInfo +func (*ResponseMetadata) ProtoMessage() {} -func (m *EmptyReply) GetResponse() []*EmptyResponse { - if m != nil { - return m.Response +func (x *ResponseMetadata) ProtoReflect() protoreflect.Message { + mi := &file_test_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 nil -} - -type EmptyResponse struct { - Metadata *ResponseMetadata `protobuf:"bytes,99,opt,name=metadata,proto3" json:"metadata,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EmptyResponse) Reset() { *m = EmptyResponse{} } -func (m *EmptyResponse) String() string { return proto.CompactTextString(m) } -func (*EmptyResponse) ProtoMessage() {} -func (*EmptyResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{8} + return mi.MessageOf(x) } -func (m *EmptyResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EmptyResponse.Unmarshal(m, b) -} -func (m *EmptyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EmptyResponse.Marshal(b, m, deterministic) -} -func (m *EmptyResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_EmptyResponse.Merge(m, src) -} -func (m *EmptyResponse) XXX_Size() int { - return xxx_messageInfo_EmptyResponse.Size(m) -} -func (m *EmptyResponse) XXX_DiscardUnknown() { - xxx_messageInfo_EmptyResponse.DiscardUnknown(m) +// Deprecated: Use ResponseMetadata.ProtoReflect.Descriptor instead. +func (*ResponseMetadata) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{3} } -var xxx_messageInfo_EmptyResponse proto.InternalMessageInfo - -func (m *EmptyResponse) GetMetadata() *ResponseMetadata { - if m != nil { - return m.Metadata +func (x *ResponseMetadata) GetHostname() string { + if x != nil { + return x.Hostname } - return nil -} - -func init() { - proto.RegisterType((*Empty)(nil), "talos.testproto.Empty") - proto.RegisterType((*PingRequest)(nil), "talos.testproto.PingRequest") - proto.RegisterType((*PingResponse)(nil), "talos.testproto.PingResponse") - proto.RegisterType((*ResponseMetadata)(nil), "talos.testproto.ResponseMetadata") - proto.RegisterType((*ResponseMetadataPrepender)(nil), "talos.testproto.ResponseMetadataPrepender") - proto.RegisterType((*MultiPingResponse)(nil), "talos.testproto.MultiPingResponse") - proto.RegisterType((*MultiPingReply)(nil), "talos.testproto.MultiPingReply") - proto.RegisterType((*EmptyReply)(nil), "talos.testproto.EmptyReply") - proto.RegisterType((*EmptyResponse)(nil), "talos.testproto.EmptyResponse") -} - -func init() { proto.RegisterFile("test.proto", fileDescriptor_c161fcfdc0c3ff1e) } - -var fileDescriptor_c161fcfdc0c3ff1e = []byte{ - // 456 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xa4, 0x93, 0x5d, 0xcf, 0xd2, 0x30, - 0x14, 0xc7, 0x1d, 0x08, 0x8c, 0xc3, 0x9b, 0x36, 0x86, 0x4c, 0x7c, 0xaf, 0x31, 0xe1, 0x6a, 0x21, - 0x78, 0x67, 0x22, 0x37, 0x8a, 0x92, 0x28, 0xba, 0x0c, 0x34, 0xd1, 0x1b, 0x33, 0xa1, 0xd1, 0x25, - 0x7b, 0xb3, 0xeb, 0x48, 0xf8, 0x2a, 0x7e, 0x46, 0xbf, 0x82, 0x89, 0x6d, 0xb7, 0x21, 0xb0, 0x87, - 0x87, 0x92, 0x5d, 0x9e, 0x7f, 0xcf, 0xf9, 0xf5, 0x9c, 0xfe, 0x4f, 0x01, 0x18, 0x89, 0x99, 0x19, - 0xd1, 0x90, 0x85, 0xa8, 0xc7, 0x1c, 0x2f, 0x8c, 0x4d, 0xa1, 0x48, 0x01, 0x37, 0xa0, 0x36, 0xf5, - 0x23, 0xb6, 0xc5, 0x4f, 0xa1, 0x65, 0xb9, 0xc1, 0x0f, 0x9b, 0xfc, 0x4a, 0xf8, 0x21, 0xba, 0x03, - 0xb5, 0x8d, 0xe3, 0x25, 0xc4, 0xd0, 0x1e, 0x6b, 0xc3, 0xa6, 0x9d, 0x06, 0x78, 0x02, 0xed, 0x34, - 0x29, 0x8e, 0xc2, 0x20, 0x26, 0x22, 0xeb, 0xf3, 0x7e, 0x96, 0x0c, 0x90, 0x01, 0x8d, 0x55, 0x98, - 0x04, 0x8c, 0x50, 0xa3, 0xc2, 0xf5, 0x9a, 0x9d, 0x87, 0xf8, 0x13, 0xdc, 0xca, 0x6b, 0xe7, 0x84, - 0x39, 0x6b, 0x87, 0x39, 0x68, 0x00, 0xfa, 0xcf, 0x30, 0x66, 0x81, 0xe3, 0x13, 0x63, 0x25, 0x31, - 0xbb, 0x18, 0x3d, 0x83, 0x6e, 0x12, 0xc5, 0x8c, 0x12, 0xc7, 0xff, 0x46, 0x28, 0x0d, 0xa9, 0xb1, - 0x96, 0x19, 0x9d, 0x5c, 0x9d, 0x0a, 0x11, 0x7f, 0x85, 0xbb, 0xc7, 0x58, 0x8b, 0x92, 0x88, 0x04, - 0x6b, 0x42, 0xd1, 0x4b, 0xd0, 0xfd, 0x4c, 0x94, 0xfc, 0xd6, 0xf8, 0x89, 0x79, 0xf4, 0x0a, 0xe6, - 0x71, 0xb5, 0xbd, 0x2b, 0xc1, 0xbf, 0x35, 0xb8, 0x3d, 0x4f, 0x3c, 0xe6, 0x1e, 0x0c, 0x5e, 0x0e, - 0x7a, 0xe9, 0xbb, 0xa1, 0x3e, 0xd4, 0x63, 0x42, 0x37, 0xfc, 0xa0, 0x2a, 0x0b, 0xb2, 0x08, 0x5b, - 0xd0, 0xdd, 0xeb, 0x2d, 0xf2, 0xb6, 0x68, 0x02, 0x3a, 0xcd, 0xee, 0xe5, 0xf0, 0x2a, 0x6f, 0x0c, - 0x17, 0x1a, 0x2b, 0x8c, 0x63, 0xef, 0x6a, 0xf0, 0x0c, 0x40, 0xee, 0x43, 0x4a, 0x7b, 0x51, 0xa0, - 0x3d, 0x2c, 0xd0, 0xb2, 0xf4, 0x02, 0xe9, 0x03, 0x74, 0x0e, 0x8e, 0x4a, 0xbe, 0xd9, 0xf8, 0x6f, - 0x05, 0x5a, 0x4b, 0x9e, 0xb8, 0xe0, 0xa3, 0xbb, 0x2b, 0x82, 0x5e, 0x43, 0x53, 0xcc, 0x20, 0xef, - 0x40, 0xfd, 0xab, 0xdb, 0x1a, 0x3c, 0x28, 0xe8, 0xfb, 0x73, 0xe3, 0x1b, 0x68, 0x0a, 0x37, 0x85, - 0x82, 0xee, 0x9f, 0x48, 0x94, 0xbf, 0xe1, 0x3c, 0xe6, 0x55, 0xd6, 0x8c, 0x58, 0xc7, 0x33, 0xac, - 0x13, 0xad, 0x72, 0xc8, 0x3b, 0xd0, 0x45, 0xe2, 0x7b, 0x97, 0xff, 0xbf, 0x72, 0xfd, 0x8c, 0x34, - 0xf4, 0x11, 0x40, 0x68, 0x0b, 0xf9, 0x4d, 0x4a, 0xe2, 0x86, 0xda, 0x48, 0x1b, 0xff, 0xa9, 0x42, - 0x5b, 0x6e, 0x4e, 0x6e, 0xc0, 0x1b, 0x15, 0x03, 0x1e, 0x5d, 0xb7, 0x7d, 0x7c, 0xc5, 0xf8, 0xd8, - 0x6f, 0x95, 0x2c, 0x50, 0x00, 0xcd, 0xd4, 0x4d, 0xb8, 0x77, 0x6a, 0x8d, 0x53, 0x92, 0xa5, 0xec, - 0x84, 0xc2, 0xef, 0x92, 0x76, 0x2c, 0x2f, 0xb0, 0x43, 0x89, 0x29, 0x3c, 0x41, 0x5f, 0xa0, 0xf7, - 0x9f, 0xaa, 0x32, 0xb7, 0x32, 0xfa, 0x7b, 0x5d, 0x1e, 0x3f, 0xff, 0x17, 0x00, 0x00, 0xff, 0xff, - 0x8f, 0xae, 0x5f, 0xeb, 0x3e, 0x06, 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 - -// TestServiceClient is the client API for TestService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type TestServiceClient interface { - PingEmpty(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*PingResponse, error) - Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) - PingError(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*Empty, error) - PingList(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (TestService_PingListClient, error) - PingStream(ctx context.Context, opts ...grpc.CallOption) (TestService_PingStreamClient, error) -} - -type testServiceClient struct { - cc *grpc.ClientConn -} - -func NewTestServiceClient(cc *grpc.ClientConn) TestServiceClient { - return &testServiceClient{cc} + return "" } -func (c *testServiceClient) PingEmpty(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*PingResponse, error) { - out := new(PingResponse) - err := c.cc.Invoke(ctx, "/talos.testproto.TestService/PingEmpty", in, out, opts...) - if err != nil { - return nil, err +func (x *ResponseMetadata) GetUpstreamError() string { + if x != nil { + return x.UpstreamError } - return out, nil + return "" } -func (c *testServiceClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) { - out := new(PingResponse) - err := c.cc.Invoke(ctx, "/talos.testproto.TestService/Ping", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} +type ResponseMetadataPrepender struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (c *testServiceClient) PingError(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*Empty, error) { - out := new(Empty) - err := c.cc.Invoke(ctx, "/talos.testproto.TestService/PingError", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil + Metadata *ResponseMetadata `protobuf:"bytes,99,opt,name=metadata,proto3" json:"metadata,omitempty"` } -func (c *testServiceClient) PingList(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (TestService_PingListClient, error) { - stream, err := c.cc.NewStream(ctx, &_TestService_serviceDesc.Streams[0], "/talos.testproto.TestService/PingList", opts...) - if err != nil { - return nil, err - } - x := &testServicePingListClient{stream} - if err := x.ClientStream.SendMsg(in); err != nil { - return nil, err +func (x *ResponseMetadataPrepender) Reset() { + *x = ResponseMetadataPrepender{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } - if err := x.ClientStream.CloseSend(); err != nil { - return nil, err - } - return x, nil } -type TestService_PingListClient interface { - Recv() (*PingResponse, error) - grpc.ClientStream +func (x *ResponseMetadataPrepender) String() string { + return protoimpl.X.MessageStringOf(x) } -type testServicePingListClient struct { - grpc.ClientStream -} +func (*ResponseMetadataPrepender) ProtoMessage() {} -func (x *testServicePingListClient) Recv() (*PingResponse, error) { - m := new(PingResponse) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err +func (x *ResponseMetadataPrepender) ProtoReflect() protoreflect.Message { + mi := &file_test_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 m, nil + return mi.MessageOf(x) } -func (c *testServiceClient) PingStream(ctx context.Context, opts ...grpc.CallOption) (TestService_PingStreamClient, error) { - stream, err := c.cc.NewStream(ctx, &_TestService_serviceDesc.Streams[1], "/talos.testproto.TestService/PingStream", opts...) - if err != nil { - return nil, err - } - x := &testServicePingStreamClient{stream} - return x, nil +// Deprecated: Use ResponseMetadataPrepender.ProtoReflect.Descriptor instead. +func (*ResponseMetadataPrepender) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{4} } -type TestService_PingStreamClient interface { - Send(*PingRequest) error - Recv() (*PingResponse, error) - grpc.ClientStream +func (x *ResponseMetadataPrepender) GetMetadata() *ResponseMetadata { + if x != nil { + return x.Metadata + } + return nil } -type testServicePingStreamClient struct { - grpc.ClientStream -} +type MultiPingResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (x *testServicePingStreamClient) Send(m *PingRequest) error { - return x.ClientStream.SendMsg(m) + Metadata *ResponseMetadata `protobuf:"bytes,99,opt,name=metadata,proto3" json:"metadata,omitempty"` + Value string `protobuf:"bytes,1,opt,name=Value,proto3" json:"Value,omitempty"` + Counter int32 `protobuf:"varint,2,opt,name=counter,proto3" json:"counter,omitempty"` + Server string `protobuf:"bytes,3,opt,name=server,proto3" json:"server,omitempty"` } -func (x *testServicePingStreamClient) Recv() (*PingResponse, error) { - m := new(PingResponse) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err +func (x *MultiPingResponse) Reset() { + *x = MultiPingResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } - return m, nil } -// TestServiceServer is the server API for TestService service. -type TestServiceServer interface { - PingEmpty(context.Context, *Empty) (*PingResponse, error) - Ping(context.Context, *PingRequest) (*PingResponse, error) - PingError(context.Context, *PingRequest) (*Empty, error) - PingList(*PingRequest, TestService_PingListServer) error - PingStream(TestService_PingStreamServer) error +func (x *MultiPingResponse) String() string { + return protoimpl.X.MessageStringOf(x) } -// UnimplementedTestServiceServer can be embedded to have forward compatible implementations. -type UnimplementedTestServiceServer struct { -} +func (*MultiPingResponse) ProtoMessage() {} -func (*UnimplementedTestServiceServer) PingEmpty(ctx context.Context, req *Empty) (*PingResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method PingEmpty not implemented") -} -func (*UnimplementedTestServiceServer) Ping(ctx context.Context, req *PingRequest) (*PingResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented") -} -func (*UnimplementedTestServiceServer) PingError(ctx context.Context, req *PingRequest) (*Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method PingError not implemented") -} -func (*UnimplementedTestServiceServer) PingList(req *PingRequest, srv TestService_PingListServer) error { - return status.Errorf(codes.Unimplemented, "method PingList not implemented") -} -func (*UnimplementedTestServiceServer) PingStream(srv TestService_PingStreamServer) error { - return status.Errorf(codes.Unimplemented, "method PingStream not implemented") +func (x *MultiPingResponse) ProtoReflect() protoreflect.Message { + mi := &file_test_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) } -func RegisterTestServiceServer(s *grpc.Server, srv TestServiceServer) { - s.RegisterService(&_TestService_serviceDesc, srv) +// Deprecated: Use MultiPingResponse.ProtoReflect.Descriptor instead. +func (*MultiPingResponse) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{5} } -func _TestService_PingEmpty_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Empty) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TestServiceServer).PingEmpty(ctx, in) +func (x *MultiPingResponse) GetMetadata() *ResponseMetadata { + if x != nil { + return x.Metadata } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/talos.testproto.TestService/PingEmpty", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TestServiceServer).PingEmpty(ctx, req.(*Empty)) - } - return interceptor(ctx, in, info, handler) + return nil } -func _TestService_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PingRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TestServiceServer).Ping(ctx, in) +func (x *MultiPingResponse) GetValue() string { + if x != nil { + return x.Value } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/talos.testproto.TestService/Ping", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TestServiceServer).Ping(ctx, req.(*PingRequest)) - } - return interceptor(ctx, in, info, handler) + return "" } -func _TestService_PingError_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PingRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TestServiceServer).PingError(ctx, in) +func (x *MultiPingResponse) GetCounter() int32 { + if x != nil { + return x.Counter } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/talos.testproto.TestService/PingError", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TestServiceServer).PingError(ctx, req.(*PingRequest)) - } - return interceptor(ctx, in, info, handler) + return 0 } -func _TestService_PingList_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(PingRequest) - if err := stream.RecvMsg(m); err != nil { - return err +func (x *MultiPingResponse) GetServer() string { + if x != nil { + return x.Server } - return srv.(TestServiceServer).PingList(m, &testServicePingListServer{stream}) -} - -type TestService_PingListServer interface { - Send(*PingResponse) error - grpc.ServerStream -} - -type testServicePingListServer struct { - grpc.ServerStream -} - -func (x *testServicePingListServer) Send(m *PingResponse) error { - return x.ServerStream.SendMsg(m) -} - -func _TestService_PingStream_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(TestServiceServer).PingStream(&testServicePingStreamServer{stream}) -} - -type TestService_PingStreamServer interface { - Send(*PingResponse) error - Recv() (*PingRequest, error) - grpc.ServerStream + return "" } -type testServicePingStreamServer struct { - grpc.ServerStream -} +type MultiPingReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (x *testServicePingStreamServer) Send(m *PingResponse) error { - return x.ServerStream.SendMsg(m) + Response []*MultiPingResponse `protobuf:"bytes,1,rep,name=response,proto3" json:"response,omitempty"` } -func (x *testServicePingStreamServer) Recv() (*PingRequest, error) { - m := new(PingRequest) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err +func (x *MultiPingReply) Reset() { + *x = MultiPingReply{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } - return m, nil -} - -var _TestService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "talos.testproto.TestService", - HandlerType: (*TestServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "PingEmpty", - Handler: _TestService_PingEmpty_Handler, - }, - { - MethodName: "Ping", - Handler: _TestService_Ping_Handler, - }, - { - MethodName: "PingError", - Handler: _TestService_PingError_Handler, - }, - }, - Streams: []grpc.StreamDesc{ - { - StreamName: "PingList", - Handler: _TestService_PingList_Handler, - ServerStreams: true, - }, - { - StreamName: "PingStream", - Handler: _TestService_PingStream_Handler, - ServerStreams: true, - ClientStreams: true, - }, - }, - Metadata: "test.proto", -} - -// MultiServiceClient is the client API for MultiService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type MultiServiceClient interface { - PingEmpty(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*MultiPingReply, error) - Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*MultiPingReply, error) - PingError(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*EmptyReply, error) - PingList(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (MultiService_PingListClient, error) - PingStream(ctx context.Context, opts ...grpc.CallOption) (MultiService_PingStreamClient, error) - PingStreamError(ctx context.Context, opts ...grpc.CallOption) (MultiService_PingStreamErrorClient, error) -} - -type multiServiceClient struct { - cc *grpc.ClientConn } -func NewMultiServiceClient(cc *grpc.ClientConn) MultiServiceClient { - return &multiServiceClient{cc} +func (x *MultiPingReply) String() string { + return protoimpl.X.MessageStringOf(x) } -func (c *multiServiceClient) PingEmpty(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*MultiPingReply, error) { - out := new(MultiPingReply) - err := c.cc.Invoke(ctx, "/talos.testproto.MultiService/PingEmpty", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} +func (*MultiPingReply) ProtoMessage() {} -func (c *multiServiceClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*MultiPingReply, error) { - out := new(MultiPingReply) - err := c.cc.Invoke(ctx, "/talos.testproto.MultiService/Ping", in, out, opts...) - if err != nil { - return nil, err +func (x *MultiPingReply) ProtoReflect() protoreflect.Message { + mi := &file_test_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 out, nil + return mi.MessageOf(x) } -func (c *multiServiceClient) PingError(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*EmptyReply, error) { - out := new(EmptyReply) - err := c.cc.Invoke(ctx, "/talos.testproto.MultiService/PingError", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil +// Deprecated: Use MultiPingReply.ProtoReflect.Descriptor instead. +func (*MultiPingReply) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{6} } -func (c *multiServiceClient) PingList(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (MultiService_PingListClient, error) { - stream, err := c.cc.NewStream(ctx, &_MultiService_serviceDesc.Streams[0], "/talos.testproto.MultiService/PingList", opts...) - if err != nil { - return nil, err - } - x := &multiServicePingListClient{stream} - if err := x.ClientStream.SendMsg(in); err != nil { - return nil, err +func (x *MultiPingReply) GetResponse() []*MultiPingResponse { + if x != nil { + return x.Response } - if err := x.ClientStream.CloseSend(); err != nil { - return nil, err - } - return x, nil -} - -type MultiService_PingListClient interface { - Recv() (*MultiPingResponse, error) - grpc.ClientStream + return nil } -type multiServicePingListClient struct { - grpc.ClientStream -} +type EmptyReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (x *multiServicePingListClient) Recv() (*MultiPingResponse, error) { - m := new(MultiPingResponse) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil + Response []*EmptyResponse `protobuf:"bytes,1,rep,name=response,proto3" json:"response,omitempty"` } -func (c *multiServiceClient) PingStream(ctx context.Context, opts ...grpc.CallOption) (MultiService_PingStreamClient, error) { - stream, err := c.cc.NewStream(ctx, &_MultiService_serviceDesc.Streams[1], "/talos.testproto.MultiService/PingStream", opts...) - if err != nil { - return nil, err +func (x *EmptyReply) Reset() { + *x = EmptyReply{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } - x := &multiServicePingStreamClient{stream} - return x, nil -} - -type MultiService_PingStreamClient interface { - Send(*PingRequest) error - Recv() (*MultiPingResponse, error) - grpc.ClientStream -} - -type multiServicePingStreamClient struct { - grpc.ClientStream } -func (x *multiServicePingStreamClient) Send(m *PingRequest) error { - return x.ClientStream.SendMsg(m) +func (x *EmptyReply) String() string { + return protoimpl.X.MessageStringOf(x) } -func (x *multiServicePingStreamClient) Recv() (*MultiPingResponse, error) { - m := new(MultiPingResponse) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} +func (*EmptyReply) ProtoMessage() {} -func (c *multiServiceClient) PingStreamError(ctx context.Context, opts ...grpc.CallOption) (MultiService_PingStreamErrorClient, error) { - stream, err := c.cc.NewStream(ctx, &_MultiService_serviceDesc.Streams[2], "/talos.testproto.MultiService/PingStreamError", opts...) - if err != nil { - return nil, err +func (x *EmptyReply) ProtoReflect() protoreflect.Message { + mi := &file_test_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - x := &multiServicePingStreamErrorClient{stream} - return x, nil -} - -type MultiService_PingStreamErrorClient interface { - Send(*PingRequest) error - Recv() (*MultiPingResponse, error) - grpc.ClientStream -} - -type multiServicePingStreamErrorClient struct { - grpc.ClientStream + return mi.MessageOf(x) } -func (x *multiServicePingStreamErrorClient) Send(m *PingRequest) error { - return x.ClientStream.SendMsg(m) +// Deprecated: Use EmptyReply.ProtoReflect.Descriptor instead. +func (*EmptyReply) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{7} } -func (x *multiServicePingStreamErrorClient) Recv() (*MultiPingResponse, error) { - m := new(MultiPingResponse) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err +func (x *EmptyReply) GetResponse() []*EmptyResponse { + if x != nil { + return x.Response } - return m, nil -} - -// MultiServiceServer is the server API for MultiService service. -type MultiServiceServer interface { - PingEmpty(context.Context, *Empty) (*MultiPingReply, error) - Ping(context.Context, *PingRequest) (*MultiPingReply, error) - PingError(context.Context, *PingRequest) (*EmptyReply, error) - PingList(*PingRequest, MultiService_PingListServer) error - PingStream(MultiService_PingStreamServer) error - PingStreamError(MultiService_PingStreamErrorServer) error -} - -// UnimplementedMultiServiceServer can be embedded to have forward compatible implementations. -type UnimplementedMultiServiceServer struct { + return nil } -func (*UnimplementedMultiServiceServer) PingEmpty(ctx context.Context, req *Empty) (*MultiPingReply, error) { - return nil, status.Errorf(codes.Unimplemented, "method PingEmpty not implemented") -} -func (*UnimplementedMultiServiceServer) Ping(ctx context.Context, req *PingRequest) (*MultiPingReply, error) { - return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented") -} -func (*UnimplementedMultiServiceServer) PingError(ctx context.Context, req *PingRequest) (*EmptyReply, error) { - return nil, status.Errorf(codes.Unimplemented, "method PingError not implemented") -} -func (*UnimplementedMultiServiceServer) PingList(req *PingRequest, srv MultiService_PingListServer) error { - return status.Errorf(codes.Unimplemented, "method PingList not implemented") -} -func (*UnimplementedMultiServiceServer) PingStream(srv MultiService_PingStreamServer) error { - return status.Errorf(codes.Unimplemented, "method PingStream not implemented") -} -func (*UnimplementedMultiServiceServer) PingStreamError(srv MultiService_PingStreamErrorServer) error { - return status.Errorf(codes.Unimplemented, "method PingStreamError not implemented") -} +type EmptyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func RegisterMultiServiceServer(s *grpc.Server, srv MultiServiceServer) { - s.RegisterService(&_MultiService_serviceDesc, srv) + Metadata *ResponseMetadata `protobuf:"bytes,99,opt,name=metadata,proto3" json:"metadata,omitempty"` } -func _MultiService_PingEmpty_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Empty) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MultiServiceServer).PingEmpty(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/talos.testproto.MultiService/PingEmpty", +func (x *EmptyResponse) Reset() { + *x = EmptyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MultiServiceServer).PingEmpty(ctx, req.(*Empty)) - } - return interceptor(ctx, in, info, handler) } -func _MultiService_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PingRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MultiServiceServer).Ping(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/talos.testproto.MultiService/Ping", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MultiServiceServer).Ping(ctx, req.(*PingRequest)) - } - return interceptor(ctx, in, info, handler) +func (x *EmptyResponse) String() string { + return protoimpl.X.MessageStringOf(x) } -func _MultiService_PingError_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PingRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MultiServiceServer).PingError(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/talos.testproto.MultiService/PingError", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MultiServiceServer).PingError(ctx, req.(*PingRequest)) - } - return interceptor(ctx, in, info, handler) -} +func (*EmptyResponse) ProtoMessage() {} -func _MultiService_PingList_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(PingRequest) - if err := stream.RecvMsg(m); err != nil { - return err +func (x *EmptyResponse) ProtoReflect() protoreflect.Message { + mi := &file_test_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 srv.(MultiServiceServer).PingList(m, &multiServicePingListServer{stream}) -} - -type MultiService_PingListServer interface { - Send(*MultiPingResponse) error - grpc.ServerStream -} - -type multiServicePingListServer struct { - grpc.ServerStream -} - -func (x *multiServicePingListServer) Send(m *MultiPingResponse) error { - return x.ServerStream.SendMsg(m) + return mi.MessageOf(x) } -func _MultiService_PingStream_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(MultiServiceServer).PingStream(&multiServicePingStreamServer{stream}) -} - -type MultiService_PingStreamServer interface { - Send(*MultiPingResponse) error - Recv() (*PingRequest, error) - grpc.ServerStream -} - -type multiServicePingStreamServer struct { - grpc.ServerStream -} - -func (x *multiServicePingStreamServer) Send(m *MultiPingResponse) error { - return x.ServerStream.SendMsg(m) +// Deprecated: Use EmptyResponse.ProtoReflect.Descriptor instead. +func (*EmptyResponse) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{8} } -func (x *multiServicePingStreamServer) Recv() (*PingRequest, error) { - m := new(PingRequest) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err +func (x *EmptyResponse) GetMetadata() *ResponseMetadata { + if x != nil { + return x.Metadata } - return m, nil -} - -func _MultiService_PingStreamError_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(MultiServiceServer).PingStreamError(&multiServicePingStreamErrorServer{stream}) -} - -type MultiService_PingStreamErrorServer interface { - Send(*MultiPingResponse) error - Recv() (*PingRequest, error) - grpc.ServerStream -} - -type multiServicePingStreamErrorServer struct { - grpc.ServerStream -} - -func (x *multiServicePingStreamErrorServer) Send(m *MultiPingResponse) error { - return x.ServerStream.SendMsg(m) + return nil } -func (x *multiServicePingStreamErrorServer) Recv() (*PingRequest, error) { - m := new(PingRequest) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} +var File_test_proto protoreflect.FileDescriptor + +var file_test_proto_rawDesc = []byte{ + 0x0a, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x74, 0x61, + 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x07, 0x0a, + 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x23, 0x0a, 0x0b, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3e, 0x0a, 0x0c, 0x50, + 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x22, 0x55, 0x0a, 0x10, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, + 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x63, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x75, + 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x64, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x22, 0x5a, 0x0a, 0x19, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x50, 0x72, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, + 0x3d, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x63, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x21, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x9a, + 0x01, 0x0a, 0x11, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x63, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x50, 0x0a, 0x0e, 0x4d, + 0x75, 0x6c, 0x74, 0x69, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x3e, 0x0a, + 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x22, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x48, 0x0a, + 0x0a, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x3a, 0x0a, 0x08, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, + 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4e, 0x0a, 0x0d, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x63, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x74, 0x61, 0x6c, + 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x32, 0xfd, 0x02, 0x0a, 0x0b, 0x54, 0x65, 0x73, 0x74, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x44, 0x0a, 0x09, 0x50, 0x69, 0x6e, 0x67, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x12, 0x16, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, + 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1d, 0x2e, 0x74, + 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, + 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x45, 0x0a, + 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1c, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, + 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, 0x74, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x09, 0x50, 0x69, 0x6e, 0x67, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x12, 0x1c, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x16, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x08, 0x50, 0x69, 0x6e, + 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1c, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, + 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, 0x74, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x4f, 0x0a, 0x0a, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1c, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, + 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x32, 0xec, 0x03, 0x0a, 0x0c, 0x4d, 0x75, 0x6c, 0x74, + 0x69, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x46, 0x0a, 0x09, 0x50, 0x69, 0x6e, 0x67, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x16, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, + 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1f, 0x2e, + 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, + 0x12, 0x47, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1c, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, + 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x50, 0x69, + 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x09, 0x50, 0x69, 0x6e, + 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1c, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, + 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6c, + 0x79, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x08, 0x50, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, + 0x1c, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, + 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x54, 0x0a, 0x0a, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x12, 0x1c, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, 0x74, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x22, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x59, 0x0a, 0x0f, 0x50, + 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1c, + 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x74, + 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, + 0x75, 0x6c, 0x74, 0x69, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_test_proto_rawDescOnce sync.Once + file_test_proto_rawDescData = file_test_proto_rawDesc +) -var _MultiService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "talos.testproto.MultiService", - HandlerType: (*MultiServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "PingEmpty", - Handler: _MultiService_PingEmpty_Handler, - }, - { - MethodName: "Ping", - Handler: _MultiService_Ping_Handler, - }, - { - MethodName: "PingError", - Handler: _MultiService_PingError_Handler, - }, - }, - Streams: []grpc.StreamDesc{ - { - StreamName: "PingList", - Handler: _MultiService_PingList_Handler, - ServerStreams: true, - }, - { - StreamName: "PingStream", - Handler: _MultiService_PingStream_Handler, - ServerStreams: true, - ClientStreams: true, - }, - { - StreamName: "PingStreamError", - Handler: _MultiService_PingStreamError_Handler, - ServerStreams: true, - ClientStreams: true, +func file_test_proto_rawDescGZIP() []byte { + file_test_proto_rawDescOnce.Do(func() { + file_test_proto_rawDescData = protoimpl.X.CompressGZIP(file_test_proto_rawDescData) + }) + return file_test_proto_rawDescData +} + +var file_test_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_test_proto_goTypes = []interface{}{ + (*Empty)(nil), // 0: talos.testproto.Empty + (*PingRequest)(nil), // 1: talos.testproto.PingRequest + (*PingResponse)(nil), // 2: talos.testproto.PingResponse + (*ResponseMetadata)(nil), // 3: talos.testproto.ResponseMetadata + (*ResponseMetadataPrepender)(nil), // 4: talos.testproto.ResponseMetadataPrepender + (*MultiPingResponse)(nil), // 5: talos.testproto.MultiPingResponse + (*MultiPingReply)(nil), // 6: talos.testproto.MultiPingReply + (*EmptyReply)(nil), // 7: talos.testproto.EmptyReply + (*EmptyResponse)(nil), // 8: talos.testproto.EmptyResponse +} +var file_test_proto_depIdxs = []int32{ + 3, // 0: talos.testproto.ResponseMetadataPrepender.metadata:type_name -> talos.testproto.ResponseMetadata + 3, // 1: talos.testproto.MultiPingResponse.metadata:type_name -> talos.testproto.ResponseMetadata + 5, // 2: talos.testproto.MultiPingReply.response:type_name -> talos.testproto.MultiPingResponse + 8, // 3: talos.testproto.EmptyReply.response:type_name -> talos.testproto.EmptyResponse + 3, // 4: talos.testproto.EmptyResponse.metadata:type_name -> talos.testproto.ResponseMetadata + 0, // 5: talos.testproto.TestService.PingEmpty:input_type -> talos.testproto.Empty + 1, // 6: talos.testproto.TestService.Ping:input_type -> talos.testproto.PingRequest + 1, // 7: talos.testproto.TestService.PingError:input_type -> talos.testproto.PingRequest + 1, // 8: talos.testproto.TestService.PingList:input_type -> talos.testproto.PingRequest + 1, // 9: talos.testproto.TestService.PingStream:input_type -> talos.testproto.PingRequest + 0, // 10: talos.testproto.MultiService.PingEmpty:input_type -> talos.testproto.Empty + 1, // 11: talos.testproto.MultiService.Ping:input_type -> talos.testproto.PingRequest + 1, // 12: talos.testproto.MultiService.PingError:input_type -> talos.testproto.PingRequest + 1, // 13: talos.testproto.MultiService.PingList:input_type -> talos.testproto.PingRequest + 1, // 14: talos.testproto.MultiService.PingStream:input_type -> talos.testproto.PingRequest + 1, // 15: talos.testproto.MultiService.PingStreamError:input_type -> talos.testproto.PingRequest + 2, // 16: talos.testproto.TestService.PingEmpty:output_type -> talos.testproto.PingResponse + 2, // 17: talos.testproto.TestService.Ping:output_type -> talos.testproto.PingResponse + 0, // 18: talos.testproto.TestService.PingError:output_type -> talos.testproto.Empty + 2, // 19: talos.testproto.TestService.PingList:output_type -> talos.testproto.PingResponse + 2, // 20: talos.testproto.TestService.PingStream:output_type -> talos.testproto.PingResponse + 6, // 21: talos.testproto.MultiService.PingEmpty:output_type -> talos.testproto.MultiPingReply + 6, // 22: talos.testproto.MultiService.Ping:output_type -> talos.testproto.MultiPingReply + 7, // 23: talos.testproto.MultiService.PingError:output_type -> talos.testproto.EmptyReply + 5, // 24: talos.testproto.MultiService.PingList:output_type -> talos.testproto.MultiPingResponse + 5, // 25: talos.testproto.MultiService.PingStream:output_type -> talos.testproto.MultiPingResponse + 5, // 26: talos.testproto.MultiService.PingStreamError:output_type -> talos.testproto.MultiPingResponse + 16, // [16:27] is the sub-list for method output_type + 5, // [5:16] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name +} + +func init() { file_test_proto_init() } +func file_test_proto_init() { + if File_test_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_test_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Empty); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PingRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PingResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResponseMetadata); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResponseMetadataPrepender); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MultiPingResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MultiPingReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EmptyReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EmptyResponse); 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_test_proto_rawDesc, + NumEnums: 0, + NumMessages: 9, + NumExtensions: 0, + NumServices: 2, }, - }, - Metadata: "test.proto", + GoTypes: file_test_proto_goTypes, + DependencyIndexes: file_test_proto_depIdxs, + MessageInfos: file_test_proto_msgTypes, + }.Build() + File_test_proto = out.File + file_test_proto_rawDesc = nil + file_test_proto_goTypes = nil + file_test_proto_depIdxs = nil } diff --git a/testservice/test_grpc.pb.go b/testservice/test_grpc.pb.go new file mode 100644 index 0000000..0327a93 --- /dev/null +++ b/testservice/test_grpc.pb.go @@ -0,0 +1,663 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package talos_testproto + +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. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// TestServiceClient is the client API for TestService 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 TestServiceClient interface { + PingEmpty(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*PingResponse, error) + Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) + PingError(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*Empty, error) + PingList(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (TestService_PingListClient, error) + PingStream(ctx context.Context, opts ...grpc.CallOption) (TestService_PingStreamClient, error) +} + +type testServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewTestServiceClient(cc grpc.ClientConnInterface) TestServiceClient { + return &testServiceClient{cc} +} + +func (c *testServiceClient) PingEmpty(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*PingResponse, error) { + out := new(PingResponse) + err := c.cc.Invoke(ctx, "/talos.testproto.TestService/PingEmpty", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *testServiceClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) { + out := new(PingResponse) + err := c.cc.Invoke(ctx, "/talos.testproto.TestService/Ping", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *testServiceClient) PingError(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/talos.testproto.TestService/PingError", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *testServiceClient) PingList(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (TestService_PingListClient, error) { + stream, err := c.cc.NewStream(ctx, &TestService_ServiceDesc.Streams[0], "/talos.testproto.TestService/PingList", opts...) + if err != nil { + return nil, err + } + x := &testServicePingListClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type TestService_PingListClient interface { + Recv() (*PingResponse, error) + grpc.ClientStream +} + +type testServicePingListClient struct { + grpc.ClientStream +} + +func (x *testServicePingListClient) Recv() (*PingResponse, error) { + m := new(PingResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *testServiceClient) PingStream(ctx context.Context, opts ...grpc.CallOption) (TestService_PingStreamClient, error) { + stream, err := c.cc.NewStream(ctx, &TestService_ServiceDesc.Streams[1], "/talos.testproto.TestService/PingStream", opts...) + if err != nil { + return nil, err + } + x := &testServicePingStreamClient{stream} + return x, nil +} + +type TestService_PingStreamClient interface { + Send(*PingRequest) error + Recv() (*PingResponse, error) + grpc.ClientStream +} + +type testServicePingStreamClient struct { + grpc.ClientStream +} + +func (x *testServicePingStreamClient) Send(m *PingRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *testServicePingStreamClient) Recv() (*PingResponse, error) { + m := new(PingResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// TestServiceServer is the server API for TestService service. +// All implementations must embed UnimplementedTestServiceServer +// for forward compatibility +type TestServiceServer interface { + PingEmpty(context.Context, *Empty) (*PingResponse, error) + Ping(context.Context, *PingRequest) (*PingResponse, error) + PingError(context.Context, *PingRequest) (*Empty, error) + PingList(*PingRequest, TestService_PingListServer) error + PingStream(TestService_PingStreamServer) error + mustEmbedUnimplementedTestServiceServer() +} + +// UnimplementedTestServiceServer must be embedded to have forward compatible implementations. +type UnimplementedTestServiceServer struct { +} + +func (UnimplementedTestServiceServer) PingEmpty(context.Context, *Empty) (*PingResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PingEmpty not implemented") +} +func (UnimplementedTestServiceServer) Ping(context.Context, *PingRequest) (*PingResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented") +} +func (UnimplementedTestServiceServer) PingError(context.Context, *PingRequest) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method PingError not implemented") +} +func (UnimplementedTestServiceServer) PingList(*PingRequest, TestService_PingListServer) error { + return status.Errorf(codes.Unimplemented, "method PingList not implemented") +} +func (UnimplementedTestServiceServer) PingStream(TestService_PingStreamServer) error { + return status.Errorf(codes.Unimplemented, "method PingStream not implemented") +} +func (UnimplementedTestServiceServer) mustEmbedUnimplementedTestServiceServer() {} + +// UnsafeTestServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to TestServiceServer will +// result in compilation errors. +type UnsafeTestServiceServer interface { + mustEmbedUnimplementedTestServiceServer() +} + +func RegisterTestServiceServer(s grpc.ServiceRegistrar, srv TestServiceServer) { + s.RegisterService(&TestService_ServiceDesc, srv) +} + +func _TestService_PingEmpty_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TestServiceServer).PingEmpty(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/talos.testproto.TestService/PingEmpty", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TestServiceServer).PingEmpty(ctx, req.(*Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _TestService_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TestServiceServer).Ping(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/talos.testproto.TestService/Ping", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TestServiceServer).Ping(ctx, req.(*PingRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _TestService_PingError_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TestServiceServer).PingError(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/talos.testproto.TestService/PingError", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TestServiceServer).PingError(ctx, req.(*PingRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _TestService_PingList_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(PingRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(TestServiceServer).PingList(m, &testServicePingListServer{stream}) +} + +type TestService_PingListServer interface { + Send(*PingResponse) error + grpc.ServerStream +} + +type testServicePingListServer struct { + grpc.ServerStream +} + +func (x *testServicePingListServer) Send(m *PingResponse) error { + return x.ServerStream.SendMsg(m) +} + +func _TestService_PingStream_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(TestServiceServer).PingStream(&testServicePingStreamServer{stream}) +} + +type TestService_PingStreamServer interface { + Send(*PingResponse) error + Recv() (*PingRequest, error) + grpc.ServerStream +} + +type testServicePingStreamServer struct { + grpc.ServerStream +} + +func (x *testServicePingStreamServer) Send(m *PingResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *testServicePingStreamServer) Recv() (*PingRequest, error) { + m := new(PingRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// TestService_ServiceDesc is the grpc.ServiceDesc for TestService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var TestService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "talos.testproto.TestService", + HandlerType: (*TestServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "PingEmpty", + Handler: _TestService_PingEmpty_Handler, + }, + { + MethodName: "Ping", + Handler: _TestService_Ping_Handler, + }, + { + MethodName: "PingError", + Handler: _TestService_PingError_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "PingList", + Handler: _TestService_PingList_Handler, + ServerStreams: true, + }, + { + StreamName: "PingStream", + Handler: _TestService_PingStream_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "test.proto", +} + +// MultiServiceClient is the client API for MultiService 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 MultiServiceClient interface { + PingEmpty(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*MultiPingReply, error) + Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*MultiPingReply, error) + PingError(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*EmptyReply, error) + PingList(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (MultiService_PingListClient, error) + PingStream(ctx context.Context, opts ...grpc.CallOption) (MultiService_PingStreamClient, error) + PingStreamError(ctx context.Context, opts ...grpc.CallOption) (MultiService_PingStreamErrorClient, error) +} + +type multiServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewMultiServiceClient(cc grpc.ClientConnInterface) MultiServiceClient { + return &multiServiceClient{cc} +} + +func (c *multiServiceClient) PingEmpty(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*MultiPingReply, error) { + out := new(MultiPingReply) + err := c.cc.Invoke(ctx, "/talos.testproto.MultiService/PingEmpty", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *multiServiceClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*MultiPingReply, error) { + out := new(MultiPingReply) + err := c.cc.Invoke(ctx, "/talos.testproto.MultiService/Ping", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *multiServiceClient) PingError(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*EmptyReply, error) { + out := new(EmptyReply) + err := c.cc.Invoke(ctx, "/talos.testproto.MultiService/PingError", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *multiServiceClient) PingList(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (MultiService_PingListClient, error) { + stream, err := c.cc.NewStream(ctx, &MultiService_ServiceDesc.Streams[0], "/talos.testproto.MultiService/PingList", opts...) + if err != nil { + return nil, err + } + x := &multiServicePingListClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type MultiService_PingListClient interface { + Recv() (*MultiPingResponse, error) + grpc.ClientStream +} + +type multiServicePingListClient struct { + grpc.ClientStream +} + +func (x *multiServicePingListClient) Recv() (*MultiPingResponse, error) { + m := new(MultiPingResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *multiServiceClient) PingStream(ctx context.Context, opts ...grpc.CallOption) (MultiService_PingStreamClient, error) { + stream, err := c.cc.NewStream(ctx, &MultiService_ServiceDesc.Streams[1], "/talos.testproto.MultiService/PingStream", opts...) + if err != nil { + return nil, err + } + x := &multiServicePingStreamClient{stream} + return x, nil +} + +type MultiService_PingStreamClient interface { + Send(*PingRequest) error + Recv() (*MultiPingResponse, error) + grpc.ClientStream +} + +type multiServicePingStreamClient struct { + grpc.ClientStream +} + +func (x *multiServicePingStreamClient) Send(m *PingRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *multiServicePingStreamClient) Recv() (*MultiPingResponse, error) { + m := new(MultiPingResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *multiServiceClient) PingStreamError(ctx context.Context, opts ...grpc.CallOption) (MultiService_PingStreamErrorClient, error) { + stream, err := c.cc.NewStream(ctx, &MultiService_ServiceDesc.Streams[2], "/talos.testproto.MultiService/PingStreamError", opts...) + if err != nil { + return nil, err + } + x := &multiServicePingStreamErrorClient{stream} + return x, nil +} + +type MultiService_PingStreamErrorClient interface { + Send(*PingRequest) error + Recv() (*MultiPingResponse, error) + grpc.ClientStream +} + +type multiServicePingStreamErrorClient struct { + grpc.ClientStream +} + +func (x *multiServicePingStreamErrorClient) Send(m *PingRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *multiServicePingStreamErrorClient) Recv() (*MultiPingResponse, error) { + m := new(MultiPingResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// MultiServiceServer is the server API for MultiService service. +// All implementations must embed UnimplementedMultiServiceServer +// for forward compatibility +type MultiServiceServer interface { + PingEmpty(context.Context, *Empty) (*MultiPingReply, error) + Ping(context.Context, *PingRequest) (*MultiPingReply, error) + PingError(context.Context, *PingRequest) (*EmptyReply, error) + PingList(*PingRequest, MultiService_PingListServer) error + PingStream(MultiService_PingStreamServer) error + PingStreamError(MultiService_PingStreamErrorServer) error + mustEmbedUnimplementedMultiServiceServer() +} + +// UnimplementedMultiServiceServer must be embedded to have forward compatible implementations. +type UnimplementedMultiServiceServer struct { +} + +func (UnimplementedMultiServiceServer) PingEmpty(context.Context, *Empty) (*MultiPingReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method PingEmpty not implemented") +} +func (UnimplementedMultiServiceServer) Ping(context.Context, *PingRequest) (*MultiPingReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented") +} +func (UnimplementedMultiServiceServer) PingError(context.Context, *PingRequest) (*EmptyReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method PingError not implemented") +} +func (UnimplementedMultiServiceServer) PingList(*PingRequest, MultiService_PingListServer) error { + return status.Errorf(codes.Unimplemented, "method PingList not implemented") +} +func (UnimplementedMultiServiceServer) PingStream(MultiService_PingStreamServer) error { + return status.Errorf(codes.Unimplemented, "method PingStream not implemented") +} +func (UnimplementedMultiServiceServer) PingStreamError(MultiService_PingStreamErrorServer) error { + return status.Errorf(codes.Unimplemented, "method PingStreamError not implemented") +} +func (UnimplementedMultiServiceServer) mustEmbedUnimplementedMultiServiceServer() {} + +// UnsafeMultiServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to MultiServiceServer will +// result in compilation errors. +type UnsafeMultiServiceServer interface { + mustEmbedUnimplementedMultiServiceServer() +} + +func RegisterMultiServiceServer(s grpc.ServiceRegistrar, srv MultiServiceServer) { + s.RegisterService(&MultiService_ServiceDesc, srv) +} + +func _MultiService_PingEmpty_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MultiServiceServer).PingEmpty(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/talos.testproto.MultiService/PingEmpty", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MultiServiceServer).PingEmpty(ctx, req.(*Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _MultiService_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MultiServiceServer).Ping(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/talos.testproto.MultiService/Ping", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MultiServiceServer).Ping(ctx, req.(*PingRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MultiService_PingError_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MultiServiceServer).PingError(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/talos.testproto.MultiService/PingError", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MultiServiceServer).PingError(ctx, req.(*PingRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MultiService_PingList_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(PingRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(MultiServiceServer).PingList(m, &multiServicePingListServer{stream}) +} + +type MultiService_PingListServer interface { + Send(*MultiPingResponse) error + grpc.ServerStream +} + +type multiServicePingListServer struct { + grpc.ServerStream +} + +func (x *multiServicePingListServer) Send(m *MultiPingResponse) error { + return x.ServerStream.SendMsg(m) +} + +func _MultiService_PingStream_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(MultiServiceServer).PingStream(&multiServicePingStreamServer{stream}) +} + +type MultiService_PingStreamServer interface { + Send(*MultiPingResponse) error + Recv() (*PingRequest, error) + grpc.ServerStream +} + +type multiServicePingStreamServer struct { + grpc.ServerStream +} + +func (x *multiServicePingStreamServer) Send(m *MultiPingResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *multiServicePingStreamServer) Recv() (*PingRequest, error) { + m := new(PingRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func _MultiService_PingStreamError_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(MultiServiceServer).PingStreamError(&multiServicePingStreamErrorServer{stream}) +} + +type MultiService_PingStreamErrorServer interface { + Send(*MultiPingResponse) error + Recv() (*PingRequest, error) + grpc.ServerStream +} + +type multiServicePingStreamErrorServer struct { + grpc.ServerStream +} + +func (x *multiServicePingStreamErrorServer) Send(m *MultiPingResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *multiServicePingStreamErrorServer) Recv() (*PingRequest, error) { + m := new(PingRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// MultiService_ServiceDesc is the grpc.ServiceDesc for MultiService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var MultiService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "talos.testproto.MultiService", + HandlerType: (*MultiServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "PingEmpty", + Handler: _MultiService_PingEmpty_Handler, + }, + { + MethodName: "Ping", + Handler: _MultiService_Ping_Handler, + }, + { + MethodName: "PingError", + Handler: _MultiService_PingError_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "PingList", + Handler: _MultiService_PingList_Handler, + ServerStreams: true, + }, + { + StreamName: "PingStream", + Handler: _MultiService_PingStream_Handler, + ServerStreams: true, + ClientStreams: true, + }, + { + StreamName: "PingStreamError", + Handler: _MultiService_PingStreamError_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "test.proto", +}