Compare commits

...

150 Commits
v3.8.0 ... v3

Author SHA1 Message Date
28234bcc3c add server type in metrics and tracing
Some checks failed
build / test (push) Failing after 4m56s
build / lint (push) Successful in 9m32s
codeql / analyze (go) (push) Failing after 3s
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2024-11-10 20:16:08 +03:00
7723dcaddf fixup endpoint name in tracing and metrics
Some checks failed
codeql / analyze (go) (push) Failing after 43s
build / test (push) Failing after 4m54s
build / lint (push) Successful in 9m28s
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2024-11-10 18:36:00 +03:00
f6ec5ae624 update for latest micro logger changes
Some checks failed
build / test (push) Failing after 4m56s
build / lint (push) Successful in 9m32s
codeql / analyze (go) (push) Failing after 1m27s
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2024-10-12 13:18:36 +03:00
295f26dd2c #348 add check method in should be skipped (#175)
Some checks failed
build / test (push) Failing after 7s
build / lint (push) Failing after 7s
codeql / analyze (go) (push) Failing after 13m47s
Co-authored-by: Gorbunov Kirill Andreevich <kgorbunov@mtsbank.ru>
Reviewed-on: #175
Reviewed-by: Василий Толстов <v.tolstov@unistack.org>
Co-authored-by: Кирилл Горбунов <kirya_gorbunov_2015@mail.ru>
Co-committed-by: Кирилл Горбунов <kirya_gorbunov_2015@mail.ru>
2024-09-20 17:43:08 +03:00
7b5ce8c49a update to latest micro
Some checks failed
build / test (push) Failing after 9s
build / lint (push) Failing after 9s
codeql / analyze (go) (push) Failing after 10s
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2024-09-17 12:52:41 +03:00
3fc05ae291 fix metadata extract and trace span creating
Some checks failed
build / lint (push) Successful in 27s
build / test (push) Failing after 33s
codeql / analyze (go) (push) Failing after 10m56s
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2024-07-18 11:09:05 +03:00
0b29668fe5 wrap stream for tracing
Some checks failed
build / test (push) Failing after 1m48s
build / lint (push) Successful in 9m12s
codeql / analyze (go) (push) Failing after 7m32s
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2024-05-06 00:28:56 +03:00
eecc3854b2 add metrics and tracing
Some checks failed
build / test (push) Failing after 1m53s
build / lint (push) Successful in 9m16s
codeql / analyze (go) (push) Failing after 3m13s
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2024-04-23 08:01:44 +03:00
e6e64ff070 improve meter
Some checks failed
build / test (push) Failing after 1m48s
build / lint (push) Successful in 9m15s
codeql / analyze (go) (push) Failing after 5m10s
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2024-04-06 22:48:21 +03:00
5ec59f0989 add missing file
Some checks failed
build / test (push) Failing after 1m42s
codeql / analyze (go) (push) Failing after 1m44s
build / lint (push) Successful in 9m21s
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2024-04-06 22:36:21 +03:00
d4a2dd918f meter support
Some checks failed
build / test (push) Failing after 1m37s
codeql / analyze (go) (push) Failing after 1m48s
build / lint (push) Has been cancelled
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2024-04-06 22:32:12 +03:00
8c42fbb18b update for latest micro
Some checks failed
build / test (push) Failing after 1m20s
build / lint (push) Successful in 9m16s
codeql / analyze (go) (push) Failing after 2m15s
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2024-03-17 00:32:52 +03:00
f860254f7b Merge pull request 'use time option' (#174) from devstigneev/micro-server-grpc:issue_171 into v3
Some checks failed
build / test (push) Failing after 1m30s
build / lint (push) Successful in 9m19s
codeql / analyze (go) (push) Failing after 2m0s
Reviewed-on: #174
2024-03-07 23:22:25 +03:00
0c060a5868 use time option
Some checks failed
automerge / automerge (pull_request) Has been skipped
dependabot-automerge / automerge (pull_request) Has been skipped
autoapprove / autoapprove (pull_request) Successful in 10s
codeql / analyze (go) (pull_request) Has been cancelled
prbuild / test (pull_request) Has been cancelled
prbuild / lint (pull_request) Has been cancelled
2024-03-07 21:52:54 +03:00
c24f1f26f8 Merge pull request '#131 delete recover' (#172) from kgorbunov/micro-server-grpc:#131 into v3
Some checks failed
build / test (push) Failing after 1m47s
codeql / analyze (go) (push) Failing after 6m1s
build / lint (push) Failing after 18m28s
Reviewed-on: #172
2024-02-27 20:28:59 +03:00
Gorbunov Kirill Andreevich
566036802b #131 delete recover
Some checks failed
autoapprove / autoapprove (pull_request) Successful in 8s
automerge / automerge (pull_request) Has been skipped
dependabot-automerge / automerge (pull_request) Has been skipped
codeql / analyze (go) (pull_request) Has been cancelled
prbuild / test (pull_request) Has been cancelled
prbuild / lint (pull_request) Has been cancelled
2024-02-27 17:08:08 +03:00
f33595f72a dont log error in server
Some checks failed
build / test (push) Has been cancelled
build / lint (push) Has been cancelled
codeql / analyze (go) (push) Has been cancelled
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2024-02-19 02:11:29 +03:00
f94c265c7a optimize unknown handler
Some checks failed
build / test (push) Has been cancelled
build / lint (push) Has been cancelled
codeql / analyze (go) (push) Has been cancelled
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2024-02-11 22:17:55 +03:00
3036359547 reflection update
Some checks failed
build / test (push) Has been cancelled
build / lint (push) Has been cancelled
codeql / analyze (go) (push) Has been cancelled
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2024-01-22 09:14:50 +03:00
9e0a58405f Merge pull request 'copy incoming content-type' (#169) from ct into v3
Some checks failed
build / test (push) Failing after 1m27s
build / lint (push) Failing after 2m31s
codeql / analyze (go) (push) Failing after 2m38s
Reviewed-on: #169
2023-12-20 09:24:16 +03:00
ee3f978683 copy incoming content-type
Some checks failed
codeql / analyze (go) (pull_request) Failing after 2m46s
prbuild / test (pull_request) Failing after 1m28s
prbuild / lint (pull_request) Failing after 2m44s
autoapprove / autoapprove (pull_request) Failing after 1m24s
automerge / automerge (pull_request) Failing after 4s
dependabot-automerge / automerge (pull_request) Has been skipped
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-12-20 09:23:42 +03:00
46891c397f add more metadata
Some checks failed
build / test (push) Failing after 1m27s
build / lint (push) Failing after 2m38s
codeql / analyze (go) (push) Failing after 2m46s
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-11-04 00:05:33 +03:00
6856038abe add Path metadata
Some checks failed
build / test (push) Failing after 1m28s
build / lint (push) Failing after 2m38s
codeql / analyze (go) (push) Failing after 2m44s
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-11-03 19:33:49 +03:00
786bbb7185 Merge pull request 'dont init twice tls listener' (#167) from tls into v3
Reviewed-on: #167
2023-06-12 18:30:41 +03:00
95207c9617 dont init twice tls listener
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-06-12 18:29:07 +03:00
d646deb468 Merge pull request 'check subscribe errors' (#164) from subscribeerr into v3
Reviewed-on: #164
2023-05-13 16:06:53 +03:00
468819f0a0 check subscribe errors
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-05-13 16:06:37 +03:00
832f1034a8 Merge pull request 'combo prepare' (#162) from init-fix into v3
Reviewed-on: #162
2023-03-04 16:28:24 +03:00
f0b6370ee1 move codec registration to init phase
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-03-04 16:25:50 +03:00
3d522b094b
Merge pull request #162 from unistack-org/grpc-server
allow to expose *grpc.Server
2023-03-03 13:11:25 +03:00
92dcd1acd7 allow to expose *grpc.Server
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-03-03 13:08:06 +03:00
dc8a736e13
Merge pull request #161 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.10.14
Bump go.unistack.org/micro/v3 from 3.10.13 to 3.10.14
2023-02-27 11:11:04 +03:00
dependabot[bot]
4219919c9e
Bump go.unistack.org/micro/v3 from 3.10.13 to 3.10.14
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.10.13 to 3.10.14.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.10.13...v3.10.14)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-27 08:08:26 +00:00
1f447ea747
Merge pull request #160 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.10.13
Bump go.unistack.org/micro/v3 from 3.10.11 to 3.10.13
2023-02-22 10:20:56 +03:00
dependabot[bot]
30c0e01397
Bump go.unistack.org/micro/v3 from 3.10.11 to 3.10.13
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.10.11 to 3.10.13.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.10.11...v3.10.13)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-22 07:17:49 +00:00
244f3def4d
Merge pull request #158 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.10.11
Bump go.unistack.org/micro/v3 from 3.10.9 to 3.10.11
2023-02-14 11:02:57 +03:00
dependabot[bot]
55cbc89e11
Bump go.unistack.org/micro/v3 from 3.10.9 to 3.10.11
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.10.9 to 3.10.11.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.10.9...v3.10.11)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-14 08:00:11 +00:00
df00f718cf
Merge pull request #157 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.10.9
Bump go.unistack.org/micro/v3 from 3.10.8 to 3.10.9
2023-02-09 10:06:46 +03:00
dependabot[bot]
bc3369f3a6
Bump go.unistack.org/micro/v3 from 3.10.8 to 3.10.9
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.10.8 to 3.10.9.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.10.8...v3.10.9)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-09 07:04:05 +00:00
8d4c661ce5
Merge pull request #154 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.10.8
Bump go.unistack.org/micro/v3 from 3.10.5 to 3.10.8
2023-02-07 10:05:29 +03:00
dependabot[bot]
7b97212e26
Bump go.unistack.org/micro/v3 from 3.10.5 to 3.10.8
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.10.5 to 3.10.8.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.10.5...v3.10.8)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-07 07:02:56 +00:00
dependabot[bot]
9d5a2c1168
Bump golang.org/x/net from 0.4.0 to 0.5.0 (#148)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.4.0 to 0.5.0.
- [Release notes](https://github.com/golang/net/releases)
- [Commits](https://github.com/golang/net/compare/v0.4.0...v0.5.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-31 06:57:46 +03:00
dependabot[bot]
483c6bb801
Bump google.golang.org/grpc from 1.52.0 to 1.52.3 (#152)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.52.0 to 1.52.3.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.52.0...v1.52.3)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-31 06:44:21 +03:00
dependabot[bot]
7ba5fd5fee
Bump golangci/golangci-lint-action from 3.3.1 to 3.4.0 (#149)
Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 3.3.1 to 3.4.0.
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](https://github.com/golangci/golangci-lint-action/compare/v3.3.1...v3.4.0)

---
updated-dependencies:
- dependency-name: golangci/golangci-lint-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-30 21:13:46 +03:00
080705a5df
Merge pull request #153 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.10.5
Bump go.unistack.org/micro/v3 from 3.10.4 to 3.10.5
2023-01-30 10:09:18 +03:00
dependabot[bot]
79df512e5e
Bump go.unistack.org/micro/v3 from 3.10.4 to 3.10.5
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.10.4 to 3.10.5.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.10.4...v3.10.5)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-30 07:06:38 +00:00
dependabot[bot]
3e893b78c8
Bump dependabot/fetch-metadata from 1.3.5 to 1.3.6 (#150)
Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.3.5 to 1.3.6.
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.3.5...v1.3.6)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-24 10:07:05 +03:00
8e9c64d78b
Merge pull request #147 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.10.4
Bump go.unistack.org/micro/v3 from 3.10.1 to 3.10.4
2023-01-18 10:06:07 +03:00
dependabot[bot]
d66aa424d2
Bump go.unistack.org/micro/v3 from 3.10.1 to 3.10.4
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.10.1 to 3.10.4.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.10.1...v3.10.4)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-18 07:03:33 +00:00
dependabot[bot]
f8d3695962
Bump google.golang.org/grpc from 1.51.0 to 1.52.0 (#144)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.51.0 to 1.52.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.51.0...v1.52.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-17 23:45:55 +03:00
ae158ce5fc
Merge pull request #146 from unistack-org/endpoint
fix endpoint
2023-01-17 23:45:33 +03:00
8125c9003c
Merge branch 'v3' into endpoint 2023-01-17 23:43:06 +03:00
a6f6df257b fix endpoint
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-01-17 23:41:48 +03:00
6b19cb2fb7
Merge pull request #145 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.10.1
Bump go.unistack.org/micro/v3 from 3.10.0 to 3.10.1
2023-01-17 10:05:22 +03:00
dependabot[bot]
db6fee9760
Bump go.unistack.org/micro/v3 from 3.10.0 to 3.10.1
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.10.0 to 3.10.1.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.10.0...v3.10.1)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-17 07:03:21 +00:00
309f100532
Merge pull request #143 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.10.0
Bump go.unistack.org/micro/v3 from 3.9.18 to 3.10.0
2023-01-09 10:07:40 +03:00
dependabot[bot]
22ae55f739
Bump go.unistack.org/micro/v3 from 3.9.18 to 3.10.0
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.9.18 to 3.10.0.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.9.18...v3.10.0)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-09 07:05:04 +00:00
70700a3f86
Merge pull request #142 from unistack-org/content-type
use default google grpc content-type
2023-01-07 23:30:18 +03:00
7dd327086c use default google grpc content-type
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-01-07 23:27:53 +03:00
a67efa39ae
Merge pull request #141 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.9.18
Bump go.unistack.org/micro/v3 from 3.9.17 to 3.9.18
2022-12-28 10:05:23 +03:00
dependabot[bot]
8ee91422cc
Bump go.unistack.org/micro/v3 from 3.9.17 to 3.9.18
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.9.17 to 3.9.18.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.9.17...v3.9.18)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-28 07:03:16 +00:00
f8ae500c5f
Merge pull request #140 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.9.17
Bump go.unistack.org/micro/v3 from 3.9.15 to 3.9.17
2022-12-26 10:12:06 +03:00
dependabot[bot]
7fcc042fbf
Bump go.unistack.org/micro/v3 from 3.9.15 to 3.9.17
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.9.15 to 3.9.17.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.9.15...v3.9.17)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-26 07:10:05 +00:00
3a22f3a900
Merge pull request #139 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.9.15
Bump go.unistack.org/micro/v3 from 3.9.14 to 3.9.15
2022-11-29 10:05:49 +03:00
dependabot[bot]
452a124aee
Bump go.unistack.org/micro/v3 from 3.9.14 to 3.9.15
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.9.14 to 3.9.15.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.9.14...v3.9.15)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-29 07:03:27 +00:00
dependabot[bot]
26d3adfe95
Bump google.golang.org/grpc from 1.50.1 to 1.51.0 (#137)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.50.1 to 1.51.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.50.1...v1.51.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-28 22:17:21 +03:00
dependabot[bot]
18d6584c8f
Bump hmarr/auto-approve-action from 2 to 3 (#136)
Bumps [hmarr/auto-approve-action](https://github.com/hmarr/auto-approve-action) from 2 to 3.
- [Release notes](https://github.com/hmarr/auto-approve-action/releases)
- [Commits](https://github.com/hmarr/auto-approve-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: hmarr/auto-approve-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-28 16:25:14 +03:00
f26dde5d63
Merge pull request #138 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.9.14
Bump go.unistack.org/micro/v3 from 3.9.13 to 3.9.14
2022-11-28 10:07:46 +03:00
dependabot[bot]
66d3feb263
Bump go.unistack.org/micro/v3 from 3.9.13 to 3.9.14
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.9.13 to 3.9.14.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.9.13...v3.9.14)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-28 07:05:07 +00:00
5c8effa23f
Merge pull request #135 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.9.13
Bump go.unistack.org/micro/v3 from 3.9.11 to 3.9.13
2022-11-15 10:04:29 +03:00
dependabot[bot]
c1e318d0b3
Bump go.unistack.org/micro/v3 from 3.9.11 to 3.9.13
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.9.11 to 3.9.13.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.9.11...v3.9.13)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-15 07:02:41 +00:00
617764706c
Merge pull request #134 from unistack-org/metadata
allow to send server metadata via header
2022-11-14 14:54:48 +03:00
0f3e56f697 allow to send server metadata via header
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-11-14 14:52:12 +03:00
dependabot[bot]
b87462c465
Bump golangci/golangci-lint-action from 3.3.0 to 3.3.1 (#133)
Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 3.3.0 to 3.3.1.
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](https://github.com/golangci/golangci-lint-action/compare/v3.3.0...v3.3.1)

---
updated-dependencies:
- dependency-name: golangci/golangci-lint-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-14 13:43:38 +03:00
dependabot[bot]
e877a92718
Bump dependabot/fetch-metadata from 1.3.4 to 1.3.5 (#132)
Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.3.4 to 1.3.5.
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.3.4...v1.3.5)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-14 06:51:08 +03:00
dependabot[bot]
c60f0ccb26
Bump golangci/golangci-lint-action from 3.2.0 to 3.3.0 (#129)
Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 3.2.0 to 3.3.0.
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](https://github.com/golangci/golangci-lint-action/compare/v3.2.0...v3.3.0)

---
updated-dependencies:
- dependency-name: golangci/golangci-lint-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-02 20:16:36 +00:00
7cf4a8d293
Merge pull request #130 from unistack-org/panic_info
in case of panic, return full service handler name
2022-11-02 23:12:27 +03:00
84b1b862a7 in case of panic, return full service handler name
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-11-02 23:09:59 +03:00
dependabot[bot]
eb17921feb
Bump google.golang.org/grpc from 1.50.0 to 1.50.1 (#128)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.50.0 to 1.50.1.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.50.0...v1.50.1)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-19 22:51:09 +03:00
dependabot[bot]
ddeb0a23c3
Bump google.golang.org/grpc from 1.49.0 to 1.50.0 (#127)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.49.0 to 1.50.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.49.0...v1.50.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 11:51:09 +03:00
dependabot[bot]
830d8d8fda
Bump dependabot/fetch-metadata from 1.3.3 to 1.3.4 (#126)
Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.3.3 to 1.3.4.
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.3.3...v1.3.4)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-04 13:05:48 +03:00
dependabot[bot]
ceaff6bf88
Bump google.golang.org/protobuf from 1.28.0 to 1.28.1 (#124)
Bumps [google.golang.org/protobuf](https://github.com/protocolbuffers/protobuf-go) from 1.28.0 to 1.28.1.
- [Release notes](https://github.com/protocolbuffers/protobuf-go/releases)
- [Changelog](https://github.com/protocolbuffers/protobuf-go/blob/master/release.bash)
- [Commits](https://github.com/protocolbuffers/protobuf-go/compare/v1.28.0...v1.28.1)

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-28 14:38:59 +00:00
dependabot[bot]
01848b8ec7
Bump dependabot/fetch-metadata from 1.3.1 to 1.3.3 (#121)
Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.3.1 to 1.3.3.
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.3.1...v1.3.3)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-28 14:32:57 +00:00
dependabot[bot]
8ddfa39811
Bump google.golang.org/grpc from 1.47.0 to 1.49.0 (#125)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.47.0 to 1.49.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.47.0...v1.49.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-28 17:23:07 +03:00
110a8a8a9c
Merge pull request #122 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.9.11
Bump go.unistack.org/micro/v3 from 3.9.10 to 3.9.11
2022-07-12 10:29:59 +03:00
dependabot[bot]
f2587f0876
Bump go.unistack.org/micro/v3 from 3.9.10 to 3.9.11
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.9.10 to 3.9.11.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.9.10...v3.9.11)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-12 07:27:49 +00:00
eccdad9752
Merge pull request #119 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.9.10
Bump go.unistack.org/micro/v3 from 3.9.8 to 3.9.10
2022-06-27 10:28:13 +03:00
dependabot[bot]
c05996ee6e
Bump go.unistack.org/micro/v3 from 3.9.8 to 3.9.10
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.9.8 to 3.9.10.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.9.8...v3.9.10)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-27 07:25:51 +00:00
734d6fa7af
Merge pull request #118 from unistack-org/cleanup
update to latest micro
2022-06-27 00:42:27 +03:00
4c0ca3664a update to latest micro
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-06-27 00:39:51 +03:00
dependabot[bot]
d34ce4f314
Bump google.golang.org/grpc from 1.46.0 to 1.47.0 (#117)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.46.0 to 1.47.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.46.0...v1.47.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-25 23:32:07 +03:00
dependabot[bot]
d9932033ee
Bump golangci/golangci-lint-action from 3.1.0 to 3.2.0 (#115)
Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 3.1.0 to 3.2.0.
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](https://github.com/golangci/golangci-lint-action/compare/v3.1.0...v3.2.0)

---
updated-dependencies:
- dependency-name: golangci/golangci-lint-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-11 11:28:34 +03:00
847887de84
Merge pull request #114 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.9.8
Bump go.unistack.org/micro/v3 from 3.9.7 to 3.9.8
2022-05-03 10:20:24 +03:00
dependabot[bot]
10ea1928f4
Bump go.unistack.org/micro/v3 from 3.9.7 to 3.9.8
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.9.7 to 3.9.8.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.9.7...v3.9.8)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-03 07:17:50 +00:00
dependabot[bot]
52d37c6579
Bump github/codeql-action from 1 to 2 (#113)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 1 to 2.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v1...v2)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-02 14:30:10 +03:00
dependabot[bot]
0af18ab84b
Bump google.golang.org/grpc from 1.45.0 to 1.46.0 (#112)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.45.0 to 1.46.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.45.0...v1.46.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-25 16:36:11 +03:00
dependabot[bot]
c46d11a2d4
Bump dependabot/fetch-metadata from 1.3.0 to 1.3.1 (#111)
Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.3.0 to 1.3.1.
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.3.0...v1.3.1)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-21 12:47:31 +03:00
dependabot[bot]
117f48aac5
Bump actions/setup-go from 2 to 3 (#109)
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 2 to 3.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-04-11 23:03:50 +03:00
b4a2fbdeeb
Merge pull request #110 from unistack-org/init_fix
fix init
2022-04-11 16:19:36 +03:00
e36db68d4d fix init
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-04-11 16:17:02 +03:00
b6b101b140
Merge pull request #107 from unistack-org/status
allow to transfer *status.Status as error from handler
2022-04-06 18:44:20 +03:00
cbafc74e41 fux
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-04-06 18:41:43 +03:00
1e19359ab1 allow to transfer *status.Status as error from handler
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-04-06 18:38:38 +03:00
8e88abbbca allow to transfer *status.Status as error from handler
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-04-06 18:37:00 +03:00
adf9a0d82d
Merge pull request #106 from unistack-org/cleanup
cleanup
2022-04-03 14:48:09 +03:00
a1a5980534 cleanup
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-04-03 14:45:40 +03:00
25a74b6935
Merge pull request #105 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.9.7
Bump go.unistack.org/micro/v3 from 3.9.5 to 3.9.7
2022-03-31 10:24:59 +03:00
dependabot[bot]
5ed755f5bb
Bump go.unistack.org/micro/v3 from 3.9.5 to 3.9.7
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.9.5 to 3.9.7.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.9.5...v3.9.7)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-31 07:22:43 +00:00
8dd303472d
Merge pull request #104 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.9.5
Bump go.unistack.org/micro/v3 from 3.9.1 to 3.9.5
2022-03-28 10:30:05 +03:00
dependabot[bot]
1f6b2b34ec
Bump go.unistack.org/micro/v3 from 3.9.1 to 3.9.5
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.9.1 to 3.9.5.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.9.1...v3.9.5)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-28 07:27:34 +00:00
ce3da2c9fa
Merge pull request #103 from unistack-org/wildcard
add unknown service handler
2022-03-24 14:40:38 +03:00
b248593e35 add unknown service handler
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-03-24 14:38:23 +03:00
dependabot[bot]
dda5d46e47
Bump google.golang.org/protobuf from 1.27.1 to 1.28.0 (#101)
Bumps [google.golang.org/protobuf](https://github.com/protocolbuffers/protobuf-go) from 1.27.1 to 1.28.0.
- [Release notes](https://github.com/protocolbuffers/protobuf-go/releases)
- [Changelog](https://github.com/protocolbuffers/protobuf-go/blob/master/release.bash)
- [Commits](https://github.com/protocolbuffers/protobuf-go/compare/v1.27.1...v1.28.0)

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-23 12:09:21 +03:00
0f50e30f9c
Merge pull request #102 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.9.1
Bump go.unistack.org/micro/v3 from 3.9.0 to 3.9.1
2022-03-23 10:30:33 +03:00
dependabot[bot]
f983ccc6d9
Bump go.unistack.org/micro/v3 from 3.9.0 to 3.9.1
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.9.0 to 3.9.1.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.9.0...v3.9.1)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-23 07:28:34 +00:00
dependabot[bot]
ef9ee6d837
Bump actions/cache from 2 to 3 (#100)
Bumps [actions/cache](https://github.com/actions/cache) from 2 to 3.
- [Release notes](https://github.com/actions/cache/releases)
- [Commits](https://github.com/actions/cache/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-22 23:04:53 +03:00
0103c05275
Merge pull request #99 from unistack-org/cleanup
server: remove unparsed body from request and message
2022-03-21 15:34:00 +03:00
d1c11644e8
Merge branch 'v3' into cleanup 2022-03-21 15:31:43 +03:00
dc01d20561 server: remove unparsed body from request and message
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-03-21 15:28:39 +03:00
cdee03a96e
Merge pull request #98 from unistack-org/grpc-fixes
support Grpc-Timeout header, export default content type
2022-03-21 13:06:19 +03:00
48bce4ed2f support Grpc-Timeout header, export default content type
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-03-21 13:03:48 +03:00
dependabot[bot]
f00e34380b
Bump google.golang.org/grpc from 1.44.0 to 1.45.0 (#97)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.44.0 to 1.45.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.44.0...v1.45.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-16 19:49:58 +03:00
86ebd173f7 update go version
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-03-07 13:46:36 +03:00
9923c98469 update workflows
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-03-05 19:09:59 +03:00
dependabot[bot]
51b93c413c
Bump dependabot/fetch-metadata from 1.1.1 to 1.2.1 (#93)
Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.1.1 to 1.2.1.
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.1.1...v1.2.1)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-01 00:37:21 +03:00
dependabot[bot]
9617533481
Bump golangci/golangci-lint-action from 2 to 3 (#94)
Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 2 to 3.
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](https://github.com/golangci/golangci-lint-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: golangci/golangci-lint-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-02-25 13:29:24 +03:00
dependabot[bot]
71f7ea49e4
Bump go.unistack.org/micro/v3 from 3.8.20 to 3.8.21 (#91)
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.8.20 to 3.8.21.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.8.20...v3.8.21)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-25 13:24:52 +03:00
dependabot[bot]
8e89b4b32f
Bump google.golang.org/grpc from 1.43.0 to 1.44.0 (#90)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.43.0 to 1.44.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.43.0...v1.44.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-25 09:49:56 +03:00
9a2965b4d4
Merge pull request #89 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.8.20
Bump go.unistack.org/micro/v3 from 3.8.19 to 3.8.20
2022-01-26 10:21:14 +03:00
dependabot[bot]
d90ff34a67
Bump go.unistack.org/micro/v3 from 3.8.19 to 3.8.20
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.8.19 to 3.8.20.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.8.19...v3.8.20)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-26 07:19:11 +00:00
d2ef32f628
Merge pull request #88 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.8.19
Bump go.unistack.org/micro/v3 from 3.8.18 to 3.8.19
2022-01-25 10:24:14 +03:00
dependabot[bot]
d14209e31e
Bump go.unistack.org/micro/v3 from 3.8.18 to 3.8.19
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.8.18 to 3.8.19.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.8.18...v3.8.19)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-25 07:20:44 +00:00
d82f7c49c7
Merge pull request #87 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.8.18
Bump go.unistack.org/micro/v3 from 3.8.16 to 3.8.18
2022-01-24 10:21:34 +03:00
dependabot[bot]
98c02c72b0
Bump go.unistack.org/micro/v3 from 3.8.16 to 3.8.18
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.8.16 to 3.8.18.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.8.16...v3.8.18)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-24 07:18:13 +00:00
35ad59444a
Merge pull request #86 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.8.16
Bump go.unistack.org/micro/v3 from 3.8.15 to 3.8.16
2022-01-21 10:21:02 +03:00
dependabot[bot]
9e63562468
Bump go.unistack.org/micro/v3 from 3.8.15 to 3.8.16
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.8.15 to 3.8.16.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.8.15...v3.8.16)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-21 07:19:14 +00:00
978f500ce2
Merge pull request #85 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.8.15
Bump go.unistack.org/micro/v3 from 3.8.14 to 3.8.15
2022-01-20 10:18:30 +03:00
dependabot[bot]
8c8073ca01
Bump go.unistack.org/micro/v3 from 3.8.14 to 3.8.15
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.8.14 to 3.8.15.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.8.14...v3.8.15)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-20 07:16:33 +00:00
dependabot[bot]
8d283ce2b2
Bump google.golang.org/grpc from 1.42.0 to 1.43.0 (#81)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.42.0 to 1.43.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.42.0...v1.43.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-12 15:31:51 +03:00
d98376446a
Merge pull request #84 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.8.14
Bump go.unistack.org/micro/v3 from 3.8.11 to 3.8.14
2022-01-11 10:20:48 +03:00
dependabot[bot]
e95d956ff7
Bump go.unistack.org/micro/v3 from 3.8.11 to 3.8.14
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.8.11 to 3.8.14.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.8.11...v3.8.14)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-11 07:16:38 +00:00
dependabot[bot]
ad2dc43aed
Bump google.golang.org/grpc from 1.41.0 to 1.42.0 (#78)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.41.0 to 1.42.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.41.0...v1.42.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-24 14:51:05 +03:00
54562aa346
Merge pull request #80 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.8.11
Bump go.unistack.org/micro/v3 from 3.8.10 to 3.8.11
2021-11-24 10:20:56 +03:00
dependabot[bot]
6f202b3a97
Bump go.unistack.org/micro/v3 from 3.8.10 to 3.8.11
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.8.10 to 3.8.11.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.8.10...v3.8.11)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-24 07:18:28 +00:00
aa73377fb5
Merge pull request #79 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.8.10
Bump go.unistack.org/micro/v3 from 3.8.7 to 3.8.10
2021-11-19 10:20:38 +03:00
dependabot[bot]
6b1e5195ba
Bump go.unistack.org/micro/v3 from 3.8.7 to 3.8.10
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.8.7 to 3.8.10.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.8.7...v3.8.10)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-19 07:18:34 +00:00
cbbcb2c10a
Merge pull request #77 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v3-3.8.7
Bump go.unistack.org/micro/v3 from 3.8.5 to 3.8.7
2021-10-28 11:24:58 +03:00
dependabot[bot]
7d7fc39779
Bump go.unistack.org/micro/v3 from 3.8.5 to 3.8.7
Bumps [go.unistack.org/micro/v3](https://github.com/unistack-org/micro) from 3.8.5 to 3.8.7.
- [Release notes](https://github.com/unistack-org/micro/releases)
- [Commits](https://github.com/unistack-org/micro/compare/v3.8.5...v3.8.7)

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-28 07:17:30 +00:00
dependabot[bot]
483eda5adc
Bump google.golang.org/grpc from 1.40.0 to 1.41.0 (#73)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.40.0 to 1.41.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.40.0...v1.41.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-10-27 18:09:42 +03:00
25d47a5b01 update workflows
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-10-27 18:05:10 +03:00
23 changed files with 1391 additions and 1079 deletions

20
.github/workflows/autoapprove.yml vendored Normal file
View File

@ -0,0 +1,20 @@
name: "autoapprove"
on:
pull_request_target:
types: [assigned, opened, synchronize, reopened]
permissions:
pull-requests: write
contents: write
jobs:
autoapprove:
runs-on: ubuntu-latest
steps:
- name: approve
uses: hmarr/auto-approve-action@v3
if: github.actor == 'vtolstov' || github.actor == 'dependabot[bot]'
id: approve
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

21
.github/workflows/automerge.yml vendored Normal file
View File

@ -0,0 +1,21 @@
name: "automerge"
on:
pull_request_target:
types: [assigned, opened, synchronize, reopened]
permissions:
pull-requests: write
contents: write
jobs:
automerge:
runs-on: ubuntu-latest
if: github.actor == 'vtolstov'
steps:
- name: merge
id: merge
run: gh pr merge --auto --merge "$PR_URL"
env:
PR_URL: ${{github.event.pull_request.html_url}}
GITHUB_TOKEN: ${{secrets.TOKEN}}

View File

@ -3,19 +3,20 @@ on:
push: push:
branches: branches:
- master - master
- v3
jobs: jobs:
test: test:
name: test name: test
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: setup - name: setup
uses: actions/setup-go@v2 uses: actions/setup-go@v3
with: with:
go-version: 1.16 go-version: 1.17
- name: checkout - name: checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: cache - name: cache
uses: actions/cache@v2 uses: actions/cache@v3
with: with:
path: ~/go/pkg/mod path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
@ -31,9 +32,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: checkout - name: checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: lint - name: lint
uses: golangci/golangci-lint-action@v2 uses: golangci/golangci-lint-action@v3.4.0
continue-on-error: true continue-on-error: true
with: with:
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version. # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.

View File

@ -9,7 +9,7 @@
# the `language` matrix defined below to confirm you have the correct set of # the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages. # supported CodeQL languages.
# #
name: "CodeQL" name: "codeql"
on: on:
workflow_run: workflow_run:
@ -17,16 +17,16 @@ on:
types: types:
- completed - completed
push: push:
branches: [ master ] branches: [ master, v3 ]
pull_request: pull_request:
# The branches below must be a subset of the branches above # The branches below must be a subset of the branches above
branches: [ master ] branches: [ master, v3 ]
schedule: schedule:
- cron: '34 1 * * 0' - cron: '34 1 * * 0'
jobs: jobs:
analyze: analyze:
name: Analyze name: analyze
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
actions: read actions: read
@ -42,12 +42,15 @@ jobs:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps: steps:
- name: Checkout repository - name: checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: setup
uses: actions/setup-go@v3
with:
go-version: 1.17
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: init
uses: github/codeql-action/init@v1 uses: github/codeql-action/init@v2
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file. # If you wish to specify custom queries, you can do so here or in a config file.
@ -57,8 +60,8 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below) # If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild - name: autobuild
uses: github/codeql-action/autobuild@v1 uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell. # Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl # 📚 https://git.io/JvXDl
@ -71,5 +74,5 @@ jobs:
# make bootstrap # make bootstrap
# make release # make release
- name: Perform CodeQL Analysis - name: analyze
uses: github/codeql-action/analyze@v1 uses: github/codeql-action/analyze@v2

View File

@ -1,66 +1,27 @@
name: "prautomerge" name: "dependabot-automerge"
on: on:
workflow_run: pull_request_target:
workflows: ["prbuild"] types: [assigned, opened, synchronize, reopened]
types:
- completed
permissions: permissions:
contents: write
pull-requests: write pull-requests: write
contents: write
jobs: jobs:
Dependabot-Automerge: automerge:
runs-on: ubuntu-latest runs-on: ubuntu-latest
# Contains workaround to execute if dependabot updates the PR by checking for the base branch in the linked PR if: github.actor == 'dependabot[bot]'
# The the github.event.workflow_run.event value is 'push' and not 'pull_request'
# dont work with multiple workflows when last returns success
if: >-
github.event.workflow_run.conclusion == 'success'
&& github.actor == 'dependabot[bot]'
&& github.event.sender.login == 'dependabot[bot]'
&& github.event.sender.type == 'Bot'
&& (github.event.workflow_run.event == 'pull_request'
|| (github.event.workflow_run.event == 'push' && github.event.workflow_run.pull_requests[0].base.ref == github.event.repository.default_branch ))
steps: steps:
- name: Approve Changes and Merge changes if label 'dependencies' is set - name: metadata
uses: actions/github-script@v4 id: metadata
uses: dependabot/fetch-metadata@v1.3.6
with: with:
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: "${{ secrets.TOKEN }}"
script: | - name: merge
console.log(context.payload.workflow_run); id: merge
if: ${{contains(steps.metadata.outputs.dependency-names, 'go.unistack.org')}}
var labelNames = await github.paginate( run: gh pr merge --auto --merge "$PR_URL"
github.issues.listLabelsOnIssue, env:
{ PR_URL: ${{github.event.pull_request.html_url}}
repo: context.repo.repo, GITHUB_TOKEN: ${{secrets.TOKEN}}
owner: context.repo.owner,
issue_number: context.payload.workflow_run.pull_requests[0].number,
},
(response) => response.data.map(
(label) => label.name
)
);
console.log(labelNames);
if (labelNames.includes('dependencies')) {
console.log('Found label');
await github.pulls.createReview({
repo: context.repo.repo,
owner: context.repo.owner,
pull_number: context.payload.workflow_run.pull_requests[0].number,
event: 'APPROVE'
});
console.log('Approved PR');
await github.pulls.merge({
repo: context.repo.repo,
owner: context.repo.owner,
pull_number: context.payload.workflow_run.pull_requests[0].number,
});
console.log('Merged PR');
}

View File

@ -3,19 +3,20 @@ on:
pull_request: pull_request:
branches: branches:
- master - master
- v3
jobs: jobs:
test: test:
name: test name: test
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: setup - name: setup
uses: actions/setup-go@v2 uses: actions/setup-go@v3
with: with:
go-version: 1.16 go-version: 1.17
- name: checkout - name: checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: cache - name: cache
uses: actions/cache@v2 uses: actions/cache@v3
with: with:
path: ~/go/pkg/mod path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
@ -31,9 +32,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: checkout - name: checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: lint - name: lint
uses: golangci/golangci-lint-action@v2 uses: golangci/golangci-lint-action@v3.4.0
continue-on-error: true continue-on-error: true
with: with:
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version. # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.

24
.gitignore vendored Normal file
View File

@ -0,0 +1,24 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
bin
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
# Go workspace file
go.work
# General
.DS_Store
.idea
.vscode

View File

@ -1,8 +1,6 @@
package grpc package grpc
import ( import (
"io"
"go.unistack.org/micro/v3/codec" "go.unistack.org/micro/v3/codec"
"google.golang.org/grpc/encoding" "google.golang.org/grpc/encoding"
) )
@ -49,29 +47,3 @@ func (w *wrapGrpcCodec) Unmarshal(d []byte, v interface{}, opts ...codec.Option)
} }
return w.Codec.Unmarshal(d, v) return w.Codec.Unmarshal(d, v)
} }
func (w *wrapGrpcCodec) ReadHeader(conn io.Reader, m *codec.Message, mt codec.MessageType) error {
return nil
}
func (w *wrapGrpcCodec) ReadBody(conn io.Reader, v interface{}) error {
if m, ok := v.(*codec.Frame); ok {
_, err := conn.Read(m.Data)
return err
}
return codec.ErrInvalidMessage
}
func (w *wrapGrpcCodec) Write(conn io.Writer, m *codec.Message, v interface{}) error {
// if we don't have a body
if v != nil {
b, err := w.Marshal(v)
if err != nil {
return err
}
m.Body = b
}
// write the body using the framing codec
_, err := conn.Write(m.Body)
return err
}

4
generate.go Normal file
View File

@ -0,0 +1,4 @@
package grpc
//go:generate go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
//go:generate sh -c "protoc -I./proto -I$(go list -f '{{ .Dir }}' -m go.unistack.org/micro-proto/v3) -I. --go-grpc_out=paths=source_relative:./proto --go_out=paths=source_relative:./proto proto/test.proto"

21
go.mod
View File

@ -1,11 +1,20 @@
module go.unistack.org/micro-server-grpc/v3 module go.unistack.org/micro-server-grpc/v3
go 1.16 go 1.22
toolchain go1.23.1
require ( require (
github.com/golang/protobuf v1.5.2 github.com/golang/protobuf v1.5.4
go.unistack.org/micro/v3 v3.8.5 go.unistack.org/micro/v3 v3.10.97
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b golang.org/x/net v0.30.0
google.golang.org/grpc v1.40.0 google.golang.org/grpc v1.67.1
google.golang.org/protobuf v1.27.1 google.golang.org/protobuf v1.35.1
)
require (
go.unistack.org/micro-proto/v3 v3.4.1 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/text v0.19.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect
) )

155
go.sum
View File

@ -1,135 +1,20 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= go.unistack.org/micro-proto/v3 v3.4.1 h1:UTjLSRz2YZuaHk9iSlVqqsA50JQNAEK2ZFboGqtEa9Q=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= go.unistack.org/micro-proto/v3 v3.4.1/go.mod h1:okx/cnOhzuCX0ggl/vToatbCupi0O44diiiLLsZ93Zo=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= go.unistack.org/micro/v3 v3.10.97 h1:8l7fv+i06/PjPrBBhRC/ZQkWGIOuHPg3jJN0vktYE78=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= go.unistack.org/micro/v3 v3.10.97/go.mod h1:YzMldzHN9Ei+zy5t/Psu7RUWDZwUfrNYiStSQtTz90g=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
github.com/ef-ds/deque v1.0.4/go.mod h1:gXDnTC3yqvBcHbq2lcExjtAcVrOnJCbMcZXmuj8Z4tg= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
github.com/golang-jwt/jwt/v4 v4.1.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/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/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/silas/dag v0.0.0-20210626123444-3804bac2d6d4/go.mod h1:7RTUFBdIRC9nZ7/3RyRNH1bdqIShrDejd1YbLwgPS+I=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.unistack.org/micro-proto/v3 v3.1.0 h1:q39FwjFiRZn+Ux/tt+d3bJTmDtsQQWa+3SLYVo1vLfA=
go.unistack.org/micro-proto/v3 v3.1.0/go.mod h1:DpRhYCBXlmSJ/AAXTmntvlh7kQkYU6eFvlmYAx4BQS8=
go.unistack.org/micro/v3 v3.8.5 h1:DIYWRsQF+NPhKZP45sCtNsUhaRw6u2+Ps7U+pKU7i3s=
go.unistack.org/micro/v3 v3.8.5/go.mod h1:KMMmOmbgo/D52/rCAbqeKbBsgEEbSKM69he54J3ZIuA=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b h1:eB48h3HiRycXNy8E0Gf5e0hv7YT6Kt14L/D73G1fuwo=
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q=
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
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/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
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=

516
grpc.go
View File

@ -1,5 +1,5 @@
// Package grpc provides a grpc server // Package grpc provides a grpc server
package grpc // import "go.unistack.org/micro-server-grpc/v3" package grpc
import ( import (
"context" "context"
@ -7,26 +7,33 @@ import (
"fmt" "fmt"
"net" "net"
"reflect" "reflect"
"runtime/debug" "slices"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"time" "time"
greflection "google.golang.org/grpc/reflection"
reflectionv1pb "google.golang.org/grpc/reflection/grpc_reflection_v1"
// nolint: staticcheck // nolint: staticcheck
oldproto "github.com/golang/protobuf/proto" oldproto "github.com/golang/protobuf/proto"
"go.unistack.org/micro/v3/broker" "go.unistack.org/micro/v3/broker"
"go.unistack.org/micro/v3/codec" "go.unistack.org/micro/v3/codec"
"go.unistack.org/micro/v3/errors" "go.unistack.org/micro/v3/errors"
"go.unistack.org/micro/v3/logger" "go.unistack.org/micro/v3/logger"
metadata "go.unistack.org/micro/v3/metadata" "go.unistack.org/micro/v3/metadata"
"go.unistack.org/micro/v3/meter"
"go.unistack.org/micro/v3/options"
"go.unistack.org/micro/v3/register" "go.unistack.org/micro/v3/register"
"go.unistack.org/micro/v3/semconv"
"go.unistack.org/micro/v3/server" "go.unistack.org/micro/v3/server"
msync "go.unistack.org/micro/v3/sync"
"go.unistack.org/micro/v3/tracer"
"golang.org/x/net/netutil" "golang.org/x/net/netutil"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/encoding" "google.golang.org/grpc/encoding"
gmetadata "google.golang.org/grpc/metadata" gmetadata "google.golang.org/grpc/metadata"
"google.golang.org/grpc/peer" "google.golang.org/grpc/peer"
@ -35,35 +42,47 @@ import (
) )
const ( const (
defaultContentType = "application/grpc+proto" DefaultContentType = "application/grpc"
) )
/* /*
type grpcServerReflection struct { type ServerReflection struct {
srv *grpc.Server srv *grpc.Server
s *serverReflectionServer s *serverReflectionServer
} }
*/ */
type grpcServer struct { type streamWrapper struct {
handlers map[string]server.Handler ctx context.Context
srv *grpc.Server grpc.ServerStream
exit chan chan error }
wg *sync.WaitGroup
rsvc *register.Service func (w *streamWrapper) Context() context.Context {
subscribers map[*subscriber][]broker.Subscriber if w.ctx != nil {
rpc *rServer return w.ctx
opts server.Options }
return w.ServerStream.Context()
}
type Server struct {
handlers map[string]server.Handler
srv *grpc.Server
exit chan chan error
wg *msync.WaitGroup
rsvc *register.Service
subscribers map[*subscriber][]broker.Subscriber
rpc *rServer
opts server.Options
unknownHandler grpc.StreamHandler
sync.RWMutex sync.RWMutex
init bool
started bool started bool
registered bool registered bool
reflection bool reflection bool
} }
func newGRPCServer(opts ...server.Option) server.Server { func newServer(opts ...server.Option) *Server {
// create a grpc server // create a grpc server
g := &grpcServer{ g := &Server{
opts: server.NewOptions(opts...), opts: server.NewOptions(opts...),
rpc: &rServer{ rpc: &rServer{
serviceMap: make(map[string]*service), serviceMap: make(map[string]*service),
@ -73,6 +92,8 @@ func newGRPCServer(opts ...server.Option) server.Server {
exit: make(chan chan error), exit: make(chan chan error),
} }
g.opts.Meter = g.opts.Meter.Clone(meter.Labels("type", "grpc"))
return g return g
} }
@ -92,7 +113,7 @@ func (r grpcRouter) ServeRequest(ctx context.Context, req server.Request, rsp se
*/ */
func (g *grpcServer) configure(opts ...server.Option) error { func (g *Server) configure(opts ...server.Option) error {
g.Lock() g.Lock()
defer g.Unlock() defer g.Unlock()
@ -100,30 +121,6 @@ func (g *grpcServer) configure(opts ...server.Option) error {
o(&g.opts) o(&g.opts)
} }
if err := g.opts.Register.Init(); err != nil {
return err
}
if err := g.opts.Broker.Init(); err != nil {
return err
}
if err := g.opts.Tracer.Init(); err != nil {
return err
}
if err := g.opts.Auth.Init(); err != nil {
return err
}
if err := g.opts.Logger.Init(); err != nil {
return err
}
if err := g.opts.Meter.Init(); err != nil {
return err
}
if err := g.opts.Transport.Init(); err != nil {
return err
}
g.wg = g.opts.Wait
if g.opts.Context != nil { if g.opts.Context != nil {
if codecs, ok := g.opts.Context.Value(codecsKey{}).(map[string]encoding.Codec); ok && codecs != nil { if codecs, ok := g.opts.Context.Value(codecsKey{}).(map[string]encoding.Codec); ok && codecs != nil {
for k, v := range codecs { for k, v := range codecs {
@ -132,6 +129,10 @@ func (g *grpcServer) configure(opts ...server.Option) error {
} }
} }
for _, k := range g.opts.Codecs {
encoding.RegisterCodec(&wrapMicroCodec{k})
}
maxMsgSize := g.getMaxMsgSize() maxMsgSize := g.getMaxMsgSize()
gopts := []grpc.ServerOption{ gopts := []grpc.ServerOption{
@ -140,12 +141,8 @@ func (g *grpcServer) configure(opts ...server.Option) error {
grpc.UnknownServiceHandler(g.handler), grpc.UnknownServiceHandler(g.handler),
} }
if creds := g.getCredentials(); creds != nil {
gopts = append(gopts, grpc.Creds(creds))
}
if opts := g.getGrpcOptions(); opts != nil { if opts := g.getGrpcOptions(); opts != nil {
gopts = append(gopts, opts...) gopts = append(opts, gopts...)
} }
g.rsvc = nil g.rsvc = nil
@ -158,38 +155,37 @@ func (g *grpcServer) configure(opts ...server.Option) error {
} }
g.srv = grpc.NewServer(gopts...) g.srv = grpc.NewServer(gopts...)
if v, ok := g.opts.Context.Value(reflectionKey{}).(bool); ok { if v, ok := g.opts.Context.Value(reflectionKey{}).(Reflector); ok {
g.reflection = v reflectionv1pb.RegisterServerReflectionServer(
g.srv,
greflection.NewServerV1(greflection.ServerOptions{
Services: v,
DescriptorResolver: v,
ExtensionResolver: v,
}),
)
}
if h, ok := g.opts.Context.Value(unknownServiceHandlerKey{}).(grpc.StreamHandler); ok {
g.unknownHandler = h
} }
if restart { if restart {
return g.Start() return g.Start()
} }
g.init = true
return nil return nil
} }
func (g *grpcServer) getMaxMsgSize() int { func (g *Server) getMaxMsgSize() int {
if g.opts.Context == nil {
return codec.DefaultMaxMsgSize
}
s, ok := g.opts.Context.Value(maxMsgSizeKey{}).(int) s, ok := g.opts.Context.Value(maxMsgSizeKey{}).(int)
if !ok { if !ok {
return codec.DefaultMaxMsgSize return 4 * 1024 * 1024
} }
return s return s
} }
func (g *grpcServer) getCredentials() credentials.TransportCredentials { func (g *Server) getGrpcOptions() []grpc.ServerOption {
if g.opts.TLSConfig != nil {
return credentials.NewTLS(g.opts.TLSConfig)
}
return nil
}
func (g *grpcServer) getGrpcOptions() []grpc.ServerOption {
if g.opts.Context == nil { if g.opts.Context == nil {
return nil return nil
} }
@ -202,61 +198,86 @@ func (g *grpcServer) getGrpcOptions() []grpc.ServerOption {
return opts return opts
} }
func (g *grpcServer) handler(srv interface{}, stream grpc.ServerStream) (err error) { func (g *Server) handler(srv interface{}, stream grpc.ServerStream) error {
defer func() { var err error
if r := recover(); r != nil {
g.RLock()
config := g.opts
g.RUnlock()
if config.Logger.V(logger.ErrorLevel) {
config.Logger.Error(config.Context, "panic recovered: ", r)
config.Logger.Error(config.Context, string(debug.Stack()))
}
err = errors.InternalServerError(g.opts.Name, "panic recovered: %v", r)
} else if err != nil {
g.RLock()
config := g.opts
g.RUnlock()
if config.Logger.V(logger.ErrorLevel) {
config.Logger.Errorf(config.Context, "grpc handler got error: %s", err)
}
}
}()
if g.wg != nil { ctx := stream.Context()
g.wg.Add(1)
defer g.wg.Done()
}
fullMethod, ok := grpc.MethodFromServerStream(stream) fullMethod, ok := grpc.MethodFromServerStream(stream)
if !ok { if !ok {
return status.Errorf(codes.Internal, "method does not exist in context") return status.Errorf(codes.Internal, "method does not exist in context")
} }
serviceName, methodName, err := serviceMethod(fullMethod)
if err != nil {
return status.New(codes.InvalidArgument, err.Error()).Err()
}
// get grpc metadata // get grpc metadata
gmd, ok := gmetadata.FromIncomingContext(stream.Context()) gmd, ok := gmetadata.FromIncomingContext(ctx)
if !ok { if !ok {
gmd = gmetadata.MD{} gmd = gmetadata.MD{}
} }
md := metadata.New(len(gmd)) var serviceName, methodName string
for k, v := range gmd { serviceName, methodName, err = serviceMethod(fullMethod)
md.Set(k, strings.Join(v, ", ")) if err != nil {
err = status.New(codes.InvalidArgument, err.Error()).Err()
return err
} }
endpointName := serviceName + "/" + methodName
ts := time.Now()
var sp tracer.Span
if !slices.Contains(tracer.DefaultSkipEndpoints, endpointName) {
ctx, sp = g.opts.Tracer.Start(ctx, "rpc-server",
tracer.WithSpanKind(tracer.SpanKindServer),
tracer.WithSpanLabels(
"endpoint", endpointName,
"server", "grpc",
),
)
defer func() {
st := status.Convert(err)
if st != nil || st.Code() != codes.OK {
sp.SetStatus(tracer.SpanStatusError, err.Error())
}
sp.Finish()
}()
}
md := metadata.New(len(gmd))
for k, v := range gmd {
md[k] = strings.Join(v, ", ")
}
md.Set("Path", fullMethod)
md.Set("Micro-Server", "grpc")
md.Set(metadata.HeaderEndpoint, methodName)
md.Set(metadata.HeaderService, serviceName)
var td string
// timeout for server deadline // timeout for server deadline
to, ok := md.Get("timeout") if v, ok := md.Get("timeout"); ok {
if ok {
md.Del("timeout") md.Del("timeout")
td = v
}
if v, ok := md.Get("Grpc-Timeout"); ok {
md.Del("Grpc-Timeout")
td = v[:len(v)-1]
switch v[len(v)-1:] {
case "S":
td += "s"
case "M":
td += "m"
case "H":
td += "h"
case "m":
td += "ms"
case "u":
td += "us"
case "n":
td += "ns"
}
} }
// get content type // get content type
ct := defaultContentType ct := DefaultContentType
if ctype, ok := md.Get("content-type"); ok { if ctype, ok := md.Get("content-type"); ok {
ct = ctype ct = ctype
@ -266,17 +287,42 @@ func (g *grpcServer) handler(srv interface{}, stream grpc.ServerStream) (err err
} }
// create new context // create new context
ctx := metadata.NewIncomingContext(stream.Context(), md) ctx = metadata.NewIncomingContext(ctx, md)
stream = &streamWrapper{ctx, stream}
if !slices.Contains(meter.DefaultSkipEndpoints, endpointName) {
g.opts.Meter.Counter(semconv.ServerRequestInflight, "endpoint", endpointName, "server", "grpc").Inc()
defer func() {
te := time.Since(ts)
g.opts.Meter.Summary(semconv.ServerRequestLatencyMicroseconds, "endpoint", endpointName, "server", "grpc").Update(te.Seconds())
g.opts.Meter.Histogram(semconv.ServerRequestDurationSeconds, "endpoint", endpointName, "server", "grpc").Update(te.Seconds())
g.opts.Meter.Counter(semconv.ServerRequestInflight, "endpoint", endpointName, "server", "grpc").Dec()
st := status.Convert(err)
if st == nil || st.Code() == codes.OK {
g.opts.Meter.Counter(semconv.ServerRequestTotal, "endpoint", endpointName, "server", "grpc", "status", "success", "code", strconv.Itoa(int(codes.OK))).Inc()
} else {
g.opts.Meter.Counter(semconv.ServerRequestTotal, "endpoint", endpointName, "server", "grpc", "status", "failure", "code", strconv.Itoa(int(st.Code()))).Inc()
}
}()
}
if g.opts.Wait != nil {
g.opts.Wait.Add(1)
defer g.opts.Wait.Done()
}
// get peer from context // get peer from context
if p, ok := peer.FromContext(stream.Context()); ok { if p, ok := peer.FromContext(ctx); ok {
md["Remote"] = p.Addr.String() md.Set("Remote", p.Addr.String())
ctx = peer.NewContext(ctx, p) ctx = peer.NewContext(ctx, p)
} }
// set the timeout if we have it // set the timeout if we have it
if len(to) > 0 { if len(td) > 0 {
if n, err := strconv.ParseUint(to, 10, 64); err == nil { var n uint64
if n, err = strconv.ParseUint(td, 10, 64); err == nil {
var cancel context.CancelFunc var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, time.Duration(n)) ctx, cancel = context.WithTimeout(ctx, time.Duration(n))
defer cancel() defer cancel()
@ -287,48 +333,39 @@ func (g *grpcServer) handler(srv interface{}, stream grpc.ServerStream) (err err
svc := g.rpc.serviceMap[serviceName] svc := g.rpc.serviceMap[serviceName]
g.rpc.mu.RUnlock() g.rpc.mu.RUnlock()
/*
if svc == nil && g.reflection && methodName == "ServerReflectionInfo" {
rfl := &grpcServerReflection{srv: g.srv, s: &serverReflectionServer{s: g.srv}}
svc = &service{}
svc.typ = reflect.TypeOf(rfl)
svc.rcvr = reflect.ValueOf(rfl)
svc.name = reflect.Indirect(svc.rcvr).Type().Name()
svc.method = make(map[string]*methodType)
typ := reflect.TypeOf(rfl)
if me, ok := typ.MethodByName("ServerReflectionInfo"); ok {
g.rpc.mu.Lock()
ep, err := prepareEndpoint(me)
if ep != nil && err != nil {
svc.method["ServerReflectionInfo"] = ep
} else if err != nil {
return status.New(codes.Unimplemented, err.Error()).Err()
}
g.rpc.mu.Unlock()
}
}
*/
if svc == nil { if svc == nil {
return status.New(codes.Unimplemented, fmt.Sprintf("unknown service %s", serviceName)).Err() if g.unknownHandler != nil {
err = g.unknownHandler(srv, stream)
return err
}
err = status.New(codes.Unimplemented, fmt.Sprintf("unknown service %s", serviceName)).Err()
return err
} }
mtype := svc.method[methodName] mtype := svc.method[methodName]
if mtype == nil { if mtype == nil {
return status.New(codes.Unimplemented, fmt.Sprintf("unknown service %s.%s", serviceName, methodName)).Err() if g.unknownHandler != nil {
err = g.unknownHandler(srv, stream)
return err
}
err = status.New(codes.Unimplemented, fmt.Sprintf("unknown service method %s.%s", serviceName, methodName)).Err()
return err
} }
// process unary // process unary
if !mtype.stream { if !mtype.stream {
return g.processRequest(ctx, stream, svc, mtype, ct) err = g.processRequest(ctx, stream, svc, mtype, ct)
} else {
// process stream
err = g.processStream(ctx, stream, svc, mtype, ct)
} }
// process stream return err
return g.processStream(ctx, stream, svc, mtype, ct)
} }
func (g *grpcServer) processRequest(ctx context.Context, stream grpc.ServerStream, service *service, mtype *methodType, ct string) error { func (g *Server) processRequest(ctx context.Context, stream grpc.ServerStream, service *service, mtype *methodType, ct string) error {
// for { // for {
var err error
var argv, replyv reflect.Value var argv, replyv reflect.Value
// Decode the argument value. // Decode the argument value.
@ -341,7 +378,7 @@ func (g *grpcServer) processRequest(ctx context.Context, stream grpc.ServerStrea
} }
// Unmarshal request // Unmarshal request
if err := stream.RecvMsg(argv.Interface()); err != nil { if err = stream.RecvMsg(argv.Interface()); err != nil {
return err return err
} }
@ -355,26 +392,17 @@ func (g *grpcServer) processRequest(ctx context.Context, stream grpc.ServerStrea
function := mtype.method.Func function := mtype.method.Func
var returnValues []reflect.Value var returnValues []reflect.Value
cf, err := g.newCodec(ct)
if err != nil {
return errors.InternalServerError(g.opts.Name, err.Error())
}
b, err := cf.Marshal(argv.Interface())
if err != nil {
return err
}
// create a client.Request // create a client.Request
r := &rpcRequest{ r := &rpcRequest{
service: g.opts.Name, service: g.opts.Name,
contentType: ct, contentType: ct,
method: fmt.Sprintf("%s.%s", service.name, mtype.method.Name), method: fmt.Sprintf("%s.%s", service.name, mtype.method.Name),
body: b, endpoint: fmt.Sprintf("%s.%s", service.name, mtype.method.Name),
payload: argv.Interface(), payload: argv.Interface(),
} }
// define the handler func // define the handler func
fn := func(ctx context.Context, req server.Request, rsp interface{}) (err error) { fn := func(ctx context.Context, req server.Request, rsp interface{}) (err error) {
returnValues = function.Call([]reflect.Value{service.rcvr, mtype.prepareContext(ctx), reflect.ValueOf(argv.Interface()), reflect.ValueOf(rsp)}) returnValues = function.Call([]reflect.Value{service.rcvr, mtype.prepareContext(ctx), argv, reflect.ValueOf(rsp)})
// The return value for the method is an error. // The return value for the method is an error.
if rerr := returnValues[0].Interface(); rerr != nil { if rerr := returnValues[0].Interface(); rerr != nil {
@ -384,15 +412,22 @@ func (g *grpcServer) processRequest(ctx context.Context, stream grpc.ServerStrea
return err return err
} }
// wrap the handler func g.opts.Hooks.EachNext(func(hook options.Hook) {
for i := len(g.opts.HdlrWrappers); i > 0; i-- { if h, ok := hook.(server.HookHandler); ok {
fn = g.opts.HdlrWrappers[i-1](fn) fn = h(fn)
} }
})
statusCode := codes.OK statusCode := codes.OK
statusDesc := "" statusDesc := ""
// execute the handler // execute the handler
if appErr := fn(ctx, r, replyv.Interface()); appErr != nil { appErr := fn(ctx, r, replyv.Interface())
if outmd, ok := metadata.FromOutgoingContext(ctx); ok {
if err = stream.SendHeader(gmetadata.New(outmd)); err != nil {
return err
}
}
if appErr != nil {
var errStatus *status.Status var errStatus *status.Status
switch verr := appErr.(type) { switch verr := appErr.(type) {
case *errors.Error: case *errors.Error:
@ -407,12 +442,14 @@ func (g *grpcServer) processRequest(ctx context.Context, stream grpc.ServerStrea
if err != nil { if err != nil {
return err return err
} }
case (interface{ GRPCStatus() *status.Status }):
errStatus = verr.GRPCStatus()
default: default:
g.RLock() g.RLock()
config := g.opts config := g.opts
g.RUnlock() g.RUnlock()
if config.Logger.V(logger.ErrorLevel) { if config.Logger.V(logger.ErrorLevel) {
config.Logger.Warn(config.Context, "handler error will not be transferred properly, must return *errors.Error or proto.Message") config.Logger.Error(config.Context, "handler error will not be transferred properly, must return *errors.Error or proto.Message")
} }
// default case user pass own error type that not proto based // default case user pass own error type that not proto based
statusCode = convertCode(verr) statusCode = convertCode(verr)
@ -428,60 +465,16 @@ func (g *grpcServer) processRequest(ctx context.Context, stream grpc.ServerStrea
} }
return status.New(statusCode, statusDesc).Err() return status.New(statusCode, statusDesc).Err()
// }
} }
/* func (g *Server) processStream(ctx context.Context, stream grpc.ServerStream, service *service, mtype *methodType, ct string) error {
type reflectStream struct {
stream server.Stream
}
func (s *reflectStream) Send(rsp *grpcreflect.ServerReflectionResponse) error {
return s.stream.Send(rsp)
}
func (s *reflectStream) Recv() (*grpcreflect.ServerReflectionRequest, error) {
req := &grpcreflect.ServerReflectionRequest{}
err := s.stream.Recv(req)
return req, err
}
func (s *reflectStream) SetHeader(gmetadata.MD) error {
return nil
}
func (s *reflectStream) SendHeader(gmetadata.MD) error {
return nil
}
func (s *reflectStream) SetTrailer(gmetadata.MD) {
}
func (s *reflectStream) Context() context.Context {
return s.stream.Context()
}
func (s *reflectStream) SendMsg(m interface{}) error {
return s.stream.Send(m)
}
func (s *reflectStream) RecvMsg(m interface{}) error {
return s.stream.Recv(m)
}
func (g *grpcServerReflection) ServerReflectionInfo(ctx context.Context, stream server.Stream) error {
return g.s.ServerReflectionInfo(&reflectStream{stream})
}
*/
func (g *grpcServer) processStream(ctx context.Context, stream grpc.ServerStream, service *service, mtype *methodType, ct string) error {
opts := g.opts opts := g.opts
r := &rpcRequest{ r := &rpcRequest{
service: opts.Name, service: opts.Name,
contentType: ct, contentType: ct,
method: fmt.Sprintf("%s.%s", service.name, mtype.method.Name), method: fmt.Sprintf("%s.%s", service.name, mtype.method.Name),
endpoint: fmt.Sprintf("%s.%s", service.name, mtype.method.Name),
stream: true, stream: true,
} }
@ -503,14 +496,22 @@ func (g *grpcServer) processStream(ctx context.Context, stream grpc.ServerStream
return nil return nil
} }
for i := len(opts.HdlrWrappers); i > 0; i-- { opts.Hooks.EachNext(func(hook options.Hook) {
fn = opts.HdlrWrappers[i-1](fn) if h, ok := hook.(server.HookHandler); ok {
} fn = h(fn)
}
})
statusCode := codes.OK statusCode := codes.OK
statusDesc := "" statusDesc := ""
if appErr := fn(ctx, r, ss); appErr != nil { appErr := fn(ctx, r, ss)
if outmd, ok := metadata.FromOutgoingContext(ctx); ok {
if err := stream.SendHeader(gmetadata.New(outmd)); err != nil {
return err
}
}
if appErr != nil {
var err error var err error
var errStatus *status.Status var errStatus *status.Status
switch verr := appErr.(type) { switch verr := appErr.(type) {
@ -542,7 +543,7 @@ func (g *grpcServer) processStream(ctx context.Context, stream grpc.ServerStream
return status.New(statusCode, statusDesc).Err() return status.New(statusCode, statusDesc).Err()
} }
func (g *grpcServer) newCodec(ct string) (codec.Codec, error) { func (g *Server) newCodec(ct string) (codec.Codec, error) {
g.RLock() g.RLock()
defer g.RUnlock() defer g.RUnlock()
@ -557,7 +558,7 @@ func (g *grpcServer) newCodec(ct string) (codec.Codec, error) {
return nil, codec.ErrUnknownContentType return nil, codec.ErrUnknownContentType
} }
func (g *grpcServer) Options() server.Options { func (g *Server) Options() server.Options {
g.RLock() g.RLock()
opts := g.opts opts := g.opts
g.RUnlock() g.RUnlock()
@ -565,18 +566,15 @@ func (g *grpcServer) Options() server.Options {
return opts return opts
} }
func (g *grpcServer) Init(opts ...server.Option) error { func (g *Server) Init(opts ...server.Option) error {
if len(opts) == 0 && g.init {
return nil
}
return g.configure(opts...) return g.configure(opts...)
} }
func (g *grpcServer) NewHandler(h interface{}, opts ...server.HandlerOption) server.Handler { func (g *Server) NewHandler(h interface{}, opts ...server.HandlerOption) server.Handler {
return newRPCHandler(h, opts...) return newRPCHandler(h, opts...)
} }
func (g *grpcServer) Handle(h server.Handler) error { func (g *Server) Handle(h server.Handler) error {
if err := g.rpc.register(h.Handler()); err != nil { if err := g.rpc.register(h.Handler()); err != nil {
return err return err
} }
@ -585,11 +583,11 @@ func (g *grpcServer) Handle(h server.Handler) error {
return nil return nil
} }
func (g *grpcServer) NewSubscriber(topic string, sb interface{}, opts ...server.SubscriberOption) server.Subscriber { func (g *Server) NewSubscriber(topic string, sb interface{}, opts ...server.SubscriberOption) server.Subscriber {
return newSubscriber(topic, sb, opts...) return newSubscriber(topic, sb, opts...)
} }
func (g *grpcServer) Subscribe(sb server.Subscriber) error { func (g *Server) Subscribe(sb server.Subscriber) error {
sub, ok := sb.(*subscriber) sub, ok := sb.(*subscriber)
if !ok { if !ok {
return fmt.Errorf("invalid subscriber: expected *subscriber") return fmt.Errorf("invalid subscriber: expected *subscriber")
@ -613,7 +611,7 @@ func (g *grpcServer) Subscribe(sb server.Subscriber) error {
return nil return nil
} }
func (g *grpcServer) Register() error { func (g *Server) Register() error {
g.RLock() g.RLock()
rsvc := g.rsvc rsvc := g.rsvc
config := g.opts config := g.opts
@ -670,7 +668,7 @@ func (g *grpcServer) Register() error {
if !registered { if !registered {
if config.Logger.V(logger.InfoLevel) { if config.Logger.V(logger.InfoLevel) {
config.Logger.Infof(config.Context, "Register [%s] Registering node: %s", config.Register.String(), service.Nodes[0].ID) config.Logger.Info(config.Context, fmt.Sprintf("Register [%s] Registering node: %s", config.Register.String(), service.Nodes[0].ID))
} }
} }
@ -687,37 +685,13 @@ func (g *grpcServer) Register() error {
g.Lock() g.Lock()
defer g.Unlock() defer g.Unlock()
for sb := range g.subscribers {
handler := g.createSubHandler(sb, config)
var opts []broker.SubscribeOption
if queue := sb.Options().Queue; len(queue) > 0 {
opts = append(opts, broker.SubscribeGroup(queue))
}
subCtx := config.Context
if cx := sb.Options().Context; cx != nil {
subCtx = cx
}
opts = append(opts, broker.SubscribeContext(subCtx))
opts = append(opts, broker.SubscribeAutoAck(sb.Options().AutoAck))
if config.Logger.V(logger.InfoLevel) {
config.Logger.Infof(config.Context, "Subscribing to topic: %s", sb.Topic())
}
sub, err := config.Broker.Subscribe(subCtx, sb.Topic(), handler, opts...)
if err != nil {
return err
}
g.subscribers[sb] = []broker.Subscriber{sub}
}
g.registered = true g.registered = true
g.rsvc = service g.rsvc = service
return nil return nil
} }
func (g *grpcServer) Deregister() error { func (g *Server) Deregister() error {
var err error var err error
g.RLock() g.RLock()
@ -730,7 +704,7 @@ func (g *grpcServer) Deregister() error {
} }
if config.Logger.V(logger.InfoLevel) { if config.Logger.V(logger.InfoLevel) {
config.Logger.Infof(config.Context, "Deregistering node: %s", service.Nodes[0].ID) config.Logger.Info(config.Context, "Deregistering node: "+service.Nodes[0].ID)
} }
if err := server.DefaultDeregisterFunc(service, config); err != nil { if err := server.DefaultDeregisterFunc(service, config); err != nil {
@ -754,11 +728,11 @@ func (g *grpcServer) Deregister() error {
go func(s broker.Subscriber) { go func(s broker.Subscriber) {
defer wg.Done() defer wg.Done()
if config.Logger.V(logger.InfoLevel) { if config.Logger.V(logger.InfoLevel) {
config.Logger.Infof(config.Context, "Unsubscribing from topic: %s", s.Topic()) config.Logger.Info(config.Context, "Unsubscribing from topic: "+s.Topic())
} }
if err := s.Unsubscribe(g.opts.Context); err != nil { if err := s.Unsubscribe(g.opts.Context); err != nil {
if config.Logger.V(logger.ErrorLevel) { if config.Logger.V(logger.ErrorLevel) {
config.Logger.Errorf(config.Context, "Unsubscribing from topic: %s err: %v", s.Topic(), err) config.Logger.Error(config.Context, "Unsubscribing from topic: "+s.Topic(), err)
} }
} }
}(sub) }(sub)
@ -771,7 +745,7 @@ func (g *grpcServer) Deregister() error {
return nil return nil
} }
func (g *grpcServer) Start() error { func (g *Server) Start() error {
g.RLock() g.RLock()
if g.started { if g.started {
g.RUnlock() g.RUnlock()
@ -781,10 +755,6 @@ func (g *grpcServer) Start() error {
config := g.Options() config := g.Options()
for _, k := range config.Codecs {
encoding.RegisterCodec(&wrapMicroCodec{k})
}
// micro: config.Transport.Listen(config.Address) // micro: config.Transport.Listen(config.Address)
var ts net.Listener var ts net.Listener
var err error var err error
@ -809,7 +779,7 @@ func (g *grpcServer) Start() error {
} }
if config.Logger.V(logger.InfoLevel) { if config.Logger.V(logger.InfoLevel) {
config.Logger.Infof(config.Context, "Server [grpc] Listening on %s", ts.Addr().String()) config.Logger.Info(config.Context, "Server [grpc] Listening on "+ts.Addr().String())
} }
g.Lock() g.Lock()
g.opts.Address = ts.Addr().String() g.opts.Address = ts.Addr().String()
@ -823,13 +793,13 @@ func (g *grpcServer) Start() error {
// connect to the broker // connect to the broker
if err = config.Broker.Connect(config.Context); err != nil { if err = config.Broker.Connect(config.Context); err != nil {
if config.Logger.V(logger.ErrorLevel) { if config.Logger.V(logger.ErrorLevel) {
config.Logger.Errorf(config.Context, "Broker [%s] connect error: %v", config.Broker.String(), err) config.Logger.Error(config.Context, fmt.Sprintf("broker [%s] connect error", config.Broker.String()), err)
} }
return err return err
} }
if config.Logger.V(logger.InfoLevel) { if config.Logger.V(logger.InfoLevel) {
config.Logger.Infof(config.Context, "Broker [%s] Connected to %s", config.Broker.String(), config.Broker.Address()) config.Logger.Info(config.Context, fmt.Sprintf("broker [%s] Connected to %s", config.Broker.String(), config.Broker.Address()))
} }
} }
@ -837,26 +807,30 @@ func (g *grpcServer) Start() error {
// nolint: nestif // nolint: nestif
if err = g.opts.RegisterCheck(config.Context); err != nil { if err = g.opts.RegisterCheck(config.Context); err != nil {
if config.Logger.V(logger.ErrorLevel) { if config.Logger.V(logger.ErrorLevel) {
config.Logger.Errorf(config.Context, "Server %s-%s register check error: %s", config.Name, config.ID, err) config.Logger.Error(config.Context, fmt.Sprintf("Server %s-%s register check error", config.Name, config.ID), err)
} }
} else { } else {
// announce self to the world // announce self to the world
if err = g.Register(); err != nil { if err = g.Register(); err != nil {
if config.Logger.V(logger.ErrorLevel) { if config.Logger.V(logger.ErrorLevel) {
config.Logger.Errorf(config.Context, "Server register error: %v", err) config.Logger.Error(config.Context, "Server register error", err)
} }
} }
} }
if err = g.subscribe(); err != nil {
return err
}
// micro: go ts.Accept(s.accept) // micro: go ts.Accept(s.accept)
go func() { go func() {
if err = g.srv.Serve(ts); err != nil { if err = g.srv.Serve(ts); err != nil {
if config.Logger.V(logger.ErrorLevel) { if config.Logger.V(logger.ErrorLevel) {
config.Logger.Errorf(config.Context, "gRPC Server start error: %v", err) config.Logger.Error(config.Context, "gRPC Server start error", err)
} }
if err = g.Stop(); err != nil { if err = g.Stop(); err != nil {
if config.Logger.V(logger.ErrorLevel) { if config.Logger.V(logger.ErrorLevel) {
config.Logger.Errorf(config.Context, "gRPC Server stop error: %v", err) config.Logger.Error(config.Context, "gRPC Server stop error", err)
} }
} }
} }
@ -886,23 +860,23 @@ func (g *grpcServer) Start() error {
// nolint: nestif // nolint: nestif
if rerr != nil && registered { if rerr != nil && registered {
if config.Logger.V(logger.ErrorLevel) { if config.Logger.V(logger.ErrorLevel) {
config.Logger.Errorf(config.Context, "Server %s-%s register check error: %s, deregister it", config.Name, config.ID, rerr) config.Logger.Error(config.Context, fmt.Sprintf("Server %s-%s register check error, deregister it", config.Name, config.ID), rerr)
} }
// deregister self in case of error // deregister self in case of error
if err = g.Deregister(); err != nil { if err = g.Deregister(); err != nil {
if config.Logger.V(logger.ErrorLevel) { if config.Logger.V(logger.ErrorLevel) {
config.Logger.Errorf(config.Context, "Server %s-%s deregister error: %s", config.Name, config.ID, err) config.Logger.Error(config.Context, fmt.Sprintf("Server %s-%s deregister error", config.Name, config.ID), err)
} }
} }
} else if rerr != nil && !registered { } else if rerr != nil && !registered {
if config.Logger.V(logger.ErrorLevel) { if config.Logger.V(logger.ErrorLevel) {
config.Logger.Errorf(config.Context, "Server %s-%s register check error: %s", config.Name, config.ID, rerr) config.Logger.Error(config.Context, fmt.Sprintf("Server %s-%s register check error", config.Name, config.ID), rerr)
} }
continue continue
} }
if err = g.Register(); err != nil { if err = g.Register(); err != nil {
if config.Logger.V(logger.ErrorLevel) { if config.Logger.V(logger.ErrorLevel) {
config.Logger.Errorf(config.Context, "Server %s-%s register error: %s", config.Name, config.ID, err) config.Logger.Error(config.Context, fmt.Sprintf("Server %s-%s register error", config.Name, config.ID), err)
} }
} }
// wait for exit // wait for exit
@ -914,13 +888,13 @@ func (g *grpcServer) Start() error {
// deregister self // deregister self
if err = g.Deregister(); err != nil { if err = g.Deregister(); err != nil {
if config.Logger.V(logger.ErrorLevel) { if config.Logger.V(logger.ErrorLevel) {
config.Logger.Errorf(config.Context, "Server deregister error: %v", err) config.Logger.Error(config.Context, "Server deregister error", err)
} }
} }
// wait for waitgroup // wait for waitgroup
if g.wg != nil { if g.opts.Wait != nil {
g.wg.Wait() g.opts.Wait.Wait()
} }
// stop the grpc server // stop the grpc server
@ -933,7 +907,7 @@ func (g *grpcServer) Start() error {
select { select {
case <-exit: case <-exit:
case <-time.After(time.Second): case <-time.After(g.opts.GracefulTimeout):
g.srv.Stop() g.srv.Stop()
} }
@ -941,12 +915,12 @@ func (g *grpcServer) Start() error {
ch <- nil ch <- nil
if config.Logger.V(logger.InfoLevel) { if config.Logger.V(logger.InfoLevel) {
config.Logger.Infof(config.Context, "Broker [%s] Disconnected from %s", config.Broker.String(), config.Broker.Address()) config.Logger.Info(config.Context, fmt.Sprintf("broker [%s] Disconnected from %s", config.Broker.String(), config.Broker.Address()))
} }
// disconnect broker // disconnect broker
if err = config.Broker.Disconnect(config.Context); err != nil { if err = config.Broker.Disconnect(config.Context); err != nil {
if config.Logger.V(logger.ErrorLevel) { if config.Logger.V(logger.ErrorLevel) {
config.Logger.Errorf(config.Context, "Broker [%s] disconnect error: %v", config.Broker.String(), err) config.Logger.Error(config.Context, fmt.Sprintf("broker [%s] disconnect error", config.Broker.String()), err)
} }
} }
}() }()
@ -959,7 +933,7 @@ func (g *grpcServer) Start() error {
return nil return nil
} }
func (g *grpcServer) Stop() error { func (g *Server) Stop() error {
g.RLock() g.RLock()
if !g.started { if !g.started {
g.RUnlock() g.RUnlock()
@ -979,14 +953,18 @@ func (g *grpcServer) Stop() error {
return err return err
} }
func (g *grpcServer) String() string { func (g *Server) String() string {
return "grpc" return "grpc"
} }
func (g *grpcServer) Name() string { func (g *Server) Name() string {
return g.opts.Name return g.opts.Name
} }
func NewServer(opts ...server.Option) server.Server { func (g *Server) GRPCServer() *grpc.Server {
return newGRPCServer(opts...) return g.srv
}
func NewServer(opts ...server.Option) *Server {
return newServer(opts...)
} }

View File

@ -9,10 +9,11 @@ import (
) )
type ( type (
codecsKey struct{} codecsKey struct{}
grpcOptions struct{} grpcOptions struct{}
maxMsgSizeKey struct{} maxMsgSizeKey struct{}
reflectionKey struct{} reflectionKey struct{}
unknownServiceHandlerKey struct{}
) )
// gRPC Codec to be used to encode/decode requests for a given content type // gRPC Codec to be used to encode/decode requests for a given content type
@ -35,15 +36,18 @@ func Options(opts ...grpc.ServerOption) server.Option {
return server.SetOption(grpcOptions{}, opts) return server.SetOption(grpcOptions{}, opts)
} }
//
// MaxMsgSize set the maximum message in bytes the server can receive and // MaxMsgSize set the maximum message in bytes the server can receive and
// send. Default maximum message size is 4 MB. // send. Default maximum message size is 4 MB.
//
func MaxMsgSize(s int) server.Option { func MaxMsgSize(s int) server.Option {
return server.SetOption(maxMsgSizeKey{}, s) return server.SetOption(maxMsgSizeKey{}, s)
} }
// Reflection enables reflection support in grpc server // Reflection enables reflection support in grpc server
func Reflection(b bool) server.Option { func Reflection(r Reflector) server.Option {
return server.SetOption(reflectionKey{}, b) return server.SetOption(reflectionKey{}, r)
}
// UnknownServiceHandler enables support for all services
func UnknownServiceHandler(h grpc.StreamHandler) server.Option {
return server.SetOption(unknownServiceHandlerKey{}, h)
} }

208
proto/test.pb.go Normal file
View File

@ -0,0 +1,208 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v4.25.2
// source: test.proto
package testpb
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type CallReq struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Data string `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
}
func (x *CallReq) Reset() {
*x = CallReq{}
if protoimpl.UnsafeEnabled {
mi := &file_test_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CallReq) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CallReq) ProtoMessage() {}
func (x *CallReq) 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 mi.MessageOf(x)
}
// Deprecated: Use CallReq.ProtoReflect.Descriptor instead.
func (*CallReq) Descriptor() ([]byte, []int) {
return file_test_proto_rawDescGZIP(), []int{0}
}
func (x *CallReq) GetData() string {
if x != nil {
return x.Data
}
return ""
}
type CallRsp struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Data string `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
}
func (x *CallRsp) Reset() {
*x = CallRsp{}
if protoimpl.UnsafeEnabled {
mi := &file_test_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CallRsp) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CallRsp) ProtoMessage() {}
func (x *CallRsp) 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)
}
// Deprecated: Use CallRsp.ProtoReflect.Descriptor instead.
func (*CallRsp) Descriptor() ([]byte, []int) {
return file_test_proto_rawDescGZIP(), []int{1}
}
func (x *CallRsp) GetData() string {
if x != nil {
return x.Data
}
return ""
}
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, 0x04, 0x74, 0x65,
0x73, 0x74, 0x22, 0x1d, 0x0a, 0x07, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a,
0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74,
0x61, 0x22, 0x1d, 0x0a, 0x07, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x73, 0x70, 0x12, 0x12, 0x0a, 0x04,
0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61,
0x32, 0x33, 0x0a, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12,
0x24, 0x0a, 0x04, 0x43, 0x61, 0x6c, 0x6c, 0x12, 0x0d, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x43,
0x61, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x0d, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x61,
0x6c, 0x6c, 0x52, 0x73, 0x70, 0x42, 0x0b, 0x5a, 0x09, 0x2e, 0x2f, 0x3b, 0x74, 0x65, 0x73, 0x74,
0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_test_proto_rawDescOnce sync.Once
file_test_proto_rawDescData = file_test_proto_rawDesc
)
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, 2)
var file_test_proto_goTypes = []interface{}{
(*CallReq)(nil), // 0: test.CallReq
(*CallRsp)(nil), // 1: test.CallRsp
}
var file_test_proto_depIdxs = []int32{
0, // 0: test.TestService.Call:input_type -> test.CallReq
1, // 1: test.TestService.Call:output_type -> test.CallRsp
1, // [1:2] is the sub-list for method output_type
0, // [0:1] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] 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.(*CallReq); 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.(*CallRsp); 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: 2,
NumExtensions: 0,
NumServices: 1,
},
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
}

18
proto/test.proto Normal file
View File

@ -0,0 +1,18 @@
syntax = "proto3";
package test;
option go_package = "./;testpb";
service TestService {
rpc Call(CallReq) returns (CallRsp);
}
message CallReq {
string data = 1;
}
message CallRsp {
string data = 1;
}

109
proto/test_grpc.pb.go Normal file
View File

@ -0,0 +1,109 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
// - protoc v4.25.2
// source: test.proto
package testpb
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
const (
TestService_Call_FullMethodName = "/test.TestService/Call"
)
// 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 {
Call(ctx context.Context, in *CallReq, opts ...grpc.CallOption) (*CallRsp, error)
}
type testServiceClient struct {
cc grpc.ClientConnInterface
}
func NewTestServiceClient(cc grpc.ClientConnInterface) TestServiceClient {
return &testServiceClient{cc}
}
func (c *testServiceClient) Call(ctx context.Context, in *CallReq, opts ...grpc.CallOption) (*CallRsp, error) {
out := new(CallRsp)
err := c.cc.Invoke(ctx, TestService_Call_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// TestServiceServer is the server API for TestService service.
// All implementations must embed UnimplementedTestServiceServer
// for forward compatibility
type TestServiceServer interface {
Call(context.Context, *CallReq) (*CallRsp, error)
mustEmbedUnimplementedTestServiceServer()
}
// UnimplementedTestServiceServer must be embedded to have forward compatible implementations.
type UnimplementedTestServiceServer struct {
}
func (UnimplementedTestServiceServer) Call(context.Context, *CallReq) (*CallRsp, error) {
return nil, status.Errorf(codes.Unimplemented, "method Call 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_Call_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CallReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TestServiceServer).Call(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: TestService_Call_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TestServiceServer).Call(ctx, req.(*CallReq))
}
return interceptor(ctx, in, info, handler)
}
// 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: "test.TestService",
HandlerType: (*TestServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Call",
Handler: _TestService_Call_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "test.proto",
}

View File

@ -1,488 +1,21 @@
// +build ignore
/*
*
* Copyright 2016 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
Package reflection implements server reflection service.
The service implemented is defined in:
https://github.com/grpc/grpc/blob/master/src/proto/grpc/reflection/v1alpha/reflection.proto.
To register server reflection on a gRPC server:
import "google.golang.org/grpc/reflection"
s := grpc.NewServer()
pb.RegisterYourOwnServer(s, &server{})
// Register reflection service on gRPC server.
reflection.Register(s)
s.Serve(lis)
*/
package grpc package grpc
import ( import (
"bytes" "google.golang.org/grpc/reflection"
"compress/gzip" "google.golang.org/protobuf/reflect/protodesc"
"fmt"
"io"
"io/ioutil"
"reflect"
"sort"
"sync"
"github.com/golang/protobuf/proto"
dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
rpb "google.golang.org/grpc/reflection/grpc_reflection_v1alpha"
"google.golang.org/grpc/status"
) )
type serverReflectionServer struct { type Reflector interface {
rpb.UnimplementedServerReflectionServer protodesc.Resolver
s *grpc.Server reflection.ServiceInfoProvider
reflection.ExtensionResolver
initSymbols sync.Once
serviceNames []string
symbols map[string]*dpb.FileDescriptorProto // map of fully-qualified names to files
} }
// Register registers the server reflection service on the given gRPC server. const (
func Register(s *grpc.Server) { // ReflectV1ServiceName is the fully-qualified name of the v1 version of the reflection service.
rpb.RegisterServerReflectionServer(s, &serverReflectionServer{ ReflectV1ServiceName = "grpc.reflection.v1.ServerReflection"
s: s, // ReflectServiceURLPathV1 is the full path for reflection service endpoint
}) ReflectServiceURLPathV1 = "/" + ReflectV1ServiceName + "/"
} // ReflectMethodName is the reflection service name
ReflectMethodName = "ServerReflectionInfo"
// protoMessage is used for type assertion on proto messages. )
// Generated proto message implements function Descriptor(), but Descriptor()
// is not part of interface proto.Message. This interface is needed to
// call Descriptor().
type protoMessage interface {
Descriptor() ([]byte, []int)
}
func (s *serverReflectionServer) getSymbols() (svcNames []string, symbolIndex map[string]*dpb.FileDescriptorProto) {
s.initSymbols.Do(func() {
serviceInfo := s.s.GetServiceInfo()
s.symbols = map[string]*dpb.FileDescriptorProto{}
s.serviceNames = make([]string, 0, len(serviceInfo))
processed := map[string]struct{}{}
for svc, info := range serviceInfo {
s.serviceNames = append(s.serviceNames, svc)
fdenc, ok := parseMetadata(info.Metadata)
if !ok {
continue
}
fd, err := decodeFileDesc(fdenc)
if err != nil {
continue
}
s.processFile(fd, processed)
}
sort.Strings(s.serviceNames)
})
return s.serviceNames, s.symbols
}
func (s *serverReflectionServer) processFile(fd *dpb.FileDescriptorProto, processed map[string]struct{}) {
filename := fd.GetName()
if _, ok := processed[filename]; ok {
return
}
processed[filename] = struct{}{}
prefix := fd.GetPackage()
for _, msg := range fd.MessageType {
s.processMessage(fd, prefix, msg)
}
for _, en := range fd.EnumType {
s.processEnum(fd, prefix, en)
}
for _, ext := range fd.Extension {
s.processField(fd, prefix, ext)
}
for _, svc := range fd.Service {
svcName := fqn(prefix, svc.GetName())
s.symbols[svcName] = fd
for _, meth := range svc.Method {
name := fqn(svcName, meth.GetName())
s.symbols[name] = fd
}
}
for _, dep := range fd.Dependency {
fdenc := proto.FileDescriptor(dep)
fdDep, err := decodeFileDesc(fdenc)
if err != nil {
continue
}
s.processFile(fdDep, processed)
}
}
func (s *serverReflectionServer) processMessage(fd *dpb.FileDescriptorProto, prefix string, msg *dpb.DescriptorProto) {
msgName := fqn(prefix, msg.GetName())
s.symbols[msgName] = fd
for _, nested := range msg.NestedType {
s.processMessage(fd, msgName, nested)
}
for _, en := range msg.EnumType {
s.processEnum(fd, msgName, en)
}
for _, ext := range msg.Extension {
s.processField(fd, msgName, ext)
}
for _, fld := range msg.Field {
s.processField(fd, msgName, fld)
}
for _, oneof := range msg.OneofDecl {
oneofName := fqn(msgName, oneof.GetName())
s.symbols[oneofName] = fd
}
}
func (s *serverReflectionServer) processEnum(fd *dpb.FileDescriptorProto, prefix string, en *dpb.EnumDescriptorProto) {
enName := fqn(prefix, en.GetName())
s.symbols[enName] = fd
for _, val := range en.Value {
valName := fqn(enName, val.GetName())
s.symbols[valName] = fd
}
}
func (s *serverReflectionServer) processField(fd *dpb.FileDescriptorProto, prefix string, fld *dpb.FieldDescriptorProto) {
fldName := fqn(prefix, fld.GetName())
s.symbols[fldName] = fd
}
func fqn(prefix, name string) string {
if prefix == "" {
return name
}
return prefix + "." + name
}
// fileDescForType gets the file descriptor for the given type.
// The given type should be a proto message.
func (s *serverReflectionServer) fileDescForType(st reflect.Type) (*dpb.FileDescriptorProto, error) {
m, ok := reflect.Zero(reflect.PtrTo(st)).Interface().(protoMessage)
if !ok {
return nil, fmt.Errorf("failed to create message from type: %v", st)
}
enc, _ := m.Descriptor()
return decodeFileDesc(enc)
}
// decodeFileDesc does decompression and unmarshalling on the given
// file descriptor byte slice.
func decodeFileDesc(enc []byte) (*dpb.FileDescriptorProto, error) {
raw, err := decompress(enc)
if err != nil {
return nil, fmt.Errorf("failed to decompress enc: %v", err)
}
fd := new(dpb.FileDescriptorProto)
if err := proto.Unmarshal(raw, fd); err != nil {
return nil, fmt.Errorf("bad descriptor: %v", err)
}
return fd, nil
}
// decompress does gzip decompression.
func decompress(b []byte) ([]byte, error) {
r, err := gzip.NewReader(bytes.NewReader(b))
if err != nil {
return nil, fmt.Errorf("bad gzipped descriptor: %v", err)
}
out, err := ioutil.ReadAll(r)
if err != nil {
return nil, fmt.Errorf("bad gzipped descriptor: %v", err)
}
return out, nil
}
func typeForName(name string) (reflect.Type, error) {
pt := proto.MessageType(name)
if pt == nil {
return nil, fmt.Errorf("unknown type: %q", name)
}
st := pt.Elem()
return st, nil
}
func fileDescContainingExtension(st reflect.Type, ext int32) (*dpb.FileDescriptorProto, error) {
m, ok := reflect.Zero(reflect.PtrTo(st)).Interface().(proto.Message)
if !ok {
return nil, fmt.Errorf("failed to create message from type: %v", st)
}
var extDesc *proto.ExtensionDesc
for id, desc := range proto.RegisteredExtensions(m) {
if id == ext {
extDesc = desc
break
}
}
if extDesc == nil {
return nil, fmt.Errorf("failed to find registered extension for extension number %v", ext)
}
return decodeFileDesc(proto.FileDescriptor(extDesc.Filename))
}
func (s *serverReflectionServer) allExtensionNumbersForType(st reflect.Type) ([]int32, error) {
m, ok := reflect.Zero(reflect.PtrTo(st)).Interface().(proto.Message)
if !ok {
return nil, fmt.Errorf("failed to create message from type: %v", st)
}
exts := proto.RegisteredExtensions(m)
out := make([]int32, 0, len(exts))
for id := range exts {
out = append(out, id)
}
return out, nil
}
// fileDescWithDependencies returns a slice of serialized fileDescriptors in
// wire format ([]byte). The fileDescriptors will include fd and all the
// transitive dependencies of fd with names not in sentFileDescriptors.
func fileDescWithDependencies(fd *dpb.FileDescriptorProto, sentFileDescriptors map[string]bool) ([][]byte, error) {
r := [][]byte{}
queue := []*dpb.FileDescriptorProto{fd}
for len(queue) > 0 {
currentfd := queue[0]
queue = queue[1:]
if sent := sentFileDescriptors[currentfd.GetName()]; len(r) == 0 || !sent {
sentFileDescriptors[currentfd.GetName()] = true
currentfdEncoded, err := proto.Marshal(currentfd)
if err != nil {
return nil, err
}
r = append(r, currentfdEncoded)
}
for _, dep := range currentfd.Dependency {
fdenc := proto.FileDescriptor(dep)
fdDep, err := decodeFileDesc(fdenc)
if err != nil {
continue
}
queue = append(queue, fdDep)
}
}
return r, nil
}
// fileDescEncodingByFilename finds the file descriptor for given filename,
// finds all of its previously unsent transitive dependencies, does marshalling
// on them, and returns the marshalled result.
func (s *serverReflectionServer) fileDescEncodingByFilename(name string, sentFileDescriptors map[string]bool) ([][]byte, error) {
enc := proto.FileDescriptor(name)
if enc == nil {
return nil, fmt.Errorf("unknown file: %v", name)
}
fd, err := decodeFileDesc(enc)
if err != nil {
return nil, err
}
return fileDescWithDependencies(fd, sentFileDescriptors)
}
// parseMetadata finds the file descriptor bytes specified meta.
// For SupportPackageIsVersion4, m is the name of the proto file, we
// call proto.FileDescriptor to get the byte slice.
// For SupportPackageIsVersion3, m is a byte slice itself.
func parseMetadata(meta interface{}) ([]byte, bool) {
// Check if meta is the file name.
if fileNameForMeta, ok := meta.(string); ok {
return proto.FileDescriptor(fileNameForMeta), true
}
// Check if meta is the byte slice.
if enc, ok := meta.([]byte); ok {
return enc, true
}
return nil, false
}
// fileDescEncodingContainingSymbol finds the file descriptor containing the
// given symbol, finds all of its previously unsent transitive dependencies,
// does marshalling on them, and returns the marshalled result. The given symbol
// can be a type, a service or a method.
func (s *serverReflectionServer) fileDescEncodingContainingSymbol(name string, sentFileDescriptors map[string]bool) ([][]byte, error) {
_, symbols := s.getSymbols()
fd := symbols[name]
if fd == nil {
// Check if it's a type name that was not present in the
// transitive dependencies of the registered services.
if st, err := typeForName(name); err == nil {
fd, err = s.fileDescForType(st)
if err != nil {
return nil, err
}
}
}
if fd == nil {
return nil, fmt.Errorf("unknown symbol: %v", name)
}
return fileDescWithDependencies(fd, sentFileDescriptors)
}
// fileDescEncodingContainingExtension finds the file descriptor containing
// given extension, finds all of its previously unsent transitive dependencies,
// does marshalling on them, and returns the marshalled result.
func (s *serverReflectionServer) fileDescEncodingContainingExtension(typeName string, extNum int32, sentFileDescriptors map[string]bool) ([][]byte, error) {
st, err := typeForName(typeName)
if err != nil {
return nil, err
}
fd, err := fileDescContainingExtension(st, extNum)
if err != nil {
return nil, err
}
return fileDescWithDependencies(fd, sentFileDescriptors)
}
// allExtensionNumbersForTypeName returns all extension numbers for the given type.
func (s *serverReflectionServer) allExtensionNumbersForTypeName(name string) ([]int32, error) {
st, err := typeForName(name)
if err != nil {
return nil, err
}
extNums, err := s.allExtensionNumbersForType(st)
if err != nil {
return nil, err
}
return extNums, nil
}
// ServerReflectionInfo is the reflection service handler.
func (s *serverReflectionServer) ServerReflectionInfo(stream rpb.ServerReflection_ServerReflectionInfoServer) error {
sentFileDescriptors := make(map[string]bool)
for {
in, err := stream.Recv()
if err == io.EOF {
return nil
}
if err != nil {
return err
}
out := &rpb.ServerReflectionResponse{
ValidHost: in.Host,
OriginalRequest: in,
}
switch req := in.MessageRequest.(type) {
case *rpb.ServerReflectionRequest_FileByFilename:
b, err := s.fileDescEncodingByFilename(req.FileByFilename, sentFileDescriptors)
if err != nil {
out.MessageResponse = &rpb.ServerReflectionResponse_ErrorResponse{
ErrorResponse: &rpb.ErrorResponse{
ErrorCode: int32(codes.NotFound),
ErrorMessage: err.Error(),
},
}
} else {
out.MessageResponse = &rpb.ServerReflectionResponse_FileDescriptorResponse{
FileDescriptorResponse: &rpb.FileDescriptorResponse{FileDescriptorProto: b},
}
}
case *rpb.ServerReflectionRequest_FileContainingSymbol:
b, err := s.fileDescEncodingContainingSymbol(req.FileContainingSymbol, sentFileDescriptors)
if err != nil {
out.MessageResponse = &rpb.ServerReflectionResponse_ErrorResponse{
ErrorResponse: &rpb.ErrorResponse{
ErrorCode: int32(codes.NotFound),
ErrorMessage: err.Error(),
},
}
} else {
out.MessageResponse = &rpb.ServerReflectionResponse_FileDescriptorResponse{
FileDescriptorResponse: &rpb.FileDescriptorResponse{FileDescriptorProto: b},
}
}
case *rpb.ServerReflectionRequest_FileContainingExtension:
typeName := req.FileContainingExtension.ContainingType
extNum := req.FileContainingExtension.ExtensionNumber
b, err := s.fileDescEncodingContainingExtension(typeName, extNum, sentFileDescriptors)
if err != nil {
out.MessageResponse = &rpb.ServerReflectionResponse_ErrorResponse{
ErrorResponse: &rpb.ErrorResponse{
ErrorCode: int32(codes.NotFound),
ErrorMessage: err.Error(),
},
}
} else {
out.MessageResponse = &rpb.ServerReflectionResponse_FileDescriptorResponse{
FileDescriptorResponse: &rpb.FileDescriptorResponse{FileDescriptorProto: b},
}
}
case *rpb.ServerReflectionRequest_AllExtensionNumbersOfType:
extNums, err := s.allExtensionNumbersForTypeName(req.AllExtensionNumbersOfType)
if err != nil {
out.MessageResponse = &rpb.ServerReflectionResponse_ErrorResponse{
ErrorResponse: &rpb.ErrorResponse{
ErrorCode: int32(codes.NotFound),
ErrorMessage: err.Error(),
},
}
} else {
out.MessageResponse = &rpb.ServerReflectionResponse_AllExtensionNumbersResponse{
AllExtensionNumbersResponse: &rpb.ExtensionNumberResponse{
BaseTypeName: req.AllExtensionNumbersOfType,
ExtensionNumber: extNums,
},
}
}
case *rpb.ServerReflectionRequest_ListServices:
svcNames, _ := s.getSymbols()
serviceResponses := make([]*rpb.ServiceResponse, len(svcNames))
for i, n := range svcNames {
serviceResponses[i] = &rpb.ServiceResponse{
Name: n,
}
}
out.MessageResponse = &rpb.ServerReflectionResponse_ListServicesResponse{
ListServicesResponse: &rpb.ListServiceResponse{
Service: serviceResponses,
},
}
default:
return status.Errorf(codes.InvalidArgument, "invalid MessageRequest: %v", in.MessageRequest)
}
if err := stream.Send(out); err != nil {
return err
}
}
}

489
reflection_old.go Normal file
View File

@ -0,0 +1,489 @@
//go:build ignore
// +build ignore
/*
*
* Copyright 2016 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
Package reflection implements server reflection service.
The service implemented is defined in:
https://github.com/grpc/grpc/blob/master/src/proto/grpc/reflection/v1alpha/reflection.proto.
To register server reflection on a gRPC server:
import "google.golang.org/grpc/reflection"
s := grpc.NewServer()
pb.RegisterYourOwnServer(s, &server{})
// Register reflection service on gRPC server.
reflection.Register(s)
s.Serve(lis)
*/
package grpc
import (
"bytes"
"compress/gzip"
"fmt"
"io"
"io/ioutil"
"reflect"
"sort"
"sync"
"github.com/golang/protobuf/proto"
dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
rpb "google.golang.org/grpc/reflection/grpc_reflection_v1alpha"
"google.golang.org/grpc/status"
)
type serverReflectionServer struct {
rpb.UnimplementedServerReflectionServer
s *grpc.Server
initSymbols sync.Once
serviceNames []string
symbols map[string]*dpb.FileDescriptorProto // map of fully-qualified names to files
}
// Register registers the server reflection service on the given gRPC server.
func Register(s *grpc.Server) {
rpb.RegisterServerReflectionServer(s, &serverReflectionServer{
s: s,
})
}
// protoMessage is used for type assertion on proto messages.
// Generated proto message implements function Descriptor(), but Descriptor()
// is not part of interface proto.Message. This interface is needed to
// call Descriptor().
type protoMessage interface {
Descriptor() ([]byte, []int)
}
func (s *serverReflectionServer) getSymbols() (svcNames []string, symbolIndex map[string]*dpb.FileDescriptorProto) {
s.initSymbols.Do(func() {
serviceInfo := s.s.GetServiceInfo()
s.symbols = map[string]*dpb.FileDescriptorProto{}
s.serviceNames = make([]string, 0, len(serviceInfo))
processed := map[string]struct{}{}
for svc, info := range serviceInfo {
s.serviceNames = append(s.serviceNames, svc)
fdenc, ok := parseMetadata(info.Metadata)
if !ok {
continue
}
fd, err := decodeFileDesc(fdenc)
if err != nil {
continue
}
s.processFile(fd, processed)
}
sort.Strings(s.serviceNames)
})
return s.serviceNames, s.symbols
}
func (s *serverReflectionServer) processFile(fd *dpb.FileDescriptorProto, processed map[string]struct{}) {
filename := fd.GetName()
if _, ok := processed[filename]; ok {
return
}
processed[filename] = struct{}{}
prefix := fd.GetPackage()
for _, msg := range fd.MessageType {
s.processMessage(fd, prefix, msg)
}
for _, en := range fd.EnumType {
s.processEnum(fd, prefix, en)
}
for _, ext := range fd.Extension {
s.processField(fd, prefix, ext)
}
for _, svc := range fd.Service {
svcName := fqn(prefix, svc.GetName())
s.symbols[svcName] = fd
for _, meth := range svc.Method {
name := fqn(svcName, meth.GetName())
s.symbols[name] = fd
}
}
for _, dep := range fd.Dependency {
fdenc := proto.FileDescriptor(dep)
fdDep, err := decodeFileDesc(fdenc)
if err != nil {
continue
}
s.processFile(fdDep, processed)
}
}
func (s *serverReflectionServer) processMessage(fd *dpb.FileDescriptorProto, prefix string, msg *dpb.DescriptorProto) {
msgName := fqn(prefix, msg.GetName())
s.symbols[msgName] = fd
for _, nested := range msg.NestedType {
s.processMessage(fd, msgName, nested)
}
for _, en := range msg.EnumType {
s.processEnum(fd, msgName, en)
}
for _, ext := range msg.Extension {
s.processField(fd, msgName, ext)
}
for _, fld := range msg.Field {
s.processField(fd, msgName, fld)
}
for _, oneof := range msg.OneofDecl {
oneofName := fqn(msgName, oneof.GetName())
s.symbols[oneofName] = fd
}
}
func (s *serverReflectionServer) processEnum(fd *dpb.FileDescriptorProto, prefix string, en *dpb.EnumDescriptorProto) {
enName := fqn(prefix, en.GetName())
s.symbols[enName] = fd
for _, val := range en.Value {
valName := fqn(enName, val.GetName())
s.symbols[valName] = fd
}
}
func (s *serverReflectionServer) processField(fd *dpb.FileDescriptorProto, prefix string, fld *dpb.FieldDescriptorProto) {
fldName := fqn(prefix, fld.GetName())
s.symbols[fldName] = fd
}
func fqn(prefix, name string) string {
if prefix == "" {
return name
}
return prefix + "." + name
}
// fileDescForType gets the file descriptor for the given type.
// The given type should be a proto message.
func (s *serverReflectionServer) fileDescForType(st reflect.Type) (*dpb.FileDescriptorProto, error) {
m, ok := reflect.Zero(reflect.PtrTo(st)).Interface().(protoMessage)
if !ok {
return nil, fmt.Errorf("failed to create message from type: %v", st)
}
enc, _ := m.Descriptor()
return decodeFileDesc(enc)
}
// decodeFileDesc does decompression and unmarshalling on the given
// file descriptor byte slice.
func decodeFileDesc(enc []byte) (*dpb.FileDescriptorProto, error) {
raw, err := decompress(enc)
if err != nil {
return nil, fmt.Errorf("failed to decompress enc: %v", err)
}
fd := new(dpb.FileDescriptorProto)
if err := proto.Unmarshal(raw, fd); err != nil {
return nil, fmt.Errorf("bad descriptor: %v", err)
}
return fd, nil
}
// decompress does gzip decompression.
func decompress(b []byte) ([]byte, error) {
r, err := gzip.NewReader(bytes.NewReader(b))
if err != nil {
return nil, fmt.Errorf("bad gzipped descriptor: %v", err)
}
out, err := ioutil.ReadAll(r)
if err != nil {
return nil, fmt.Errorf("bad gzipped descriptor: %v", err)
}
return out, nil
}
func typeForName(name string) (reflect.Type, error) {
pt := proto.MessageType(name)
if pt == nil {
return nil, fmt.Errorf("unknown type: %q", name)
}
st := pt.Elem()
return st, nil
}
func fileDescContainingExtension(st reflect.Type, ext int32) (*dpb.FileDescriptorProto, error) {
m, ok := reflect.Zero(reflect.PtrTo(st)).Interface().(proto.Message)
if !ok {
return nil, fmt.Errorf("failed to create message from type: %v", st)
}
var extDesc *proto.ExtensionDesc
for id, desc := range proto.RegisteredExtensions(m) {
if id == ext {
extDesc = desc
break
}
}
if extDesc == nil {
return nil, fmt.Errorf("failed to find registered extension for extension number %v", ext)
}
return decodeFileDesc(proto.FileDescriptor(extDesc.Filename))
}
func (s *serverReflectionServer) allExtensionNumbersForType(st reflect.Type) ([]int32, error) {
m, ok := reflect.Zero(reflect.PtrTo(st)).Interface().(proto.Message)
if !ok {
return nil, fmt.Errorf("failed to create message from type: %v", st)
}
exts := proto.RegisteredExtensions(m)
out := make([]int32, 0, len(exts))
for id := range exts {
out = append(out, id)
}
return out, nil
}
// fileDescWithDependencies returns a slice of serialized fileDescriptors in
// wire format ([]byte). The fileDescriptors will include fd and all the
// transitive dependencies of fd with names not in sentFileDescriptors.
func fileDescWithDependencies(fd *dpb.FileDescriptorProto, sentFileDescriptors map[string]bool) ([][]byte, error) {
r := [][]byte{}
queue := []*dpb.FileDescriptorProto{fd}
for len(queue) > 0 {
currentfd := queue[0]
queue = queue[1:]
if sent := sentFileDescriptors[currentfd.GetName()]; len(r) == 0 || !sent {
sentFileDescriptors[currentfd.GetName()] = true
currentfdEncoded, err := proto.Marshal(currentfd)
if err != nil {
return nil, err
}
r = append(r, currentfdEncoded)
}
for _, dep := range currentfd.Dependency {
fdenc := proto.FileDescriptor(dep)
fdDep, err := decodeFileDesc(fdenc)
if err != nil {
continue
}
queue = append(queue, fdDep)
}
}
return r, nil
}
// fileDescEncodingByFilename finds the file descriptor for given filename,
// finds all of its previously unsent transitive dependencies, does marshalling
// on them, and returns the marshalled result.
func (s *serverReflectionServer) fileDescEncodingByFilename(name string, sentFileDescriptors map[string]bool) ([][]byte, error) {
enc := proto.FileDescriptor(name)
if enc == nil {
return nil, fmt.Errorf("unknown file: %v", name)
}
fd, err := decodeFileDesc(enc)
if err != nil {
return nil, err
}
return fileDescWithDependencies(fd, sentFileDescriptors)
}
// parseMetadata finds the file descriptor bytes specified meta.
// For SupportPackageIsVersion4, m is the name of the proto file, we
// call proto.FileDescriptor to get the byte slice.
// For SupportPackageIsVersion3, m is a byte slice itself.
func parseMetadata(meta interface{}) ([]byte, bool) {
// Check if meta is the file name.
if fileNameForMeta, ok := meta.(string); ok {
return proto.FileDescriptor(fileNameForMeta), true
}
// Check if meta is the byte slice.
if enc, ok := meta.([]byte); ok {
return enc, true
}
return nil, false
}
// fileDescEncodingContainingSymbol finds the file descriptor containing the
// given symbol, finds all of its previously unsent transitive dependencies,
// does marshalling on them, and returns the marshalled result. The given symbol
// can be a type, a service or a method.
func (s *serverReflectionServer) fileDescEncodingContainingSymbol(name string, sentFileDescriptors map[string]bool) ([][]byte, error) {
_, symbols := s.getSymbols()
fd := symbols[name]
if fd == nil {
// Check if it's a type name that was not present in the
// transitive dependencies of the registered services.
if st, err := typeForName(name); err == nil {
fd, err = s.fileDescForType(st)
if err != nil {
return nil, err
}
}
}
if fd == nil {
return nil, fmt.Errorf("unknown symbol: %v", name)
}
return fileDescWithDependencies(fd, sentFileDescriptors)
}
// fileDescEncodingContainingExtension finds the file descriptor containing
// given extension, finds all of its previously unsent transitive dependencies,
// does marshalling on them, and returns the marshalled result.
func (s *serverReflectionServer) fileDescEncodingContainingExtension(typeName string, extNum int32, sentFileDescriptors map[string]bool) ([][]byte, error) {
st, err := typeForName(typeName)
if err != nil {
return nil, err
}
fd, err := fileDescContainingExtension(st, extNum)
if err != nil {
return nil, err
}
return fileDescWithDependencies(fd, sentFileDescriptors)
}
// allExtensionNumbersForTypeName returns all extension numbers for the given type.
func (s *serverReflectionServer) allExtensionNumbersForTypeName(name string) ([]int32, error) {
st, err := typeForName(name)
if err != nil {
return nil, err
}
extNums, err := s.allExtensionNumbersForType(st)
if err != nil {
return nil, err
}
return extNums, nil
}
// ServerReflectionInfo is the reflection service handler.
func (s *serverReflectionServer) ServerReflectionInfo(stream rpb.ServerReflection_ServerReflectionInfoServer) error {
sentFileDescriptors := make(map[string]bool)
for {
in, err := stream.Recv()
if err == io.EOF {
return nil
}
if err != nil {
return err
}
out := &rpb.ServerReflectionResponse{
ValidHost: in.Host,
OriginalRequest: in,
}
switch req := in.MessageRequest.(type) {
case *rpb.ServerReflectionRequest_FileByFilename:
b, err := s.fileDescEncodingByFilename(req.FileByFilename, sentFileDescriptors)
if err != nil {
out.MessageResponse = &rpb.ServerReflectionResponse_ErrorResponse{
ErrorResponse: &rpb.ErrorResponse{
ErrorCode: int32(codes.NotFound),
ErrorMessage: err.Error(),
},
}
} else {
out.MessageResponse = &rpb.ServerReflectionResponse_FileDescriptorResponse{
FileDescriptorResponse: &rpb.FileDescriptorResponse{FileDescriptorProto: b},
}
}
case *rpb.ServerReflectionRequest_FileContainingSymbol:
b, err := s.fileDescEncodingContainingSymbol(req.FileContainingSymbol, sentFileDescriptors)
if err != nil {
out.MessageResponse = &rpb.ServerReflectionResponse_ErrorResponse{
ErrorResponse: &rpb.ErrorResponse{
ErrorCode: int32(codes.NotFound),
ErrorMessage: err.Error(),
},
}
} else {
out.MessageResponse = &rpb.ServerReflectionResponse_FileDescriptorResponse{
FileDescriptorResponse: &rpb.FileDescriptorResponse{FileDescriptorProto: b},
}
}
case *rpb.ServerReflectionRequest_FileContainingExtension:
typeName := req.FileContainingExtension.ContainingType
extNum := req.FileContainingExtension.ExtensionNumber
b, err := s.fileDescEncodingContainingExtension(typeName, extNum, sentFileDescriptors)
if err != nil {
out.MessageResponse = &rpb.ServerReflectionResponse_ErrorResponse{
ErrorResponse: &rpb.ErrorResponse{
ErrorCode: int32(codes.NotFound),
ErrorMessage: err.Error(),
},
}
} else {
out.MessageResponse = &rpb.ServerReflectionResponse_FileDescriptorResponse{
FileDescriptorResponse: &rpb.FileDescriptorResponse{FileDescriptorProto: b},
}
}
case *rpb.ServerReflectionRequest_AllExtensionNumbersOfType:
extNums, err := s.allExtensionNumbersForTypeName(req.AllExtensionNumbersOfType)
if err != nil {
out.MessageResponse = &rpb.ServerReflectionResponse_ErrorResponse{
ErrorResponse: &rpb.ErrorResponse{
ErrorCode: int32(codes.NotFound),
ErrorMessage: err.Error(),
},
}
} else {
out.MessageResponse = &rpb.ServerReflectionResponse_AllExtensionNumbersResponse{
AllExtensionNumbersResponse: &rpb.ExtensionNumberResponse{
BaseTypeName: req.AllExtensionNumbersOfType,
ExtensionNumber: extNums,
},
}
}
case *rpb.ServerReflectionRequest_ListServices:
svcNames, _ := s.getSymbols()
serviceResponses := make([]*rpb.ServiceResponse, len(svcNames))
for i, n := range svcNames {
serviceResponses[i] = &rpb.ServiceResponse{
Name: n,
}
}
out.MessageResponse = &rpb.ServerReflectionResponse_ListServicesResponse{
ListServicesResponse: &rpb.ListServiceResponse{
Service: serviceResponses,
},
}
default:
return status.Errorf(codes.InvalidArgument, "invalid MessageRequest: %v", in.MessageRequest)
}
if err := stream.Send(out); err != nil {
return err
}
}
}

62
reflection_test.go Normal file
View File

@ -0,0 +1,62 @@
package grpc
import (
"fmt"
"testing"
_ "go.unistack.org/micro-server-grpc/v3/proto"
"go.unistack.org/micro/v3/server"
"google.golang.org/grpc"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry"
)
type reflector struct{}
func (r *reflector) FindFileByPath(path string) (protoreflect.FileDescriptor, error) {
fd, err := protoregistry.GlobalFiles.FindFileByPath(path)
if err != nil {
fmt.Printf("err: %v\n", err)
return nil, err
}
return fd, nil
}
func (r *reflector) FindDescriptorByName(name protoreflect.FullName) (protoreflect.Descriptor, error) {
fd, err := protoregistry.GlobalFiles.FindDescriptorByName(name)
if err != nil {
return nil, err
}
return fd, nil
}
func (r *reflector) GetServiceInfo() map[string]grpc.ServiceInfo {
fmt.Printf("GetServiceInfo\n")
return nil
}
func (r *reflector) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) {
fmt.Printf("FindExtensionByName field %#+v\n", field)
return nil, nil
}
func (r *reflector) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) {
fmt.Printf("FindExtensionByNumber message %#+v field %#+v\n", message, field)
return nil, nil
}
func (r *reflector) RangeExtensionsByMessage(message protoreflect.FullName, f func(protoreflect.ExtensionType) bool) {
fmt.Printf("RangeExtensionsByMessage\n")
}
func TestReflector(t *testing.T) {
srv := NewServer(Reflection(&reflector{}), server.Address(":12345"))
if err := srv.Init(); err != nil {
t.Fatal(err)
}
if err := srv.Start(); err != nil {
t.Fatal(err)
}
t.Logf("addr %s", srv.Options().Address)
select {}
}

View File

@ -8,10 +8,7 @@ import (
"go.unistack.org/micro/v3/server" "go.unistack.org/micro/v3/server"
) )
var ( var _ server.Request = &rpcRequest{}
_ server.Request = &rpcRequest{}
_ server.Message = &rpcMessage{}
)
type rpcRequest struct { type rpcRequest struct {
rw io.ReadWriter rw io.ReadWriter
@ -22,19 +19,9 @@ type rpcRequest struct {
endpoint string endpoint string
contentType string contentType string
service string service string
body []byte
stream bool stream bool
} }
type rpcMessage struct {
payload interface{}
codec codec.Codec
header metadata.Metadata
topic string
contentType string
body []byte
}
func (r *rpcRequest) ContentType() string { func (r *rpcRequest) ContentType() string {
return r.contentType return r.contentType
} }
@ -60,11 +47,7 @@ func (r *rpcRequest) Header() metadata.Metadata {
} }
func (r *rpcRequest) Read() ([]byte, error) { func (r *rpcRequest) Read() ([]byte, error) {
f := &codec.Frame{} return nil, nil
if err := r.codec.ReadBody(r.rw, f); err != nil {
return nil, err
}
return f.Data, nil
} }
func (r *rpcRequest) Stream() bool { func (r *rpcRequest) Stream() bool {
@ -74,27 +57,3 @@ func (r *rpcRequest) Stream() bool {
func (r *rpcRequest) Body() interface{} { func (r *rpcRequest) Body() interface{} {
return r.payload return r.payload
} }
func (r *rpcMessage) ContentType() string {
return r.contentType
}
func (r *rpcMessage) Topic() string {
return r.topic
}
func (r *rpcMessage) Payload() interface{} {
return r.payload
}
func (r *rpcMessage) Header() metadata.Metadata {
return r.header
}
func (r *rpcMessage) Body() []byte {
return r.body
}
func (r *rpcMessage) Codec() codec.Codec {
return r.codec
}

View File

@ -27,8 +27,5 @@ func (r *rpcResponse) WriteHeader(hdr metadata.Metadata) {
} }
func (r *rpcResponse) Write(b []byte) error { func (r *rpcResponse) Write(b []byte) error {
return r.codec.Write(r.rw, &codec.Message{ return nil
Header: r.header,
Body: b,
}, nil)
} }

View File

@ -4,17 +4,47 @@ import (
"context" "context"
"fmt" "fmt"
"reflect" "reflect"
"runtime/debug"
"strings" "strings"
"go.unistack.org/micro/v3/broker" "go.unistack.org/micro/v3/broker"
"go.unistack.org/micro/v3/errors" "go.unistack.org/micro/v3/codec"
"go.unistack.org/micro/v3/logger" "go.unistack.org/micro/v3/logger"
"go.unistack.org/micro/v3/metadata" "go.unistack.org/micro/v3/metadata"
"go.unistack.org/micro/v3/options"
"go.unistack.org/micro/v3/register" "go.unistack.org/micro/v3/register"
"go.unistack.org/micro/v3/server" "go.unistack.org/micro/v3/server"
) )
var _ server.Message = &rpcMessage{}
type rpcMessage struct {
payload interface{}
codec codec.Codec
header metadata.Metadata
topic string
contentType string
}
func (r *rpcMessage) ContentType() string {
return r.contentType
}
func (r *rpcMessage) Topic() string {
return r.topic
}
func (r *rpcMessage) Body() interface{} {
return r.payload
}
func (r *rpcMessage) Header() metadata.Metadata {
return r.header
}
func (r *rpcMessage) Codec() codec.Codec {
return r.codec
}
type handler struct { type handler struct {
reqType reflect.Type reqType reflect.Type
ctxType reflect.Type ctxType reflect.Type
@ -102,18 +132,8 @@ func newSubscriber(topic string, sub interface{}, opts ...server.SubscriberOptio
} }
} }
func (g *grpcServer) createSubHandler(sb *subscriber, opts server.Options) broker.Handler { func (g *Server) createSubHandler(sb *subscriber, opts server.Options) broker.Handler {
return func(p broker.Event) (err error) { return func(p broker.Event) (err error) {
defer func() {
if r := recover(); r != nil {
if g.opts.Logger.V(logger.ErrorLevel) {
g.opts.Logger.Error(g.opts.Context, "panic recovered: ", r)
g.opts.Logger.Error(g.opts.Context, string(debug.Stack()))
}
err = errors.InternalServerError(g.opts.Name+".subscriber", "panic recovered: %v", r)
}
}()
msg := p.Message() msg := p.Message()
// if we don't have headers, create empty map // if we don't have headers, create empty map
if msg.Header == nil { if msg.Header == nil {
@ -122,8 +142,8 @@ func (g *grpcServer) createSubHandler(sb *subscriber, opts server.Options) broke
ct := msg.Header["Content-Type"] ct := msg.Header["Content-Type"]
if len(ct) == 0 { if len(ct) == 0 {
msg.Header["Content-Type"] = defaultContentType msg.Header["Content-Type"] = DefaultContentType
ct = defaultContentType ct = DefaultContentType
} }
cf, err := g.newCodec(ct) cf, err := g.newCodec(ct)
if err != nil { if err != nil {
@ -132,9 +152,6 @@ func (g *grpcServer) createSubHandler(sb *subscriber, opts server.Options) broke
hdr := make(map[string]string, len(msg.Header)) hdr := make(map[string]string, len(msg.Header))
for k, v := range msg.Header { for k, v := range msg.Header {
if k == "Content-Type" {
continue
}
hdr[k] = v hdr[k] = v
} }
@ -171,7 +188,7 @@ func (g *grpcServer) createSubHandler(sb *subscriber, opts server.Options) broke
vals = append(vals, reflect.ValueOf(ctx)) vals = append(vals, reflect.ValueOf(ctx))
} }
vals = append(vals, reflect.ValueOf(msg.Payload())) vals = append(vals, reflect.ValueOf(msg.Body()))
returnValues := handler.method.Call(vals) returnValues := handler.method.Call(vals)
if rerr := returnValues[0].Interface(); rerr != nil { if rerr := returnValues[0].Interface(); rerr != nil {
@ -180,9 +197,11 @@ func (g *grpcServer) createSubHandler(sb *subscriber, opts server.Options) broke
return nil return nil
} }
for i := len(opts.SubWrappers); i > 0; i-- { opts.Hooks.EachNext(func(hook options.Hook) {
fn = opts.SubWrappers[i-1](fn) if h, ok := hook.(server.HookSubHandler); ok {
} fn = h(fn)
}
})
if g.wg != nil { if g.wg != nil {
g.wg.Add(1) g.wg.Add(1)
@ -196,7 +215,6 @@ func (g *grpcServer) createSubHandler(sb *subscriber, opts server.Options) broke
contentType: ct, contentType: ct,
payload: req.Interface(), payload: req.Interface(),
header: msg.Header, header: msg.Header,
body: msg.Body,
}) })
results <- cerr results <- cerr
}() }()
@ -230,3 +248,38 @@ func (s *subscriber) Endpoints() []*register.Endpoint {
func (s *subscriber) Options() server.SubscriberOptions { func (s *subscriber) Options() server.SubscriberOptions {
return s.opts return s.opts
} }
func (g *Server) subscribe() error {
config := g.opts
subCtx := config.Context
for sb := range g.subscribers {
if cx := sb.Options().Context; cx != nil {
subCtx = cx
}
opts := []broker.SubscribeOption{
broker.SubscribeContext(subCtx),
broker.SubscribeAutoAck(sb.Options().AutoAck),
broker.SubscribeBodyOnly(sb.Options().BodyOnly),
}
if queue := sb.Options().Queue; len(queue) > 0 {
opts = append(opts, broker.SubscribeGroup(queue))
}
if config.Logger.V(logger.InfoLevel) {
config.Logger.Info(config.Context, "subscribing to topic: "+sb.Topic())
}
sub, err := config.Broker.Subscribe(subCtx, sb.Topic(), g.createSubHandler(sb, config), opts...)
if err != nil {
return err
}
g.subscribers[sb] = []broker.Subscriber{sub}
}
return nil
}

View File

@ -26,6 +26,7 @@ func TestServiceMethod(t *testing.T) {
if err != nil && test.err == true { if err != nil && test.err == true {
continue continue
} }
t.Logf("input %s service %s method %s", test.input, service, method)
// unexpected error // unexpected error
if err != nil && test.err == false { if err != nil && test.err == false {
t.Fatalf("unexpected err %v for %+v", err, test) t.Fatalf("unexpected err %v for %+v", err, test)