Compare commits

..

121 Commits

Author SHA1 Message Date
Johnson C b884a68347 feat: update out of date docs (#2520)
Run tests / Test repo (push) Waiting to run
* feat: redis implementation of cache

* Revert "feat: redis implementation of cache"

This reverts commit 4b3f25c1fc494d934613992d8a762024fafad7b6.

* feat: update out of date docs
2022-07-02 08:44:32 +01:00
Asim Aslam bfcdfc3c7f remove m3o
Run tests / Test repo (push) Waiting to run
2022-07-01 11:37:13 +01:00
Asim Aslam 392610022a Update README.md 2022-07-01 08:38:57 +01:00
Asim Aslam 34a51c9f29 Update README.md 2022-07-01 08:34:20 +01:00
Asim Aslam a5fb3fab66 Update README.md 2022-07-01 08:33:53 +01:00
JellyTony 96576a612a feat(web): add start and stop functions to the web (#2519) 2022-07-01 08:06:27 +01:00
Thomas Chandelle 87c96bc4d0 Correctly check error on redis command XTRIM (#2518)
Also:
 - add comment about version requirement
 - move minID to var for code readability
2022-06-30 18:24:27 +08:00
JellyTony 65a2e4ed02 fix(registry): fix watch services only first time (#2517) 2022-06-29 08:49:22 +01:00
Abdul Hadi 9960cd1d36 typo siza #2429 (#2515) 2022-06-24 19:18:47 +01:00
David Brouwer 107bd74187 fix: allow event subscribers to use pointers (#2514)
When a subscriber would use a pointer as event type, panics would occur.
2022-06-22 09:01:13 +08:00
Johnson C 7a6a2b6373 feat: redis implementation of cache (#2513)
* feat: redis implementation of cache

* Revert "feat: redis implementation of cache"

This reverts commit 4b3f25c1fc494d934613992d8a762024fafad7b6.

* feat: redis implementation of cache
2022-06-21 20:05:00 +01:00
Asim Aslam cf51ddeb26 Update README.md 2022-05-30 08:50:02 +01:00
Asim Aslam 13b76331ec Update README.md
Run tests / Test repo (push) Waiting to run
2022-05-11 09:55:41 +01:00
Asim Aslam de0b456b46 Update README.md 2022-05-10 06:59:08 +01:00
yulian 072547201c remove unused variable in loop (#2495) 2022-05-03 11:06:13 +08:00
bosima 8293988499 fix: consume and publish blocked after rabbitmq reconnecting (#2492)
* Support direct generation of grpc method when package and service names of proto files are different.

* fix req.Interface() return nil.

* Get rid of dependence on 'Micro-Topic'

* Revert "Get rid of dependence on 'Micro-Topic'"

This reverts commit 3ff69443364d39f5fda3a32fc2249826e2d207dd.

* Revert "fix req.Interface() return nil."

This reverts commit 90a1b34195e07772fa6f2074e1cf22237ac2a87f.

* Revert "Revert "fix req.Interface() return nil.""

This reverts commit e64737b7da8d1767c4456881f6730f1c196cea60.

* Revert "Revert "Get rid of dependence on 'Micro-Topic'""

This reverts commit 141bb0a557c81cb6d1c651b085b3e65483d5e681.

* fix: consume and publish blocked after reconnecting

Co-authored-by: maxinglun <maxinglun@zhijiaxing.net>
2022-04-28 17:55:06 +08:00
Asim Aslam 367771923c Update README.md 2022-04-19 15:47:45 +01:00
Asim Aslam 4ca75f3ab3 Update README.md 2022-04-19 15:47:31 +01:00
Asim Aslam 4a7c16419e Update README.md 2022-04-19 15:31:23 +01:00
Asim Aslam 1d396bdd64 Update README.md 2022-04-19 15:31:11 +01:00
Sergey Galkin ca807e36c5 option to disable file watcher (#2485)
Co-authored-by: Sergey Galkin <v.sergey.galkin@reddit.com>
2022-04-18 19:30:14 +01:00
Asim Aslam cce02927e7 Update README.md 2022-04-18 19:20:45 +01:00
Wang 034ba9a0de typo fix; (#2480) 2022-04-15 09:55:30 +08:00
bosima 1919048c8f Support direct generation of grpc method (#2474)
* Support direct generation of grpc method when package and service names of proto files are different.
* fix req.Interface() return nil.
2022-04-10 22:12:39 +08:00
Asim Aslam 62c2981baf remove cli 2022-04-07 11:46:07 +01:00
Asim Aslam efa2c4f2d2 remove dashboard 2022-04-07 11:45:58 +01:00
Asim Aslam 27b98c450e Remove examples 2022-04-07 11:45:39 +01:00
Asim Aslam e8604f065c remove services 2022-04-07 11:45:22 +01:00
Asim Aslam aaca7c27da Update README.md 2022-04-07 11:44:47 +01:00
Asim Aslam 664ee31b1a Update README.md 2022-04-07 08:20:57 +01:00
Wang 6dedee5d8c Add header suppor for Kafka broker plugin; (#2470) 2022-04-04 19:54:19 +01:00
Wang d1806e2883 Fix codec/bytes (#2466)
* Update marshaler.go

Byes codec always return error "invalid message" now.

* Update go.mod

Update package name

* Update go.mod
2022-04-02 18:11:12 +01:00
Morya 1f086a3002 fix https://github.com/asim/go-micro/issues/2344 (#2462)
fix https://github.com/asim/go-micro/issues/2344
2022-04-01 07:10:51 +01:00
Muhammad Iqbal Alaydrus 73eda3346d Add Wait option support for sync/etcd plugins (#2459)
* Add Wait support for sync/etcd plugins

* Use ErrLockTimeout if context deadline exceeded
2022-03-25 10:28:19 +08:00
Chris Moran c6d352c832 #2453 Fix with associated test update (#2454) 2022-03-17 10:22:05 +08:00
baerwang 356448017f style:arrays pre-allocation (#2449) 2022-03-14 14:03:14 +08:00
dependabot[bot] d6a74c1a8e Bump github.com/nats-io/nats-server/v2 in /plugins/events/natsjs (#2447)
Bumps [github.com/nats-io/nats-server/v2](https://github.com/nats-io/nats-server) from 2.6.2 to 2.7.4.
- [Release notes](https://github.com/nats-io/nats-server/releases)
- [Changelog](https://github.com/nats-io/nats-server/blob/main/.goreleaser.yml)
- [Commits](https://github.com/nats-io/nats-server/compare/v2.6.2...v2.7.4)

---
updated-dependencies:
- dependency-name: github.com/nats-io/nats-server/v2
  dependency-type: direct:production
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-14 12:02:12 +08:00
Willy Kloucek e5a35d38f9 fix natsjs syntax error, remove TODOs and enable tests (#2446) 2022-03-11 16:03:35 +08:00
Willy Kloucek a2f6fac852 add NATS JetStream events plugin (#2433)
* add NATS JetStream plugin

* add notes about de-duplication and inprogress call

* fix typo
2022-03-04 14:53:15 +00:00
Ak-Army dca3a3b553 [fix] http transport deadlock (#2441)
Co-authored-by: Hunyadvári Péter <peter.hunyadvari@vcc.live>
2022-02-24 09:32:09 +00:00
AlkaidChen 4154ed6a80 add tls option for sync etcd plugin (#2440) 2022-02-24 17:07:14 +08:00
Chris Moran 69b4b5d1c6 Support for -micro_out=module=<module_prefix> for protoc-gen-micro (#2435) 2022-02-23 13:14:50 +08:00
Asim Aslam d47c2d984b add new services 2022-02-16 08:43:36 +00:00
Asim Aslam 91cfd18373 Update README.md 2022-02-16 08:35:22 +00:00
Asim Aslam 9e0be6c85d add service updates (#2418)
Run tests / Test repo (push) Waiting to run
2022-01-18 15:27:36 +00:00
Asim Aslam 23f1de80c5 Update README.md 2022-01-17 13:35:01 +00:00
Asim Aslam 6bc97c16ee Update README.md 2022-01-17 13:34:30 +00:00
Asim Aslam a612e09a34 Add files via upload 2022-01-15 20:26:27 +00:00
Asim Aslam 1e2d197c7d default the content type to json (#2412) 2022-01-11 13:36:20 +00:00
Asim Aslam 3a999a0db6 Add files via upload 2022-01-11 12:07:54 +00:00
Asim Aslam b8c2eb2b28 Update README.md 2022-01-11 08:35:55 +00:00
Asim Aslam 6f15174a2f Update README.md 2022-01-11 08:35:16 +00:00
Asim Aslam 748fb39cac Add files via upload 2022-01-11 08:34:58 +00:00
simon 5f2251cfad Add Kafka asynchronous send support (#2409)
* Add Kafka asynchronous send support

* Add Kafka asynchronous send support

* Upgrade sarama to 1.30.1

* Example
2022-01-09 14:12:10 +00:00
Amir Khazaie ef7528ebdb use read lock and unlock instead of write ones (#2410)
Co-authored-by: Amir Khazaie <a.khazaie@digikala.com>
2022-01-09 10:20:08 +00:00
Asim Aslam 696a0ba714 Merge branch 'master' of ssh://github.com/asim/go-micro 2022-01-03 11:21:29 +00:00
Asim Aslam 267da35259 move the api client 2022-01-03 11:21:20 +00:00
Asim Aslam d152870bdb Update client_test.go 2021-12-31 12:39:12 +00:00
Asim Aslam da41ab146e switch services client 2021-12-31 10:11:49 +00:00
Asim Aslam 757d0fe343 fix client 2021-12-30 09:47:40 +00:00
Asim Aslam c8d94c44f0 remove the client 2021-12-30 09:42:08 +00:00
Asim Aslam 5fa6e89f4f fix go mod 2021-12-30 09:35:21 +00:00
Asim Aslam 85f1c44000 Delete go.sum 2021-12-30 08:58:45 +00:00
Asim Aslam 3ba69f11ff Delete go.mod 2021-12-30 08:58:34 +00:00
Asim Aslam af5e70a1d6 add service interfaces 2021-12-30 08:44:34 +00:00
Johnson C 5fe884e59f [FEATURE] add changelog (#2400)
change logs for release history
2021-12-29 11:01:40 +08:00
isfk 415016c6e4 nats config plugin (#2397) 2021-12-28 11:27:36 +08:00
Asim Aslam e0de23c546 Update and rename m3o.go to services.go 2021-12-24 11:43:20 +00:00
Asim Aslam 7af0eb4b7a Update services/ (#2392) 2021-12-21 13:18:29 +00:00
isfk 8e52761edb fix context value nil (#2391) 2021-12-20 16:31:48 +08:00
Johnson C 37de747d19 [fix] nats deregister issue (#2384)
Run tests / Test repo (push) Waiting to run
2021-12-10 19:32:21 +08:00
Johnson C a40f6e8fae [fix] fixing f.IsExported undefined issue (#2382)
IsExported needs go1.17, replace with PkgPath
2021-12-07 17:30:48 +08:00
Johnson C b00c8368b9 [feat] dashboard update (#2381)
* [feature] dashboard update
2021-12-07 10:42:31 +08:00
Ak-Army 97f169c424 fix http_transport Recv and Close race condition on buff (#2374)
fix rpc_stream panic override with the "Unlock of unlocked RWMutex" panic

Co-authored-by: Hunyadvári Péter <peter.hunyadvari@vcc.live>
2021-12-05 11:56:17 +00:00
Ak-Army 81244a41f1 Extend client mock with ability to test publish, and a few useful method like SetResponse and SetSubscriber (#2375)
Co-authored-by: Hunyadvári Péter <peter.hunyadvari@vcc.live>
2021-12-05 11:55:54 +00:00
JeffreyBool 229b369702 [fix] update protoc-gen-micro install doc 2021-12-04 12:52:02 +08:00
Johnson C c0e0b2b225 [FEATURE] dashboard support publish messages (#2373)
* [feature] dashboard

* [feat] support publish message
2021-12-02 13:15:38 +08:00
Johnson C 1e4dd94b71 [fix] zookeeper registry delete event (#2372)
* [fix] #2358 zookeeper delete event
2021-12-01 16:26:31 +08:00
zhaoyang b25d744f5c feat: delete redundant lines (#2364) 2021-11-24 17:41:54 +00:00
zhaoyang 685f9979a1 feat: modify the dependencies urls (#2363) 2021-11-24 16:43:05 +00:00
Asim Aslam 6fc5e45626 Update README.md 2021-11-24 07:32:51 +00:00
Asim Aslam 2c6515152a Update load.go 2021-11-24 07:32:20 +00:00
Johnson C 70d2bd8a6b [feature] dashboard (#2361) 2021-11-24 11:27:23 +08:00
Johnson C 90b3e4af0b [fix] ignore unexported field (#2354)
ignore unexported field when register endpoints
2021-11-18 17:07:00 +08:00
Niek den Breeje 4f1a571704 Fix Micro CLI's proto comments (#2353) 2021-11-18 06:10:43 +01:00
陈杨文 799b8d6a65 upgrade to go 1.17 (#2346)
Run tests / Test repo (push) Waiting to run
2021-11-11 14:03:34 +00:00
Asim Aslam 8e312801a1 Update README.md 2021-11-08 09:03:37 +00:00
Asim Aslam 335c4e54a1 Merge branch 'master' of ssh://github.com/asim/go-micro 2021-11-08 09:01:56 +00:00
Asim Aslam e6d17257b0 add nats and redis events plugins 2021-11-08 08:59:14 +00:00
Asim Aslam 0c2041e439 add events package (#2341)
* add events package

* update go version
2021-11-08 08:52:39 +00:00
Johnson C c5be9f560c fix(#2333): etcd grpc marshal issue (#2334)
make protocodec compatible with legacy proto message type
2021-11-03 10:58:05 +08:00
Asim Aslam 62b985f49c Update README.md 2021-11-01 21:44:52 +00:00
Asim Aslam 2b9a6f9aeb flatten cli (#2332)
Run tests / Test repo (push) Waiting to run
2021-11-01 14:34:09 +00:00
Asim Aslam 3c70d23a1d m3o client changed 2021-11-01 11:00:21 +00:00
Asim Aslam adaa98e6cf use vanity url for cli command 2021-11-01 09:00:14 +00:00
无相 ed90a65783 fix broker nsq plugin nil pointer error (#2329)
Co-authored-by: longhaoteng <longhaoteng@kingsoft.com>
2021-11-01 08:47:22 +00:00
无相 268278c53e fix config json slice parsing (#2330)
Co-authored-by: longhaoteng <longhaoteng@kingsoft.com>
2021-11-01 08:47:00 +00:00
Benjamin 5d5aee1f08 replace ioutil with io and os (#2327)
set the go version to 1.16 in pr.yml and tests.yml, so as to be consistent with the version in go.mod.
2021-10-30 19:24:40 +01:00
Johnson C ed690ed838 fixing #2308 (#2326)
IPV6 too many colons in address
net.SplitHostPort need ipv6 address in [host]:port format
2021-10-28 17:03:48 +08:00
Niek den Breeje e155029a4b Fix Micro CLI by removing replace line in go.mod 2021-10-27 17:40:26 +02:00
Asim Aslam 880d751df4 Update README.md 2021-10-27 16:34:55 +01:00
Niek den Breeje a3202b00ee Rename gomu to micro (#2325)
* Rename Gomu to Micro

* docs: Remove license reference in CLI's README
2021-10-27 16:31:29 +01:00
Asim Aslam efcda9a48c Update README.md 2021-10-26 20:17:07 +01:00
Asim Aslam 2c73c7fcf3 strip protoc-gen-micro go mod 2021-10-26 19:46:25 +01:00
Johnson C d2a51d05c4 [feature] stream CloseSend (#2323)
* support stream CloseSend

* move CloseSend into Closer
2021-10-26 15:07:08 +01:00
Johnson C af3cfa0a4c remove unnecessary dependencies between plugins
remove unnecessary dependencies between plugins
upgrade go-micro.dev/v4 to v4.2.1
2021-10-23 16:20:42 +08:00
Johnson C f96b48dad9 1. use default memory registry in grpc plugins (#2317)
2. try fixing grpc plugin failed to get issue
use v4.0.0-v4.0.0-00010101000000-000000000000 instead of specific version
3. kafka panic on disconnect
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x18 pc=0x1266c50]

goroutine 31 [running]:
github.com/asim/go-micro/plugins/broker/kafka/v3.(*kBroker).Disconnect(0xc0002400c0)
        C:/Workshop/Go/pkg/mod/github.com/asim/go-micro/plugins/broker/kafka/v3@v3.7.0/kafka.go:130 +0xd0
github.com/asim/go-micro/plugins/server/grpc/v3.(*grpcServer).Start.func2()
        C:/Workshop/Go/pkg/mod/github.com/asim/go-micro/plugins/server/grpc/v3@v3.0.0-20210712061837-0532fd9de8ae/grpc.go:998 +0xc8d
created by github.com/asim/go-micro/plugins/server/grpc/v3.(*grpcServer).Start
        C:/Workshop/Go/pkg/mod/github.com/asim/go-micro/plugins/server/grpc/v3@v3.0.0-20210712061837-0532fd9de8ae/grpc.go:917 +0xcaf
exit status 2
2021-10-22 22:30:28 +08:00
Niek den Breeje 9edc569e68 Add update rule to Makefile (#2315)
I realized that when writing `require go-micro.dev/v4 v4.1.0` in the
`go.mod` file, `go mod tidy` will install that exact version of
`go-micro.dev/v4`. As of right now, v4.1.0 is an outdated version, and
preferably we shouldn't be updating gomu's Go Modules template everytime
a new release is tagged, but still want gomu users to generate projects
using the latest Go Micro version.

In an attempt to solve this problem, I'm opting to add a new Makefile
rule for new projects generated by gomu, `update` that runs `go get -u`.
This aggressively updates any dependencies your Go Modules project may
have.  `go mod tidy` is then able to prune the `go.mod` and `go.sum`
files by removing the unnecessary checksums and transitive dependencies
(e.g. `// indirect`), that were added to by go get -u due to newer
semver available.

Put one and one together and you get two. In addition to adding an
`update` rule to the Makefile generated for new projects by gomu, I'm
also updating the proto and client comments printed when new projects
have been generated to promote the `update` rule.

References:

- https://stackoverflow.com/questions/67201708/go-update-all-modules
2021-10-19 21:12:42 +02:00
Johnson C 29fefbad4e Plugins (#2311)
* release plugins

* add window plugins release bat script

Co-authored-by: Johnson C <johnson.cheng@scenestek.com>
2021-10-16 05:56:51 +01:00
Asim Aslam 9f4770e7fd fix generation (#2312)
Run tests / Test repo (push) Waiting to run
2021-10-15 14:03:40 +01:00
Asim Aslam e7dbda689e fix gomu
Run tests / Test repo (push) Waiting to run
2021-10-14 08:09:21 +01:00
Asim Aslam 00f461141a fix examples go mod
Run tests / Test repo (push) Waiting to run
2021-10-13 13:37:24 +01:00
Asim Aslam 8cad88edae update go sums 2021-10-13 13:35:17 +01:00
Asim Aslam 62801c3d68 update 2021-10-13 13:31:23 +01:00
Asim Aslam 7136c61dbd rename to go-micro.dev 2021-10-13 09:52:05 +01:00
Asim Aslam a87f9a808c move to go-micro.dev 2021-10-13 09:44:24 +01:00
Asim Aslam ca594b922c Merge branch 'master' of ssh://github.com/asim/go-micro 2021-10-13 09:42:31 +01:00
Asim Aslam aa4a87ed9a move to v4 in protoc-gen-micro 2021-10-13 09:42:21 +01:00
justcy 690facdb5c update model template (#2307) 2021-10-13 08:07:48 +01:00
Asim Aslam f63e46a7d1 use 4.1.0 2021-10-12 13:22:08 +01:00
Asim Aslam 1cd7cfaa6c go-micro.dev/v4 (#2305)
Run tests / Test repo (push) Waiting to run
2021-10-12 12:55:53 +01:00
1021 changed files with 13687 additions and 17513 deletions
+2 -2
View File
@@ -8,10 +8,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.15
- name: Set up Go 1.17
uses: actions/setup-go@v1
with:
go-version: 1.15
go-version: 1.17
id: go
- name: Check out code into the Go module directory
+2 -2
View File
@@ -8,10 +8,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.15
- name: Set up Go 1.17
uses: actions/setup-go@v1
with:
go-version: 1.15
go-version: 1.17
id: go
- name: Check out code into the Go module directory
+774
View File
@@ -0,0 +1,774 @@
# 4.7.0 (2022/05/19)
### Features
- remove unused variable in loop (#2495)
- option to disable file watcher (#2485)
- Support direct generation of grpc method (#2474)
- remove cli
- remove dashboard
- Remove examples
- Add header suppor for Kafka broker plugin; (#2470)
- Fix codec/bytes (#2466)
- Add Wait option support for sync/etcd plugins (#2459)
- #2453 Fix with associated test update (#2454)
- style:arrays pre-allocation (#2449)
- Bump github.com/nats-io/nats-server/v2 in /plugins/events/natsjs (#2447)
- add NATS JetStream events plugin (#2433)
- add tls option for sync etcd plugin (#2440)
- add new services
### Bug Fixes
- fix: consume and publish blocked after rabbitmq reconnecting (#2492)
- typo fix; (#2480)
- fix https://github.com/asim/go-micro/issues/2344 (#2462)
- fix natsjs syntax error, remove TODOs and enable tests (#2446)
- http transport deadlock (#2441)
- Support for `-micro_out=module=<module_prefix>` for protoc-gen-micro (#2435)
# 4.6.0 (2022/02/08)
### Features
- add service updates (#2418)
- Add files via upload
- default the content type to json (#2412)
- Add Kafka asynchronous send support (#2409)
- use read lock and unlock instead of write ones (#2410)
- move the api client
- Update client_test.go
- switch services client
- remove the client
- add service interfaces
- [FEATURE] add changelog (#2400)
- nats config plugin (#2397)
- Update and rename m3o.go to services.go
- Update services/ (#2392)
### Bug Fixes
- fix client
- fix context value nil (#2391)
# 4.5.0 (2021/12/19)
### Bug Fixes
- nats deregister issue (#2384)
- fixing f.IsExported undefined issue (#2382)
- fix http_transport Recv and Close race condition on buff (#2374)
- update protoc-gen-micro install doc
- zookeeper registry delete event (#2372)
- delete redundant lines (#2364)
- modify the dependencies urls (#2363)
- ignore unexported field (#2354)
- Fix Micro CLI's proto comments (#2353)
### Features
- Extend client mock with ability to test publish, and a few useful method like SetResponse and SetSubscriber (#2375)
- go micro dashboard (#2361)
# 4.4.0 (2021/11/11)
### Bug Fixes
- fix(#2333): etcd grpc marshal issue (#2334)
### Features
- upgrade to go 1.17 (#2346)
- add nats and redis events plugins
- add events package (#2341)
# 4.3.0 (2021/11/01)
### Bug Fixes
- flatten cli (#2332)
- m3o client changed
- use vanity url for cli command
- fix broker nsq plugin nil pointer error (#2329)
- fix config json slice parsing (#2330)
- replace ioutil with io and os (#2327)
- fixing #2308 (#2326)
- Fix Micro CLI by removing replace line in go.mod
- remove unnecessary dependencies between plugins
- 1. use default memory registry in grpc plugins (#2317)
- Add update rule to Makefile (#2315)
- Plugins (#2311)
### Features
- Rename gomu to micro (#2325)
- stream CloseSend (#2323)
- strip protoc-gen-micro go mod
### BREAKING CHANGES
- go install go-micro.dev/v4/cmd/micro@v4
- go install go-micro.dev/v4/cmd/protoc-gen-micro@v4
- upgrade go micro to support stream.CloseSend
# 4.2.1 (2021/10/14)
### Bug Fixes
- fix gomu.
# 4.2.0 (2021/10/13)
### Bug Fixes
- fix examples go mod.
- update go sums.
- move to go-micro.dev.
- upgrade protoc-gen-micro to v4.
# 4.1.0 (2021/10/12)
- v4.1.0.
# 4.0.0 (2021/10/12)
### Features
- Vanity URL go-micro.dev([#2271](https://github.com/asim/go-micro/issues/2271)).
### BREAKING CHANGES
- upgrade github.com/asim/go-micro/v3 to go-micro.dev/v4.
# 3.7.0 (2021/10/11)
- Add latest version (#2303).
# 3.6.0 (2021/08/23)
- Minor fixes https://github.com/asim/go-micro/compare/v3.5.2...c7195aae9817db4eaf5483990fcb8706f86d3002.
# 3.5.2 (2021/07/06)
- Tag it and bag it.
# 3.5.1 (2021/04/20)
- Minor bug fixes.
# 3.5.0 (2021/01/29)
- kill the bugs.
# 3.0.1 (2021/01/20)
- Tag with protoc changes.
# 3.0.0 (2021/01/20)
- V3.
### BREAKING CHANGES
- upgrade github.com/micro/go-micro/v2 to github.com/asim/go-micro/v3.
- change default transport from gRPC to mucp, using grpc server/client plugins.
# 3.0.0-beta.3 (2020/09/29)
- Secret implementation of config. Supporting config merge (#2027)
- remove transport options
- read service package (#2026)
- env config implementation (#2024)
- runtime: remove builder package (moved to micro) (#2023)
- Fix branch names support for k8s runtime (#2020)
- fix config bug (#2021)
- runtime: minor fixes for local runtime (#2019)
- remove memcache and update gomod
- Add errors to config methods (#2015)
- store/file: fix segmentation violation bug (#2013)
- Config interface change (#2010)
- proxy/grpc: fix client streaming bug (EOF not sent to the server) (#2011)
- client/grpc: fix stream closed bug (#2009)
- store/file: don't keep connection to boltdb open (#2006)
- runtime/builder with golang implementation (#2003)
- store: implement s3 blob store (#2005)
- store: add blob interface with file implementation (#2004)
- auth: remove micro specific code (#1999)
- Fix running subfolders (#1998)
- api: fix request body re-sequencing bug (#1996)
- add Name to auth.Account as a user friendly alias (#1992)
- Fixing top level run outside repo (#1993)
- runtime: normalised service statuses (#1994)
- Add 'Namespace' header to allowed CORS headers (#1990)
- Remove all the external plugins except grpc (#1988)
- util/kubernetes: fix TCPSocketAction bug (#1987)
- Fixing the metric tagging issue here (#1986).
# 3.0.0-beta.2 (2020/09/05)
- Cut a v3 beta 2.
# 3.0.0-beta (2020/08/12)
- write nil when expiry is zero.
# 3.0.0-alpha (2020/07/27)
- v3 refactor (#1868).
# 2.9.1 (2020/07/03)
- push tags to docker hub (#1766).
# 2.9.0 (2020/06/12)
- Fix regex detection. Fixes #1663 (#1696).
# 2.9.0-rc5 (2020/06/11)
- Merge branch 'master' into release-2.9.0.
# 2.9.0-rc4 (2020/06/11)
- Merge branch 'master' into release-2.9.0.
# 2.9.0-rc1 (2020/06/11)
- Merge branch 'master' into release-2.9.0.
# 2.8.0 (2020/05/31)
- Rewrite Auth interface to use Rules
- Add Cache interface into the Client for request caching
- Fix atomic sequence updates in Client
- Update go mod deps
- Fix ipv6 parsing in mdns registry
- Add namespacing to the default runtime
- Replace go-git with v5
- Increase register ttl to 90 seconds.
# 2.7.0 (2020/05/18)
- Fix the rpc handler json rpc body parsing
- Use caddyserver/certmagic instead of mholt
- Add HasRole to Account
- Add jwt refresh token generation
- Fix rpc stream close locking race
- Add auth namespace env var
- Strip the router penalty code
- Add file upload util
- Fix killing processes in runtime
- Pass namespace to runtime commands
- Generate account on start
- Check errors in cockroachdb.
# 2.6.0 (2020/05/04)
- Fix discord bot authentication header
- Improve api rpc regexp matching
- Change auth account access via context
- Create a jwt implementation of auth
- Fix grpc content-type encoding bug
- Consolidate proxy/network env var logic
- Change secrets interface naming
- Log file path in the logger
- Change location of network resolver
- Add Store to service options
- Fix default runtime log parsing
- Add namespace checks to k8s runtime
- Add proper git checkout in local runtime
- Add database/table options for store
- Add pki implementation
- Import qson.
# 2.5.0 (2020/04/15)
- api/router/registry: extract path based parameters from url to req (#1530).
# 2.4.0 (2020/03/31)
- There can be only one! (#1445).
# 2.3.0 (2020/03/17)
- grpc client/server fixes (#1355).
# 2.2.0 (2020/02/28)
- Rename Auth Validate to Verify
- Replaces noop auth with base32 generated tokens
- Change Excludes to Exclude
- Add token option to auth
- Add profile option and flags for debug
- Add config loading for auth token
- Move before start to before listening.
# 2.1.2 (2020/02/24)
- fix router panic (#1254).
# 2.1.1 (2020/02/23)
- update go modules (#1240).
# 2.1.0 (2020/02/13)
- Exclude Stats & Trace from Auth (#1192).
# 2.0.0 (2020/01/30)
- v2 release.
# 1.18.0 (2019/12/08)
- Add golang ci linter
- Add race detection to travis
- Please the linter
- Do some perf optimisations on slice alloc
- Move http broker to use single entry in registry
- Strip the grpc metadata filtering
- Strip the old codec usage
- Disable retries in client when MICRO_PROXY is enabled
- Strip old X-Micro headers
- Add debug/log streaming implementations
- Add first debug/log interface
- Huge network/tunnel refactor to fix bugs
- Fix proxy slice allocation bug
- Splay out some of the network events
- Default to AdvertiseLocal for router
- Add runtime filtering with Type
- Remove SIGKILL processing.
# 1.17.1 (2019/11/27)
- fix rpc server go routine leak
- add a psuedo socket pool
- update debug buffer to return entries.
# 1.17.0 (2019/11/27)
- Add github related issue templates
- Add Dockerfile for predownloaded go-micro source
- Regenerate all the protos to move to \*.pb.micro.go
- Fix api handler to parse text/plain as default content type
- Fix event handler to allow GET requests
- Change http broker ids to go.micro.http.broker-uuid
- Require protocol field in metadata to query services via client
- Process raw frames in call to Publish
- Complete proxy support for processing messages
- Proxy support for publishing of messages
- Fix grpc connection leak by always closing the connection
- Add a debug ring buffer
- Add broker to tunnel and network
- Force network dns resolver to use cloudflare 1.0.0.1
- Add option to specify whether server should handle signalling
- Change mdns request timeout to 10ms rather than 100ms
- Add router AdvertiseNone and AdvertiseLocal strategies
- Rename runtime packager to builder
- Add full support for a kubernetes runtime.
# 1.16.0 (2019/11/09)
- Pre-make slices for perf optimisation
- Add runtime flag and k8s runtime
- Add debug/profile for pprof profiling
- Reduce go routines in mdns registry and registry cache
- Optimise the router flap detection.
# 1.15.1 (2019/11/03)
- Router recovery penalty should be below 500.
# 1.15.0 (2019/11/03)
- go fmt -s
- web generate service on registration
- downgrade some network messages to trace
- fix tunnel panic on deleting link
- add postgres store
- change grpc recover logging
- add runtime service
- add kubernetes runtime
- add runtime notifier
- proxy add header based routing for Micro-{Gateway, Router, Network}
- network hash address based on service + node id
- metadata add mergecontext function.
# 1.14.0 (2019/10/25)
- Remove consul registry
- Change store Sync endpoint to List
- Remove cloudflare-go usage in store
- Add non-backwards compatible link changes.
# 1.13.2 (2019/10/22)
- Fix proxy selection to use round robin strategy.
# 1.13.1 (2019/10/19)
- Fix divide by zero bug in broker.
# 1.13.0 (2019/10/18)
- Fix network recursive read lock bug
- Add certmagic random pull time
- Strip http broker topic: prefix.
# 1.12.0 (2019/10/17)
- Add ACME Provider interface
- Implement certmagic ACME Provider
- Add certmagic Store implementation
- Add broker service implementation
- Add ability to set grpc dial and call options
- Add etcd registry and other plugins
- Add Network.Connect rpc endpoint
- Resolve network node dns names
- Support Network.Routes querying
- Fix caching registry bugs
- Move gossip registry to go-plugins
- Add router advertise strategy
- Add Cloudflare store implementation
- Add store service implementation.
# 1.11.3 (2019/10/12)
- Fix the quic-go checksum mismatch by updating to 0.12.1.
# 1.11.2 (2019/10/12)
- Fix cache error check.
# 1.11.1 (2019/10/07)
- Fix cache registry deadlocking bug.
# 1.11.0 (2019/10/01)
- This is likely the last release of v1.
# 1.10.0 (2019/09/11)
- Add grpc client code application/grpc content-type
- Move client to use stream dialer
- Add network implementation
- Add dynamic plugin loading
- Add multilink usage in proxy
- Add registry implementation
- Scope mdns to .micro domain
- Support grpc server processing by default
- Add tunnel broker.
# 1.9.1 (2019/08/19)
- Fix waitgroup race condition.
# 1.9.0 (2019/08/19)
- Fix grpc codec for broker publishing
- Use the connection pool for streaming
- Send EOS from client when closing stream
- Add stream header to mucp protocol
- Add stream multiplexing in the server
- Fix watcher bug in file config source
- Fix monitoring watcher to only look at mucp services
- Only check router status on lookup failure
- Fix proxy streaming and client request processing
- Fix host:port processing for messaging systems
- Add start method to the router
- Fix router race condition for default values
- Add loopback detection to the tunnel
- Add connection retry logic to tunnel
- Make log levels accessible for the logger
- Add proxy muxer for internal calls.
# 1.8.3 (2019/08/12)
- Fix nats draining
- More verbose selector errors to return service name
- Move handler debug package
- Add a monitoring package
- Fix consul address parsing
- Fix server extraction code
- Add tunnel implementation
- Add util log level
- Add util io package to wrap transport socket.
# 1.8.2 (2019/08/06)
- Point release for micro
- Adds travis caching
- Removes unused network code
- Adds tunnel interface
- Consul agent check
- Router handler interface
- Non host:port fixes.
# 1.8.1 (2019/07/31)
- Use mdns 0.2.0 release tag.
# 1.8.0 (2019/07/29)
- Move the selector into client
- Change broker.Publication to broker.Event
- Move cmd into config
- Enable default json processing in api
- Remove port from registry
- Memory broker/transport race fixes
- GRPC codec fix
- Client pool interface
- Router interface/service implementations
- Config decoding fixes
- Memory store expiration fix
- Network link/tunnel/resolver packages
- Proxy router caching
- Registry util functions.
# 1.7.0 (2019/06/21)
- Update go mod
- Move mock data out of memory registry
- wrap the grpc codecs to support framing
- change grpc resolution to use service.method
- support full proxying via grpc
- add text codec
- move data/store
- add network interface
- add router package and implementation
- move options to config/options
- send gossip updates on register/deregister
- fix node add/del bug
- add handler wrapper back into core router.
# 1.6.0 (2019/06/07)
- Massive go.mod dependency cleanup _ Moved etcd, memcache, redis sync things to go-plugins _ uuid to google uuid \* blew away go.mod
- Add better proxy interface and features
- Add new options interface.
# 1.5.0 (2019/06/05)
- Fix go mod issues.
# 1.4.0 (2019/06/04)
- Final consolidation of all libraries.
# 1.3.1 (2019/06/03)
- Fix broken pipe bug. Don't send message when client closed connection..
# 1.3.0 (2019/05/31)
- The great rewrite.
# 1.2.0 (2019/05/22)
- Update go mod
- Fix mock client
- Fix retries logic
- Fix consul api change
- Use consul client for watcher
- Fix gossip data races
- Add registry check function.
# 1.1.0 (2019/03/28)
- Update go mod
- Fix endpoint extractor generation.
# 1.0.0 (2019/03/05)
- 1.0.0 release.
# 0.27.1 (2019/03/05)
- Fix nil consul client.
# 0.27.0 (2019/02/23)
- Remove buff check in http transport
- Change default version to latest
- Add exchange routing
- Update go modules.
# 0.26.1 (2019/02/13)
- Fix gossip registry
- Update go modules for rcache.
# 0.26.0 (2019/02/13)
- Update go modules
- Add gossip registry rejoin
- Move selector to rcache.
# 0.25.0 (2019/02/04)
- Add server request body.
# 0.24.1 (2019/02/01)
- Various bug fixes
- Backwards compatible with 0.14 and older
- Fix mdns and gossip race conditions
- Use official h2c server
- Enable support for MICRO_PROXY.
# 0.24.0 (2019/01/30)
- Add go mod.
# 0.23.0 (2019/01/29)
- Move headers from X-Micro to Micro
- Remove Register/Deregister methods from server
- Move register_interval to be internal
- Add subscriber context option.
# 0.22.1 (2019/01/22)
- Fix broken error handling
- now returns error from ServeRequest router.
# 0.22.0 (2019/01/18)
- Address backwards compatibility.
# 0.21.0 (2019/01/17)
- Make MDNS the default registry
- Move mocks to be memory implementations
- Add metadata.Copy function.
# 0.20.0 (2019/01/14)
- BREAKING CHANGES.
# 0.17.0 (2019/01/03)
- Offline inbox for http broker
- JSON/Proto/GRPC codecs
- HTTP proxy from environment.
# 0.16.0 (2018/12/29)
- Fix cache/gossip data race
- Rename cache selector to registry.
# 0.15.1 (2018/12/18)
- Selector cache lookup optimization.
# 0.15.0 (2018/12/13)
- Public NewSubscribeOptions
- http2 broker support
- Timeout error function
- Consul Query Options
- Gossip registry
- RPC Codec renaming.
# 0.14.1 (2018/11/22)
- bug fix socket headers.
# 0.14.0 (2018/11/21)
- use google uuid
- add http handler option.
# 0.13.0 (2018/11/15)
- add local/remote ip methods
- various linting things
- get checks on 0 ttl
- accept loop.
# 0.12.0 (2018/10/09)
- reorder server flag
- atomic increment sequence
- new error method.
# 0.11.0 (2018/08/24)
- Support Consul Connect registration
- Add/Use Init for initialisation from cmd.
# 0.10.0 (2018/07/26)
- Fix broker locking
- Add RetryOnError as default retry policy
- Fix mock client reflection
- Support dialtimeout only above 0
- Add verbose client errors
- Allow client retries to be 0.
# 0.9.0 (2018/06/09)
- Reset server address on shutdown
- Set default pool size to 1
- Support reinitialising connection pool
- Set retries to 1 by default
- Return error for subscribers.
# 0.8.0 (2018/04/20)
- Rework of interfaces.
# 0.7.0 (2018/04/10)
- Move misc to util package
- Add register ttl and interval flags
- Fix protoc-gen-micro example.
# 0.6.0 (2018/04/05)
- Add consul TCP check
- Atomic increment rpc stream sequence.
# 0.5.0 (2018/03/04)
- Support consul services without version
- Switch to stdlib context.
# 0.4.0 (2018/02/19)
- Add WatchOption which allows filtering by service
- Add Options method to registry
- Add Conflict error
- Only watch selected services in cache.
# 0.3.0 (2018/01/02)
- https support for consul
- subscriber deadlock fix
- selector top level option.
# 0.2.0 (2017/10/29)
- Performance improvements.
# 0.1.4 (2017/09/04)
- sort handler/subscriber endpoints
- pass options to new subscriber.
# 0.1.3 (2017/08/15)
- Bug fix nil consul http client.
# 0.1.2 (2017/07/20)
- respond when codec errors out.
# 0.1.1 (2017/06/12)
- Fix potential panic/waitgroup bug.
# 0.1.0 (2017/06/12)
- Initial release.
+46 -40
View File
@@ -1,57 +1,61 @@
# Go Micro [![License](https://img.shields.io/:license-apache-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Go.Dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/github.com/asim/go-micro/v3?tab=doc)
# Go Micro [![License](https://img.shields.io/:license-apache-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Go.Dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/go-micro.dev/v4?tab=doc) [![Community](https://img.shields.io/:community-projects-orange.svg)](https://github.com/go-micro)
Go Micro is a framework for distributed systems development.
## Overview
Go Micro provides the core requirements for distributed systems development including RPC and Event driven communication.
The **Micro** philosophy is sane defaults with a pluggable architecture. We provide defaults to get you started quickly
but everything can be easily swapped out.
Go Micro provides the core requirements for distributed systems development including RPC and Event driven communication.
The Go Micro philosophy is sane defaults with a pluggable architecture. We provide defaults to get you started quickly
but everything can be easily swapped out.
## Features
Go Micro abstracts away the details of distributed systems. Here are the main features.
- **Authentication** - Auth is built in as a first class citizen. Authentication and authorization enable secure
zero trust networking by providing every service an identity and certificates. This additionally includes rule
based access control.
- **Authentication** - Auth is built in as a first class citizen. Authentication and authorization enable secure
zero trust networking by providing every service an identity and certificates. This additionally includes rule
based access control.
- **Dynamic Config** - Load and hot reload dynamic config from anywhere. The config interface provides a way to load application
level config from any source such as env vars, file, etcd. You can merge the sources and even define fallbacks.
- **Dynamic Config** - Load and hot reload dynamic config from anywhere. The config interface provides a way to load application
level config from any source such as env vars, file, etcd. You can merge the sources and even define fallbacks.
- **Data Storage** - A simple data store interface to read, write and delete records. It includes support for memory, file and
CockroachDB by default. State and persistence becomes a core requirement beyond prototyping and Micro looks to build that into the framework.
- **Data Storage** - A simple data store interface to read, write and delete records. It includes support for memory, file and
CockroachDB by default. State and persistence becomes a core requirement beyond prototyping and Micro looks to build that into the framework.
- **Service Discovery** - Automatic service registration and name resolution. Service discovery is at the core of micro service
development. When service A needs to speak to service B it needs the location of that service. The default discovery mechanism is
multicast DNS (mdns), a zeroconf system.
- **Service Discovery** - Automatic service registration and name resolution. Service discovery is at the core of micro service
development. When service A needs to speak to service B it needs the location of that service. The default discovery mechanism is
multicast DNS (mdns), a zeroconf system.
- **Load Balancing** - Client side load balancing built on service discovery. Once we have the addresses of any number of instances
of a service we now need a way to decide which node to route to. We use random hashed load balancing to provide even distribution
across the services and retry a different node if there's a problem.
- **Load Balancing** - Client side load balancing built on service discovery. Once we have the addresses of any number of instances
of a service we now need a way to decide which node to route to. We use random hashed load balancing to provide even distribution
across the services and retry a different node if there's a problem.
- **Message Encoding** - Dynamic message encoding based on content-type. The client and server will use codecs along with content-type
to seamlessly encode and decode Go types for you. Any variety of messages could be encoded and sent from different clients. The client
and server handle this by default. This includes protobuf and json by default.
- **Message Encoding** - Dynamic message encoding based on content-type. The client and server will use codecs along with content-type
to seamlessly encode and decode Go types for you. Any variety of messages could be encoded and sent from different clients. The client
and server handle this by default. This includes protobuf and json by default.
- **RPC Client/Server** - RPC based request/response with support for bidirectional streaming. We provide an abstraction for synchronous
communication. A request made to a service will be automatically resolved, load balanced, dialled and streamed.
- **RPC Client/Server** - RPC based request/response with support for bidirectional streaming. We provide an abstraction for synchronous
communication. A request made to a service will be automatically resolved, load balanced, dialled and streamed.
- **Async Messaging** - PubSub is built in as a first class citizen for asynchronous communication and event driven architectures.
Event notifications are a core pattern in micro service development. The default messaging system is a HTTP event message broker.
- **Async Messaging** - PubSub is built in as a first class citizen for asynchronous communication and event driven architectures.
Event notifications are a core pattern in micro service development. The default messaging system is a HTTP event message broker.
- **Synchronization** - Distributed systems are often built in an eventually consistent manner. Support for distributed locking and
leadership are built in as a Sync interface. When using an eventually consistent database or scheduling use the Sync interface.
- **Event Streaming** - PubSub is great for async notifications but for more advanced use cases event streaming is preferred. Offering
persistent storage, consuming from offsets and acking. Go Micro includes support for NATS Jetstream and Redis streams.
- **Pluggable Interfaces** - Go Micro makes use of Go interfaces for each distributed system abstraction. Because of this these interfaces
are pluggable and allows Go Micro to be runtime agnostic. You can plugin any underlying technology.
- **Synchronization** - Distributed systems are often built in an eventually consistent manner. Support for distributed locking and
leadership are built in as a Sync interface. When using an eventually consistent database or scheduling use the Sync interface.
- **Pluggable Interfaces** - Go Micro makes use of Go interfaces for each distributed system abstraction. Because of this these interfaces
are pluggable and allows Go Micro to be runtime agnostic. You can plugin any underlying technology.
## Getting Started
To make use of Go Micro
```golang
import "github.com/asim/go-micro/v3"
import "go-micro.dev/v4"
// create a new service
service := micro.NewService(
@@ -65,27 +69,29 @@ service.Init()
service.Run()
```
See the [examples](https://github.com/micro/go-micro/tree/master/examples) for detailed information on usage.
## Command Line Interface
See [cmd/gomu](https://github.com/asim/go-micro/tree/master/cmd/gomu) for the command line interface.
See the [examples](https://github.com/go-micro/examples) for detailed information on usage.
## Code Generation
See [cmd/protoc-gen-micro](https://github.com/micro/go-micro/tree/master/cmd/protoc-gen-micro) for protobuf code generation.
## Example Usage
## Community
See [examples](https://github.com/micro/go-micro/tree/master/examples) directory for usage examples.
See [github.com/go-micro](https://github.com/go-micro) for community led projects.
## Plugins
- [Demo](https://github.com/go-micro/demo)
- [Plugins](https://github.com/go-micro/plugins)
- [Examples](https://github.com/go-micro/examples)
- [Dashboard](https://github.com/go-micro/dashboard)
- [CLI](https://github.com/go-micro/cli)
See [plugins](https://github.com/micro/go-micro/tree/master/plugins) directory for all the plugins.
## Changelog
## Services
See [CHANGELOG.md](https://github.com/micro/go-micro/tree/master/CHANGELOG.md) for release history.
See [services](https://github.com/micro/go-micro/tree/master/services) directory for third party services.
## Evolution
Go Micro started in 2015. It's since evolved into a platform called [Micro](https://micro.dev) and a service called [M3O](https://m3o.com).
## License
+2 -2
View File
@@ -5,8 +5,8 @@ import (
"regexp"
"strings"
"github.com/asim/go-micro/v3/registry"
"github.com/asim/go-micro/v3/server"
"go-micro.dev/v4/registry"
"go-micro.dev/v4/server"
)
type Api interface {
+219
View File
@@ -0,0 +1,219 @@
// Package client provides an api client
package client
import (
"bytes"
"encoding/json"
"errors"
"io/ioutil"
"net/http"
"net/url"
"strings"
"time"
"github.com/gorilla/websocket"
)
const (
// local address for api
localAddress = "http://localhost:8080"
)
// Options of the Client
type Options struct {
// Token for authentication
Token string
// Address of the micro platform.
// By default it connects to live. Change it or use the local flag
// to connect to your local installation.
Address string
// Helper flag to help users connect to the default local address
Local bool
// set a timeout
Timeout time.Duration
}
// Request is the request of the generic `api-client` call
type Request struct {
// eg. "go.micro.srv.greeter"
Service string `json:"service"`
// eg. "Say.Hello"
Endpoint string `json:"endpoint"`
// json and then base64 encoded body
Body string `json:"body"`
}
// Response is the response of the generic `api-client` call.
type Response struct {
// json and base64 encoded response body
Body string `json:"body"`
// error fields. Error json example
// {"id":"go.micro.client","code":500,"detail":"malformed method name: \"\"","status":"Internal Server Error"}
Code int `json:"code"`
ID string `json:"id"`
Detail string `json:"detail"`
Status string `json:"status"`
}
// Client enables generic calls to micro
type Client struct {
options Options
}
type Stream struct {
conn *websocket.Conn
service, endpoint string
}
// NewClient returns a generic micro client that connects to live by default
func NewClient(options *Options) *Client {
ret := new(Client)
ret.options = Options{
Address: localAddress,
}
// no options provided
if options == nil {
return ret
}
if options.Token != "" {
ret.options.Token = options.Token
}
if options.Local {
ret.options.Address = localAddress
ret.options.Local = true
}
if options.Timeout > 0 {
ret.options.Timeout = options.Timeout
}
return ret
}
// SetToken sets the api auth token
func (client *Client) SetToken(t string) {
client.options.Token = t
}
// SetTimeout sets the http client's timeout
func (client *Client) SetTimeout(d time.Duration) {
client.options.Timeout = d
}
// Call enables you to access any endpoint of any service on Micro
func (client *Client) Call(service, endpoint string, request, response interface{}) error {
// example curl: curl -XPOST -d '{"service": "go.micro.srv.greeter", "endpoint": "Say.Hello"}'
// -H 'Content-Type: application/json' http://localhost:8080/client {"body":"eyJtc2ciOiJIZWxsbyAifQ=="}
uri, err := url.Parse(client.options.Address)
if err != nil {
return err
}
// set the url to go through the v1 api
uri.Path = "/" + service + "/" + endpoint
b, err := marshalRequest(service, endpoint, request)
if err != nil {
return err
}
req, err := http.NewRequest("POST", uri.String(), bytes.NewBuffer(b))
if err != nil {
return err
}
// set the token if it exists
if len(client.options.Token) > 0 {
req.Header.Set("Authorization", "Bearer "+client.options.Token)
}
req.Header.Set("Content-Type", "application/json")
// if user didn't specify Timeout the default is 0 i.e no timeout
httpClient := &http.Client{
Timeout: client.options.Timeout,
}
resp, err := httpClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
if !(resp.StatusCode >= 200 && resp.StatusCode < 300) {
return errors.New(string(body))
}
return unmarshalResponse(body, response)
}
// Stream enables the ability to stream via websockets
func (client *Client) Stream(service, endpoint string, request interface{}) (*Stream, error) {
b, err := marshalRequest(service, endpoint, request)
if err != nil {
return nil, err
}
uri, err := url.Parse(client.options.Address)
if err != nil {
return nil, err
}
// set the url to go through the v1 api
uri.Path = "/" + service + "/" + endpoint
// replace http with websocket
uri.Scheme = strings.Replace(uri.Scheme, "http", "ws", 1)
// create the headers
header := make(http.Header)
// set the token if it exists
if len(client.options.Token) > 0 {
header.Set("Authorization", "Bearer "+client.options.Token)
}
header.Set("Content-Type", "application/json")
// dial the connection
conn, _, err := websocket.DefaultDialer.Dial(uri.String(), header)
if err != nil {
return nil, err
}
// send the first request
if err := conn.WriteMessage(websocket.TextMessage, b); err != nil {
return nil, err
}
return &Stream{conn, service, endpoint}, nil
}
func (s *Stream) Recv(v interface{}) error {
// read response
_, message, err := s.conn.ReadMessage()
if err != nil {
return err
}
return unmarshalResponse(message, v)
}
func (s *Stream) Send(v interface{}) error {
b, err := marshalRequest(s.service, s.endpoint, v)
if err != nil {
return err
}
return s.conn.WriteMessage(websocket.TextMessage, b)
}
func marshalRequest(service, endpoint string, v interface{}) ([]byte, error) {
return json.Marshal(v)
}
func unmarshalResponse(body []byte, v interface{}) error {
return json.Unmarshal(body, &v)
}
+24
View File
@@ -0,0 +1,24 @@
package client
import (
"os"
"testing"
)
func TestBasicCall(t *testing.T) {
if v := os.Getenv("IN_TRAVIS_CI"); v == "yes" {
return
}
response := map[string]interface{}{}
if err := NewClient(&Options{
Token: os.Getenv("TOKEN"),
}).Call("groups", "list", map[string]interface{}{
"memberId": "random",
}, &response); err != nil {
t.Fatal(err)
}
if len(response) > 0 {
t.Fatal(len(response))
}
}
+7 -7
View File
@@ -4,13 +4,13 @@ package api
import (
"net/http"
goapi "github.com/asim/go-micro/v3/api"
"github.com/asim/go-micro/v3/api/handler"
api "github.com/asim/go-micro/v3/api/proto"
"github.com/asim/go-micro/v3/client"
"github.com/asim/go-micro/v3/errors"
"github.com/asim/go-micro/v3/selector"
"github.com/asim/go-micro/v3/util/ctx"
goapi "go-micro.dev/v4/api"
"go-micro.dev/v4/api/handler"
api "go-micro.dev/v4/api/proto"
"go-micro.dev/v4/client"
"go-micro.dev/v4/errors"
"go-micro.dev/v4/selector"
"go-micro.dev/v4/util/ctx"
)
type apiHandler struct {
+3 -3
View File
@@ -7,10 +7,10 @@ import (
"net/http"
"strings"
api "github.com/asim/go-micro/v3/api/proto"
"github.com/asim/go-micro/v3/registry"
"github.com/asim/go-micro/v3/selector"
"github.com/oxtoacart/bpool"
api "go-micro.dev/v4/api/proto"
"go-micro.dev/v4/registry"
"go-micro.dev/v4/selector"
)
var (
+3 -3
View File
@@ -10,11 +10,11 @@ import (
"strings"
"time"
"github.com/asim/go-micro/v3/api/handler"
proto "github.com/asim/go-micro/v3/api/proto"
"github.com/asim/go-micro/v3/util/ctx"
"github.com/google/uuid"
"github.com/oxtoacart/bpool"
"go-micro.dev/v4/api/handler"
proto "go-micro.dev/v4/api/proto"
"go-micro.dev/v4/util/ctx"
)
var (
+3 -3
View File
@@ -8,9 +8,9 @@ import (
"net/http/httputil"
"net/url"
"github.com/asim/go-micro/v3/api"
"github.com/asim/go-micro/v3/api/handler"
"github.com/asim/go-micro/v3/selector"
"go-micro.dev/v4/api"
"go-micro.dev/v4/api/handler"
"go-micro.dev/v4/selector"
)
const (
+6 -6
View File
@@ -6,12 +6,12 @@ import (
"net/http/httptest"
"testing"
"github.com/asim/go-micro/v3/api/handler"
"github.com/asim/go-micro/v3/api/resolver"
"github.com/asim/go-micro/v3/api/resolver/vpath"
"github.com/asim/go-micro/v3/api/router"
regRouter "github.com/asim/go-micro/v3/api/router/registry"
"github.com/asim/go-micro/v3/registry"
"go-micro.dev/v4/api/handler"
"go-micro.dev/v4/api/resolver"
"go-micro.dev/v4/api/resolver/vpath"
"go-micro.dev/v4/api/router"
regRouter "go-micro.dev/v4/api/router/registry"
"go-micro.dev/v4/registry"
)
func testHttp(t *testing.T, path, service, ns string) {
+2 -2
View File
@@ -1,8 +1,8 @@
package handler
import (
"github.com/asim/go-micro/v3/api/router"
"github.com/asim/go-micro/v3/client"
"go-micro.dev/v4/api/router"
"go-micro.dev/v4/client"
)
var (
+14 -14
View File
@@ -9,22 +9,22 @@ import (
"strconv"
"strings"
"github.com/asim/go-micro/v3/api"
"github.com/asim/go-micro/v3/api/handler"
"github.com/asim/go-micro/v3/api/internal/proto"
"github.com/asim/go-micro/v3/client"
"github.com/asim/go-micro/v3/codec"
"github.com/asim/go-micro/v3/codec/jsonrpc"
"github.com/asim/go-micro/v3/codec/protorpc"
"github.com/asim/go-micro/v3/errors"
"github.com/asim/go-micro/v3/logger"
"github.com/asim/go-micro/v3/metadata"
"github.com/asim/go-micro/v3/registry"
"github.com/asim/go-micro/v3/selector"
"github.com/asim/go-micro/v3/util/ctx"
"github.com/asim/go-micro/v3/util/qson"
jsonpatch "github.com/evanphx/json-patch/v5"
"github.com/oxtoacart/bpool"
"go-micro.dev/v4/api"
"go-micro.dev/v4/api/handler"
"go-micro.dev/v4/api/internal/proto"
"go-micro.dev/v4/client"
"go-micro.dev/v4/codec"
"go-micro.dev/v4/codec/jsonrpc"
"go-micro.dev/v4/codec/protorpc"
"go-micro.dev/v4/errors"
"go-micro.dev/v4/logger"
"go-micro.dev/v4/metadata"
"go-micro.dev/v4/registry"
"go-micro.dev/v4/selector"
"go-micro.dev/v4/util/ctx"
"go-micro.dev/v4/util/qson"
)
const (
+1 -1
View File
@@ -7,8 +7,8 @@ import (
"reflect"
"testing"
go_api "github.com/asim/go-micro/v3/api/proto"
"github.com/golang/protobuf/proto"
go_api "go-micro.dev/v4/api/proto"
)
func TestRequestPayloadFromRequest(t *testing.T) {
+5 -5
View File
@@ -9,14 +9,14 @@ import (
"strings"
"time"
"github.com/asim/go-micro/v3/api"
"github.com/asim/go-micro/v3/client"
raw "github.com/asim/go-micro/v3/codec/bytes"
"github.com/asim/go-micro/v3/logger"
"github.com/asim/go-micro/v3/selector"
"github.com/gobwas/httphead"
"github.com/gobwas/ws"
"github.com/gobwas/ws/wsutil"
"go-micro.dev/v4/api"
"go-micro.dev/v4/client"
raw "go-micro.dev/v4/codec/bytes"
"go-micro.dev/v4/logger"
"go-micro.dev/v4/selector"
)
// serveWebsocket will stream rpc back over websockets assuming json
+3 -3
View File
@@ -11,9 +11,9 @@ import (
"net/url"
"strings"
"github.com/asim/go-micro/v3/api"
"github.com/asim/go-micro/v3/api/handler"
"github.com/asim/go-micro/v3/selector"
"go-micro.dev/v4/api"
"go-micro.dev/v4/api/handler"
"go-micro.dev/v4/selector"
)
const (
+1 -1
View File
@@ -6,7 +6,7 @@ import (
"net/http"
"strings"
"github.com/asim/go-micro/v3/api/resolver"
"go-micro.dev/v4/api/resolver"
)
type Resolver struct{}
+1 -1
View File
@@ -4,7 +4,7 @@ package host
import (
"net/http"
"github.com/asim/go-micro/v3/api/resolver"
"go-micro.dev/v4/api/resolver"
)
type Resolver struct {
+1 -1
View File
@@ -5,7 +5,7 @@ import (
"net/http"
"strings"
"github.com/asim/go-micro/v3/api/resolver"
"go-micro.dev/v4/api/resolver"
)
type Resolver struct {
+1 -1
View File
@@ -7,7 +7,7 @@ import (
"regexp"
"strings"
"github.com/asim/go-micro/v3/api/resolver"
"go-micro.dev/v4/api/resolver"
)
func NewResolver(opts ...resolver.Option) resolver.Resolver {
+3 -3
View File
@@ -1,9 +1,9 @@
package router
import (
"github.com/asim/go-micro/v3/api/resolver"
"github.com/asim/go-micro/v3/api/resolver/vpath"
"github.com/asim/go-micro/v3/registry"
"go-micro.dev/v4/api/resolver"
"go-micro.dev/v4/api/resolver/vpath"
"go-micro.dev/v4/registry"
)
type Options struct {
+7 -7
View File
@@ -10,13 +10,13 @@ import (
"sync"
"time"
"github.com/asim/go-micro/v3/api"
"github.com/asim/go-micro/v3/api/router"
"github.com/asim/go-micro/v3/api/router/util"
"github.com/asim/go-micro/v3/logger"
"github.com/asim/go-micro/v3/metadata"
"github.com/asim/go-micro/v3/registry"
"github.com/asim/go-micro/v3/registry/cache"
"go-micro.dev/v4/api"
"go-micro.dev/v4/api/router"
"go-micro.dev/v4/api/router/util"
"go-micro.dev/v4/logger"
"go-micro.dev/v4/metadata"
"go-micro.dev/v4/registry"
"go-micro.dev/v4/registry/cache"
)
// endpoint struct, that holds compiled pcre
+1 -1
View File
@@ -3,8 +3,8 @@ package registry
import (
"testing"
"github.com/asim/go-micro/v3/registry"
"github.com/stretchr/testify/assert"
"go-micro.dev/v4/registry"
)
func TestStoreRegex(t *testing.T) {
+1 -1
View File
@@ -4,7 +4,7 @@ package router
import (
"net/http"
"github.com/asim/go-micro/v3/api"
"go-micro.dev/v4/api"
)
// Router is used to determine an endpoint for a request
+7 -7
View File
@@ -8,13 +8,13 @@ import (
"strings"
"sync"
"github.com/asim/go-micro/v3/api"
"github.com/asim/go-micro/v3/api/router"
"github.com/asim/go-micro/v3/api/router/util"
"github.com/asim/go-micro/v3/logger"
"github.com/asim/go-micro/v3/metadata"
"github.com/asim/go-micro/v3/registry"
rutil "github.com/asim/go-micro/v3/util/registry"
"go-micro.dev/v4/api"
"go-micro.dev/v4/api/router"
"go-micro.dev/v4/api/router/util"
"go-micro.dev/v4/logger"
"go-micro.dev/v4/metadata"
"go-micro.dev/v4/registry"
rutil "go-micro.dev/v4/util/registry"
)
type endpoint struct {
+1 -1
View File
@@ -6,7 +6,7 @@ import (
"fmt"
"strings"
"github.com/asim/go-micro/v3/logger"
"go-micro.dev/v4/logger"
)
// InvalidTemplateError indicates that the path template is not valid.
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"reflect"
"testing"
"github.com/asim/go-micro/v3/logger"
"go-micro.dev/v4/logger"
)
func TestTokenize(t *testing.T) {
+1 -1
View File
@@ -7,7 +7,7 @@ import (
"fmt"
"strings"
"github.com/asim/go-micro/v3/logger"
"go-micro.dev/v4/logger"
)
var (
+2 -2
View File
@@ -7,8 +7,8 @@ import (
"net"
"os"
"github.com/asim/go-micro/v3/api/server/acme"
"github.com/asim/go-micro/v3/logger"
"go-micro.dev/v4/api/server/acme"
"go-micro.dev/v4/logger"
"golang.org/x/crypto/acme/autocert"
)
+3 -3
View File
@@ -8,10 +8,10 @@ import (
"os"
"sync"
"github.com/asim/go-micro/v3/api/server"
"github.com/asim/go-micro/v3/api/server/cors"
"github.com/asim/go-micro/v3/logger"
"github.com/gorilla/handlers"
"go-micro.dev/v4/api/server"
"go-micro.dev/v4/api/server/cors"
"go-micro.dev/v4/logger"
)
type httpServer struct {
+5 -5
View File
@@ -2,9 +2,9 @@ package http
import (
"fmt"
"github.com/asim/go-micro/v3/api/server"
"github.com/asim/go-micro/v3/api/server/cors"
"io/ioutil"
"go-micro.dev/v4/api/server"
"go-micro.dev/v4/api/server/cors"
"io"
"net/http"
"testing"
)
@@ -28,7 +28,7 @@ func TestHTTPServer(t *testing.T) {
}
defer rsp.Body.Close()
b, err := ioutil.ReadAll(rsp.Body)
b, err := io.ReadAll(rsp.Body)
if err != nil {
t.Fatal(err)
}
@@ -73,7 +73,7 @@ func TestCORSHTTPServer(t *testing.T) {
}
defer rsp.Body.Close()
b, err := ioutil.ReadAll(rsp.Body)
b, err := io.ReadAll(rsp.Body)
if err != nil {
t.Fatal(err)
}
+3 -3
View File
@@ -2,11 +2,11 @@ package server
import (
"crypto/tls"
"github.com/asim/go-micro/v3/api/server/cors"
"go-micro.dev/v4/api/server/cors"
"net/http"
"github.com/asim/go-micro/v3/api/resolver"
"github.com/asim/go-micro/v3/api/server/acme"
"go-micro.dev/v4/api/resolver"
"go-micro.dev/v4/api/server/acme"
)
type Option func(o *Options)
+9 -10
View File
@@ -8,7 +8,6 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"math/rand"
"net"
"net/http"
@@ -17,14 +16,14 @@ import (
"sync"
"time"
"github.com/asim/go-micro/v3/codec/json"
merr "github.com/asim/go-micro/v3/errors"
"github.com/asim/go-micro/v3/registry"
"github.com/asim/go-micro/v3/registry/cache"
maddr "github.com/asim/go-micro/v3/util/addr"
mnet "github.com/asim/go-micro/v3/util/net"
mls "github.com/asim/go-micro/v3/util/tls"
"github.com/google/uuid"
"go-micro.dev/v4/codec/json"
merr "go-micro.dev/v4/errors"
"go-micro.dev/v4/registry"
"go-micro.dev/v4/registry/cache"
maddr "go-micro.dev/v4/util/addr"
mnet "go-micro.dev/v4/util/net"
mls "go-micro.dev/v4/util/tls"
"golang.org/x/net/http2"
)
@@ -300,7 +299,7 @@ func (h *httpBroker) ServeHTTP(w http.ResponseWriter, req *http.Request) {
req.ParseForm()
b, err := ioutil.ReadAll(req.Body)
b, err := io.ReadAll(req.Body)
if err != nil {
errr := merr.InternalServerError("go.micro.broker", "Error reading request body: %v", err)
w.WriteHeader(500)
@@ -558,7 +557,7 @@ func (h *httpBroker) Publish(topic string, msg *Message, opts ...PublishOption)
}
// discard response body
io.Copy(ioutil.Discard, r.Body)
io.Copy(io.Discard, r.Body)
r.Body.Close()
return nil
}
+2 -2
View File
@@ -5,9 +5,9 @@ import (
"testing"
"time"
"github.com/asim/go-micro/v3/broker"
"github.com/asim/go-micro/v3/registry"
"github.com/google/uuid"
"go-micro.dev/v4/broker"
"go-micro.dev/v4/registry"
)
var (
+239
View File
@@ -0,0 +1,239 @@
// Package memory provides a memory broker
package broker
import (
"context"
"errors"
"math/rand"
"sync"
"time"
"github.com/google/uuid"
"go-micro.dev/v4/logger"
maddr "go-micro.dev/v4/util/addr"
mnet "go-micro.dev/v4/util/net"
)
type memoryBroker struct {
opts Options
addr string
sync.RWMutex
connected bool
Subscribers map[string][]*memorySubscriber
}
type memoryEvent struct {
opts Options
topic string
err error
message interface{}
}
type memorySubscriber struct {
id string
topic string
exit chan bool
handler Handler
opts SubscribeOptions
}
func (m *memoryBroker) Options() Options {
return m.opts
}
func (m *memoryBroker) Address() string {
return m.addr
}
func (m *memoryBroker) Connect() error {
m.Lock()
defer m.Unlock()
if m.connected {
return nil
}
// use 127.0.0.1 to avoid scan of all network interfaces
addr, err := maddr.Extract("127.0.0.1")
if err != nil {
return err
}
i := rand.Intn(20000)
// set addr with port
addr = mnet.HostPort(addr, 10000+i)
m.addr = addr
m.connected = true
return nil
}
func (m *memoryBroker) Disconnect() error {
m.Lock()
defer m.Unlock()
if !m.connected {
return nil
}
m.connected = false
return nil
}
func (m *memoryBroker) Init(opts ...Option) error {
for _, o := range opts {
o(&m.opts)
}
return nil
}
func (m *memoryBroker) Publish(topic string, msg *Message, opts ...PublishOption) error {
m.RLock()
if !m.connected {
m.RUnlock()
return errors.New("not connected")
}
subs, ok := m.Subscribers[topic]
m.RUnlock()
if !ok {
return nil
}
var v interface{}
if m.opts.Codec != nil {
buf, err := m.opts.Codec.Marshal(msg)
if err != nil {
return err
}
v = buf
} else {
v = msg
}
p := &memoryEvent{
topic: topic,
message: v,
opts: m.opts,
}
for _, sub := range subs {
if err := sub.handler(p); err != nil {
p.err = err
if eh := m.opts.ErrorHandler; eh != nil {
eh(p)
continue
}
return err
}
}
return nil
}
func (m *memoryBroker) Subscribe(topic string, handler Handler, opts ...SubscribeOption) (Subscriber, error) {
m.RLock()
if !m.connected {
m.RUnlock()
return nil, errors.New("not connected")
}
m.RUnlock()
var options SubscribeOptions
for _, o := range opts {
o(&options)
}
sub := &memorySubscriber{
exit: make(chan bool, 1),
id: uuid.New().String(),
topic: topic,
handler: handler,
opts: options,
}
m.Lock()
m.Subscribers[topic] = append(m.Subscribers[topic], sub)
m.Unlock()
go func() {
<-sub.exit
m.Lock()
var newSubscribers []*memorySubscriber
for _, sb := range m.Subscribers[topic] {
if sb.id == sub.id {
continue
}
newSubscribers = append(newSubscribers, sb)
}
m.Subscribers[topic] = newSubscribers
m.Unlock()
}()
return sub, nil
}
func (m *memoryBroker) String() string {
return "memory"
}
func (m *memoryEvent) Topic() string {
return m.topic
}
func (m *memoryEvent) Message() *Message {
switch v := m.message.(type) {
case *Message:
return v
case []byte:
msg := &Message{}
if err := m.opts.Codec.Unmarshal(v, msg); err != nil {
if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
logger.Errorf("[memory]: failed to unmarshal: %v\n", err)
}
return nil
}
return msg
}
return nil
}
func (m *memoryEvent) Ack() error {
return nil
}
func (m *memoryEvent) Error() error {
return m.err
}
func (m *memorySubscriber) Options() SubscribeOptions {
return m.opts
}
func (m *memorySubscriber) Topic() string {
return m.topic
}
func (m *memorySubscriber) Unsubscribe() error {
m.exit <- true
return nil
}
func NewMemoryBroker(opts ...Option) Broker {
options := Options{
Context: context.Background(),
}
rand.Seed(time.Now().UnixNano())
for _, o := range opts {
o(&options)
}
return &memoryBroker{
opts: options,
Subscribers: make(map[string][]*memorySubscriber),
}
}
+50
View File
@@ -0,0 +1,50 @@
package broker_test
import (
"fmt"
"testing"
"go-micro.dev/v4/broker"
)
func TestMemoryBroker(t *testing.T) {
b := broker.NewMemoryBroker()
if err := b.Connect(); err != nil {
t.Fatalf("Unexpected connect error %v", err)
}
topic := "test"
count := 10
fn := func(p broker.Event) error {
return nil
}
sub, err := b.Subscribe(topic, fn)
if err != nil {
t.Fatalf("Unexpected error subscribing %v", err)
}
for i := 0; i < count; i++ {
message := &broker.Message{
Header: map[string]string{
"foo": "bar",
"id": fmt.Sprintf("%d", i),
},
Body: []byte(`hello world`),
}
if err := b.Publish(topic, message); err != nil {
t.Fatalf("Unexpected error publishing %d", i)
}
}
if err := sub.Unsubscribe(); err != nil {
t.Fatalf("Unexpected error unsubscribing from %s: %v", topic, err)
}
if err := b.Disconnect(); err != nil {
t.Fatalf("Unexpected connect error %v", err)
}
}
+2 -2
View File
@@ -4,8 +4,8 @@ import (
"context"
"crypto/tls"
"github.com/asim/go-micro/v3/codec"
"github.com/asim/go-micro/v3/registry"
"go-micro.dev/v4/codec"
"go-micro.dev/v4/registry"
)
type Options struct {
+8 -8
View File
@@ -23,15 +23,15 @@ var (
// Cache is the interface that wraps the cache.
//
// Context specifies the context for the cache.
// Get gets a cached value by key.
// Put stores a key-value pair into cache.
// Delete removes a key from cache.
type Cache interface {
Context(ctx context.Context) Cache
Get(key string) (interface{}, time.Time, error)
Put(key string, val interface{}, d time.Duration) error
Delete(key string) error
// Get gets a cached value by key.
Get(ctx context.Context, key string) (interface{}, time.Time, error)
// Put stores a key-value pair into cache.
Put(ctx context.Context, key string, val interface{}, d time.Duration) error
// Delete removes a key from cache.
Delete(ctx context.Context, key string) error
// String returns the name of the implementation.
String() string
}
// Item represents an item stored in the cache.
+9 -11
View File
@@ -9,19 +9,13 @@ import (
type memCache struct {
opts Options
sync.RWMutex
ctx context.Context
items map[string]Item
}
func (c *memCache) Context(ctx context.Context) Cache {
c.ctx = ctx
return c
}
func (c *memCache) Get(key string) (interface{}, time.Time, error) {
c.RWMutex.Lock()
defer c.RWMutex.Unlock()
func (c *memCache) Get(ctx context.Context, key string) (interface{}, time.Time, error) {
c.RWMutex.RLock()
defer c.RWMutex.RUnlock()
item, found := c.items[key]
if !found {
@@ -34,7 +28,7 @@ func (c *memCache) Get(key string) (interface{}, time.Time, error) {
return item.Value, time.Unix(0, item.Expiration), nil
}
func (c *memCache) Put(key string, val interface{}, d time.Duration) error {
func (c *memCache) Put(ctx context.Context, key string, val interface{}, d time.Duration) error {
var e int64
if d == DefaultExpiration {
d = c.opts.Expiration
@@ -54,7 +48,7 @@ func (c *memCache) Put(key string, val interface{}, d time.Duration) error {
return nil
}
func (c *memCache) Delete(key string) error {
func (c *memCache) Delete(ctx context.Context, key string) error {
c.RWMutex.Lock()
defer c.RWMutex.Unlock()
@@ -66,3 +60,7 @@ func (c *memCache) Delete(key string) error {
delete(c.items, key)
return nil
}
func (m *memCache) String() string {
return "memory"
}
+17 -17
View File
@@ -7,15 +7,15 @@ import (
)
var (
ctx context.Context = context.TODO()
key string = "test"
val interface{} = "hello go-micro"
ctx = context.TODO()
key string = "test"
val interface{} = "hello go-micro"
)
// TestMemCache tests the in-memory cache implementation.
func TestCache(t *testing.T) {
t.Run("CacheGetMiss", func(t *testing.T) {
if _, _, err := NewCache().Context(ctx).Get(key); err == nil {
if _, _, err := NewCache().Get(ctx, key); err == nil {
t.Error("expected to get no value from cache")
}
})
@@ -23,11 +23,11 @@ func TestCache(t *testing.T) {
t.Run("CacheGetHit", func(t *testing.T) {
c := NewCache()
if err := c.Context(ctx).Put(key, val, 0); err != nil {
if err := c.Put(ctx, key, val, 0); err != nil {
t.Error(err)
}
if a, _, err := c.Context(ctx).Get(key); err != nil {
if a, _, err := c.Get(ctx, key); err != nil {
t.Errorf("Expected a value, got err: %s", err)
} else if a != val {
t.Errorf("Expected '%v', got '%v'", val, a)
@@ -38,12 +38,12 @@ func TestCache(t *testing.T) {
c := NewCache()
e := 20 * time.Millisecond
if err := c.Context(ctx).Put(key, val, e); err != nil {
if err := c.Put(ctx, key, val, e); err != nil {
t.Error(err)
}
<-time.After(25 * time.Millisecond)
if _, _, err := c.Context(ctx).Get(key); err == nil {
if _, _, err := c.Get(ctx, key); err == nil {
t.Error("expected to get no value from cache")
}
})
@@ -52,18 +52,18 @@ func TestCache(t *testing.T) {
c := NewCache()
e := 25 * time.Millisecond
if err := c.Context(ctx).Put(key, val, e); err != nil {
if err := c.Put(ctx, key, val, e); err != nil {
t.Error(err)
}
<-time.After(20 * time.Millisecond)
if _, _, err := c.Context(ctx).Get(key); err != nil {
if _, _, err := c.Get(ctx, key); err != nil {
t.Errorf("expected a value, got err: %s", err)
}
})
t.Run("CacheDeleteMiss", func(t *testing.T) {
if err := NewCache().Context(ctx).Delete(key); err == nil {
if err := NewCache().Delete(ctx, key); err == nil {
t.Error("expected to delete no value from cache")
}
})
@@ -71,15 +71,15 @@ func TestCache(t *testing.T) {
t.Run("CacheDeleteHit", func(t *testing.T) {
c := NewCache()
if err := c.Context(ctx).Put(key, val, 0); err != nil {
if err := c.Put(ctx, key, val, 0); err != nil {
t.Error(err)
}
if err := c.Context(ctx).Delete(key); err != nil {
if err := c.Delete(ctx, key); err != nil {
t.Errorf("Expected to delete an item, got err: %s", err)
}
if _, _, err := c.Context(ctx).Get(key); err == nil {
if _, _, err := c.Get(ctx, key); err == nil {
t.Errorf("Expected error")
}
})
@@ -89,12 +89,12 @@ func TestCacheWithOptions(t *testing.T) {
t.Run("CacheWithExpiration", func(t *testing.T) {
c := NewCache(Expiration(20 * time.Millisecond))
if err := c.Context(ctx).Put(key, val, 0); err != nil {
if err := c.Put(ctx, key, val, 0); err != nil {
t.Error(err)
}
<-time.After(25 * time.Millisecond)
if _, _, err := c.Context(ctx).Get(key); err == nil {
if _, _, err := c.Get(ctx, key); err == nil {
t.Error("expected to get no value from cache")
}
})
@@ -102,7 +102,7 @@ func TestCacheWithOptions(t *testing.T) {
t.Run("CacheWithItems", func(t *testing.T) {
c := NewCache(Items(map[string]Item{key: {val, 0}}))
if a, _, err := c.Context(ctx).Get(key); err != nil {
if a, _, err := c.Get(ctx, key); err != nil {
t.Errorf("Expected a value, got err: %s", err)
} else if a != val {
t.Errorf("Expected '%v', got '%v'", val, a)
+22 -1
View File
@@ -1,11 +1,18 @@
package cache
import "time"
import (
"context"
"time"
)
// Options represents the options for the cache.
type Options struct {
Expiration time.Duration
Items map[string]Item
// Address represents the address or other connection information of the cache service.
Address string
// Context should contain all implementation specific options, using context.WithValue.
Context context.Context
}
// Option manipulates the Options passed.
@@ -25,6 +32,20 @@ func Items(i map[string]Item) Option {
}
}
// WithAddress sets the cache service address or connection information
func WithAddress(addr string) Option {
return func(o *Options) {
o.Address = addr
}
}
// WithContext sets the cache context, for any extra configuration
func WithContext(c context.Context) Option {
return func(o *Options) {
o.Context = c
}
}
// NewOptions returns a new options struct.
func NewOptions(opts ...Option) Options {
options := Options{
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"context"
"time"
"github.com/asim/go-micro/v3/util/backoff"
"go-micro.dev/v4/util/backoff"
)
type BackoffFunc func(ctx context.Context, req Request, attempts int) (time.Duration, error)
+1 -1
View File
@@ -7,8 +7,8 @@ import (
"hash/fnv"
"time"
"github.com/asim/go-micro/v3/metadata"
cache "github.com/patrickmn/go-cache"
"go-micro.dev/v4/metadata"
)
// NewCache returns an initialised cache.
+1 -1
View File
@@ -5,7 +5,7 @@ import (
"testing"
"time"
"github.com/asim/go-micro/v3/metadata"
"go-micro.dev/v4/metadata"
)
func TestCache(t *testing.T) {
+8 -1
View File
@@ -5,7 +5,7 @@ import (
"context"
"time"
"github.com/asim/go-micro/v3/codec"
"go-micro.dev/v4/codec"
)
// Client is the interface used to make requests to services.
@@ -64,6 +64,7 @@ type Response interface {
// Stream is the inteface for a bidirectional synchronous stream
type Stream interface {
Closer
// Context for the stream
Context() context.Context
// The request made
@@ -80,6 +81,12 @@ type Stream interface {
Close() error
}
// Closer handle client close
type Closer interface {
// CloseSend closes the send direction of the stream.
CloseSend() error
}
// Option used by the Client
type Option func(*Options)
+1 -1
View File
@@ -1,7 +1,7 @@
package client
import (
"github.com/asim/go-micro/v3/registry"
"go-micro.dev/v4/registry"
)
var (
+5 -5
View File
@@ -4,11 +4,11 @@ import (
"context"
"time"
"github.com/asim/go-micro/v3/broker"
"github.com/asim/go-micro/v3/codec"
"github.com/asim/go-micro/v3/registry"
"github.com/asim/go-micro/v3/selector"
"github.com/asim/go-micro/v3/transport"
"go-micro.dev/v4/broker"
"go-micro.dev/v4/codec"
"go-micro.dev/v4/registry"
"go-micro.dev/v4/selector"
"go-micro.dev/v4/transport"
)
type Options struct {
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"testing"
"time"
"github.com/asim/go-micro/v3/transport"
"go-micro.dev/v4/transport"
)
func TestCallOptions(t *testing.T) {
+1 -1
View File
@@ -3,7 +3,7 @@ package client
import (
"context"
"github.com/asim/go-micro/v3/errors"
"go-micro.dev/v4/errors"
)
// note that returning either false or a non-nil error will result in the call not being retried
+12 -12
View File
@@ -6,18 +6,18 @@ import (
"sync/atomic"
"time"
"github.com/asim/go-micro/v3/broker"
"github.com/asim/go-micro/v3/codec"
raw "github.com/asim/go-micro/v3/codec/bytes"
"github.com/asim/go-micro/v3/errors"
"github.com/asim/go-micro/v3/metadata"
"github.com/asim/go-micro/v3/registry"
"github.com/asim/go-micro/v3/selector"
"github.com/asim/go-micro/v3/transport"
"github.com/asim/go-micro/v3/util/buf"
"github.com/asim/go-micro/v3/util/net"
"github.com/asim/go-micro/v3/util/pool"
"github.com/google/uuid"
"go-micro.dev/v4/broker"
"go-micro.dev/v4/codec"
raw "go-micro.dev/v4/codec/bytes"
"go-micro.dev/v4/errors"
"go-micro.dev/v4/metadata"
"go-micro.dev/v4/registry"
"go-micro.dev/v4/selector"
"go-micro.dev/v4/transport"
"go-micro.dev/v4/util/buf"
"go-micro.dev/v4/util/net"
"go-micro.dev/v4/util/pool"
)
type rpcClient struct {
@@ -60,7 +60,7 @@ func (r *rpcClient) newCodec(contentType string) (codec.NewCodec, error) {
if cf, ok := DefaultCodecs[contentType]; ok {
return cf, nil
}
return nil, fmt.Errorf("Unsupported Content-Type: %s", contentType)
return nil, fmt.Errorf("unsupported Content-Type: %s", contentType)
}
func (r *rpcClient) call(ctx context.Context, node *registry.Node, req Request, resp interface{}, opts CallOptions) error {
+3 -3
View File
@@ -5,9 +5,9 @@ import (
"fmt"
"testing"
"github.com/asim/go-micro/v3/errors"
"github.com/asim/go-micro/v3/registry"
"github.com/asim/go-micro/v3/selector"
"go-micro.dev/v4/errors"
"go-micro.dev/v4/registry"
"go-micro.dev/v4/selector"
)
func newTestRegistry() registry.Registry {
+11 -11
View File
@@ -4,16 +4,16 @@ import (
"bytes"
errs "errors"
"github.com/asim/go-micro/v3/codec"
raw "github.com/asim/go-micro/v3/codec/bytes"
"github.com/asim/go-micro/v3/codec/grpc"
"github.com/asim/go-micro/v3/codec/json"
"github.com/asim/go-micro/v3/codec/jsonrpc"
"github.com/asim/go-micro/v3/codec/proto"
"github.com/asim/go-micro/v3/codec/protorpc"
"github.com/asim/go-micro/v3/errors"
"github.com/asim/go-micro/v3/registry"
"github.com/asim/go-micro/v3/transport"
"go-micro.dev/v4/codec"
raw "go-micro.dev/v4/codec/bytes"
"go-micro.dev/v4/codec/grpc"
"go-micro.dev/v4/codec/json"
"go-micro.dev/v4/codec/jsonrpc"
"go-micro.dev/v4/codec/proto"
"go-micro.dev/v4/codec/protorpc"
"go-micro.dev/v4/errors"
"go-micro.dev/v4/registry"
"go-micro.dev/v4/transport"
)
const (
@@ -50,7 +50,7 @@ type readWriteCloser struct {
}
var (
DefaultContentType = "application/protobuf"
DefaultContentType = "application/json"
DefaultCodecs = map[string]codec.NewCodec{
"application/grpc": grpc.NewCodec,
+1 -1
View File
@@ -1,7 +1,7 @@
package client
import (
"github.com/asim/go-micro/v3/codec"
"go-micro.dev/v4/codec"
)
type rpcRequest struct {
+2 -2
View File
@@ -1,8 +1,8 @@
package client
import (
"github.com/asim/go-micro/v3/codec"
"github.com/asim/go-micro/v3/transport"
"go-micro.dev/v4/codec"
"go-micro.dev/v4/transport"
)
type rpcResponse struct {
+7 -1
View File
@@ -2,10 +2,11 @@ package client
import (
"context"
"errors"
"io"
"sync"
"github.com/asim/go-micro/v3/codec"
"go-micro.dev/v4/codec"
)
// Implements the streamer interface
@@ -93,6 +94,7 @@ func (r *rpcStream) Recv(msg interface{}) error {
return io.ErrUnexpectedEOF
}
r.err = err
r.Unlock()
return err
}
@@ -132,6 +134,10 @@ func (r *rpcStream) Error() error {
return r.err
}
func (r *rpcStream) CloseSend() error {
return errors.New("streamer not implemented")
}
func (r *rpcStream) Close() error {
r.Lock()
+1 -1
View File
@@ -3,7 +3,7 @@ package client
import (
"context"
"github.com/asim/go-micro/v3/registry"
"go-micro.dev/v4/registry"
)
// CallFunc represents the individual call func
+16 -16
View File
@@ -7,23 +7,23 @@ import (
"strings"
"time"
"github.com/asim/go-micro/v3/auth"
"github.com/asim/go-micro/v3/broker"
"github.com/asim/go-micro/v3/cache"
"github.com/asim/go-micro/v3/client"
"github.com/asim/go-micro/v3/config"
"github.com/asim/go-micro/v3/debug/profile"
"github.com/asim/go-micro/v3/debug/profile/http"
"github.com/asim/go-micro/v3/debug/profile/pprof"
"github.com/asim/go-micro/v3/debug/trace"
"github.com/asim/go-micro/v3/logger"
"github.com/asim/go-micro/v3/registry"
"github.com/asim/go-micro/v3/runtime"
"github.com/asim/go-micro/v3/selector"
"github.com/asim/go-micro/v3/server"
"github.com/asim/go-micro/v3/store"
"github.com/asim/go-micro/v3/transport"
"github.com/urfave/cli/v2"
"go-micro.dev/v4/auth"
"go-micro.dev/v4/broker"
"go-micro.dev/v4/cache"
"go-micro.dev/v4/client"
"go-micro.dev/v4/config"
"go-micro.dev/v4/debug/profile"
"go-micro.dev/v4/debug/profile/http"
"go-micro.dev/v4/debug/profile/pprof"
"go-micro.dev/v4/debug/trace"
"go-micro.dev/v4/logger"
"go-micro.dev/v4/registry"
"go-micro.dev/v4/runtime"
"go-micro.dev/v4/selector"
"go-micro.dev/v4/server"
"go-micro.dev/v4/store"
"go-micro.dev/v4/transport"
)
type Cmd interface {
-33
View File
@@ -1,33 +0,0 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
_build
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test
*.prof
# ignore go build and test outputs
coverage.txt
coverage.out
# ignore locally built binaries
gomu
dist
-389
View File
@@ -1,389 +0,0 @@
# Gomu
Gomu is a helper tool for developing [Go Micro][1] projects.
## Getting Started
[Download][2] and install **Go**. Version `1.16` or higher is required.
Installation is done by using the [`go install`][3] command.
```bash
go install github.com/asim/go-micro/cmd/gomu@latest
```
Let's create a new service using the `new` command.
```bash
gomu new service helloworld
```
Follow the on-screen instructions. Next, we can run the program.
```bash
cd helloworld
make proto tidy
gomu run
```
Finally we can call the service.
```bash
gomu call helloworld Helloworld.Call '{"name": "John"}'
```
That's all you need to know to get started. Refer to the [Go Micro][1]
documentation for more info on developing services.
## Dependencies
You will need protoc-gen-micro for code generation
* [protobuf][4]
* [protoc-gen-go][5]
* [protoc-gen-micro][6]
```bash
# Download latest proto release
# https://github.com/protocolbuffers/protobuf/releases
go get -u google.golang.org/protobuf/proto
go install github.com/golang/protobuf/protoc-gen-go@latest
go install github.com/asim/go-micro/cmd/protoc-gen-micro/v3@latest
```
## Creating A Service
To create a new service, use the `gomu new service` command.
```bash
$ gomu new service helloworld
creating service helloworld
download protoc zip packages (protoc-$VERSION-$PLATFORM.zip) and install:
visit https://github.com/protocolbuffers/protobuf/releases/latest
download protobuf for go-micro:
go get -u google.golang.org/protobuf/proto
go install github.com/golang/protobuf/protoc-gen-go@latest
go install github.com/asim/go-micro/cmd/protoc-gen-micro/v3@latest
compile the proto file helloworld.proto:
cd helloworld
make proto tidy
```
To create a new function, use the `gomu new function` command. Functions differ
from services in that they exit after returning.
```bash
$ gomu new function helloworld
creating function helloworld
download protoc zip packages (protoc-$VERSION-$PLATFORM.zip) and install:
visit https://github.com/protocolbuffers/protobuf/releases/latest
download protobuf for go-micro:
go get -u google.golang.org/protobuf/proto
go install github.com/golang/protobuf/protoc-gen-go@latest
go install github.com/asim/go-micro/cmd/protoc-gen-micro/v3@latest
compile the proto file helloworld.proto:
cd helloworld
make proto tidy
```
### Jaeger
To create a new service with [Jaeger][7] integration, pass the `--jaeger` flag
to the `gomu new service` or `gomu new function` commands. You may configure
the Jaeger client using [environment variables][8].
```bash
gomu new service --jaeger helloworld
```
You may invoke `trace.NewSpan(context.Context).Finish()` to nest spans. For
example, consider the following handler implementing a greeter.
`handler/helloworld.go`
```go
package helloworld
import (
"context"
log "github.com/asim/go-micro/v3/logger"
"helloworld/greeter"
pb "helloworld/proto"
)
type Helloworld struct{}
func (e *Helloworld) Call(ctx context.Context, req pb.CallRequest, rsp *pb.CallResponse) error {
log.Infof("Received Helloworld.Call request: %v", req)
rsp.Msg = greeter.Greet(ctx, req.Name)
return nil
}
```
`greeter/greeter.go`
```go
package greeter
import (
"context"
"fmt"
"github.com/asim/go-micro/cmd/gomu/debug/trace"
)
func Greet(ctx context.Context, name string) string {
defer trace.NewSpan(ctx).Finish()
return fmt.Sprint("Hello " + name)
}
```
### Skaffold
To create a new service with [Skaffold][9] files, pass the `--skaffold` flag to
the `gomu new service` or `gomu new function` commands.
```bash
gomu new service --skaffold helloworld
```
## Running A Service
To run a service, use the `gomu run` command to build and run your service
continuously.
```bash
$ gomu run
2021-08-20 14:05:54 file=v3@v3.5.2/service.go:199 level=info Starting [service] helloworld
2021-08-20 14:05:54 file=server/rpc_server.go:820 level=info Transport [http] Listening on [::]:34531
2021-08-20 14:05:54 file=server/rpc_server.go:840 level=info Broker [http] Connected to 127.0.0.1:44975
2021-08-20 14:05:54 file=server/rpc_server.go:654 level=info Registry [mdns] Registering node: helloworld-45f43a6f-5fc0-4b0d-af73-e4a10c36ef54
```
### With Docker
To run a service with Docker, build the Docker image and run the Docker
container.
```bash
$ make docker
$ docker run helloworld:latest
2021-08-20 12:07:31 file=v3@v3.5.2/service.go:199 level=info Starting [service] helloworld
2021-08-20 12:07:31 file=server/rpc_server.go:820 level=info Transport [http] Listening on [::]:36037
2021-08-20 12:07:31 file=server/rpc_server.go:840 level=info Broker [http] Connected to 127.0.0.1:46157
2021-08-20 12:07:31 file=server/rpc_server.go:654 level=info Registry [mdns] Registering node: helloworld-31f58714-72f5-4d12-b2eb-98f66aea7a34
```
### With Skaffold
When you've created your service using the `--skaffold` flag, you may run the
Skaffold pipeline using the `skaffold` command.
```bash
skaffold dev
```
## Creating A Client
To create a new client, use the `gomu new client` command. The name is the
service you'd like to create a client project for.
```bash
$ gomu new client helloworld
creating client helloworld
cd helloworld-client
make tidy
```
You may optionally pass the fully qualified package name of the service you'd
like to create a client project for.
```bash
$ gomu new client github.com/auditemarlow/helloworld
creating client helloworld
cd helloworld-client
make tidy
```
## Running A Client
To run a client, use the `gomu run` command to build and run your client
continuously.
```bash
$ gomu run
2021-09-03 12:52:23 file=helloworld-client/main.go:33 level=info msg:"Hello John"
```
## Generating Files
To generate Go Micro project template files after the fact, use the `gomu
generate` command. It will place the generated files in the current working
directory.
```bash
$ gomu generate skaffold
skaffold project template files generated
```
## Listing Services
To list services, use the `gomu services` command.
```bash
$ gomu services
helloworld
```
## Describing A Service
To describe a service, use the `gomu describe service` command.
```bash
$ gomu describe service helloworld
{
"name": "helloworld",
"version": "latest",
"metadata": null,
"endpoints": [
{
"name": "Helloworld.Call",
"request": {
"name": "CallRequest",
"type": "CallRequest",
"values": [
{
"name": "name",
"type": "string",
"values": null
}
]
},
"response": {
"name": "CallResponse",
"type": "CallResponse",
"values": [
{
"name": "msg",
"type": "string",
"values": null
}
]
}
}
],
"nodes": [
{
"id": "helloworld-9660f06a-d608-43d9-9f44-e264ff63c554",
"address": "172.26.165.161:45059",
"metadata": {
"broker": "http",
"protocol": "mucp",
"registry": "mdns",
"server": "mucp",
"transport": "http"
}
}
]
}
```
You may pass the `--format=yaml` flag to output a YAML formatted object.
```bash
$ gomu describe service --format=yaml helloworld
name: helloworld
version: latest
metadata: {}
endpoints:
- name: Helloworld.Call
request:
name: CallRequest
type: CallRequest
values:
- name: name
type: string
values: []
response:
name: CallResponse
type: CallResponse
values:
- name: msg
type: string
values: []
nodes:
- id: helloworld-9660f06a-d608-43d9-9f44-e264ff63c554
address: 172.26.165.161:45059
metadata:
broker: http
protocol: mucp
registry: mdns
server: mucp
transport: http
```
## Calling A Service
To call a service, use the `gomu call` command. This will send a single request
and expect a single response.
```bash
$ gomu call helloworld Helloworld.Call '{"name": "John"}'
{"msg":"Hello John"}
```
To call a service's server stream, use the `gomu stream server` command. This
will send a single request and expect a stream of responses.
```bash
$ gomu stream server helloworld Helloworld.ServerStream '{"count": 10}'
{"count":0}
{"count":1}
{"count":2}
{"count":3}
{"count":4}
{"count":5}
{"count":6}
{"count":7}
{"count":8}
{"count":9}
```
To call a service's bidirectional stream, use the `gomu stream bidi` command.
This will send a stream of requests and expect a stream of responses.
```bash
$ gomu stream bidi helloworld Helloworld.BidiStream '{"stroke": 1}' '{"stroke": 2}' '{"stroke": 3}'
{"stroke":1}
{"stroke":2}
{"stroke":3}
```
## License
This software is published under the [MIT license][10].
[1]: https://github.com/asim/go-micro
[2]: https://golang.org/dl/
[3]: https://golang.org/cmd/go/#hdr-Compile_and_install_packages_and_dependencies
[4]: https://grpc.io/docs/protoc-installation/
[5]: https://micro.mu/github.com/golang/protobuf/protoc-gen-go
[6]: https://github.com/asim/go-micro/tree/master/cmd/protoc-gen-micro
[7]: https://www.jaegertracing.io/
[8]: https://github.com/jaegertracing/jaeger-client-go#environment-variables
[9]: https://skaffold.dev/
[10]: LICENSE
-63
View File
@@ -1,63 +0,0 @@
package call
import (
"context"
"encoding/json"
"fmt"
"strings"
"github.com/asim/go-micro/cmd/gomu/cmd"
"github.com/asim/go-micro/v3"
"github.com/asim/go-micro/v3/client"
"github.com/urfave/cli/v2"
)
func init() {
cmd.Register(&cli.Command{
Name: "call",
Usage: "Call a service, e.g. " + cmd.App().Name + " call helloworld Helloworld.Call '{\"name\": \"John\"}'",
Action: RunCall,
})
}
// RunCall calls a service endpoint and prints its response. Exits on error.
func RunCall(ctx *cli.Context) error {
args := ctx.Args().Slice()
if len(args) < 2 {
return cli.ShowSubcommandHelp(ctx)
}
service := args[0]
endpoint := args[1]
req := strings.Join(args[2:], " ")
if len(req) == 0 {
req = `{}`
}
d := json.NewDecoder(strings.NewReader(req))
d.UseNumber()
var creq map[string]interface{}
if err := d.Decode(&creq); err != nil {
return err
}
srv := micro.NewService()
srv.Init()
c := srv.Client()
request := c.NewRequest(service, endpoint, creq, client.WithContentType("application/json"))
var response map[string]interface{}
if err := c.Call(context.Background(), request, &response); err != nil {
return err
}
b, err := json.Marshal(response)
if err != nil {
return err
}
fmt.Println(string(b))
return nil
}
-11
View File
@@ -1,11 +0,0 @@
package cli
import (
_ "github.com/asim/go-micro/cmd/gomu/cmd/cli/call"
_ "github.com/asim/go-micro/cmd/gomu/cmd/cli/describe"
_ "github.com/asim/go-micro/cmd/gomu/cmd/cli/generate"
_ "github.com/asim/go-micro/cmd/gomu/cmd/cli/new"
_ "github.com/asim/go-micro/cmd/gomu/cmd/cli/run"
_ "github.com/asim/go-micro/cmd/gomu/cmd/cli/services"
_ "github.com/asim/go-micro/cmd/gomu/cmd/cli/stream"
)
-30
View File
@@ -1,30 +0,0 @@
package describe
import (
"github.com/asim/go-micro/cmd/gomu/cmd"
"github.com/urfave/cli/v2"
)
var flags []cli.Flag = []cli.Flag{
&cli.StringFlag{
Name: "format",
Value: "json",
Usage: "output a formatted description, e.g. json or yaml",
},
}
func init() {
cmd.Register(&cli.Command{
Name: "describe",
Usage: "Describe a resource",
Subcommands: []*cli.Command{
{
Name: "service",
Aliases: []string{"s"},
Usage: "Describe a service resource, e.g. " + cmd.App().Name + " describe service helloworld",
Action: Service,
Flags: flags,
},
},
})
}
-47
View File
@@ -1,47 +0,0 @@
package describe
import (
"encoding/json"
"fmt"
"github.com/asim/go-micro/cmd/gomu/cmd"
"github.com/urfave/cli/v2"
"gopkg.in/yaml.v2"
)
// Service fetches information for a service from the registry and prints it in
// either JSON or YAML, depending on the format flag passed. Exits on error.
func Service(ctx *cli.Context) error {
args := ctx.Args().Slice()
if len(args) < 1 {
return cli.ShowSubcommandHelp(ctx)
}
if ctx.String("format") != "json" && ctx.String("format") != "yaml" {
return cli.ShowSubcommandHelp(ctx)
}
r := *cmd.DefaultOptions().Registry
srvs, err := r.GetService(args[0])
if err != nil {
return err
}
if len(srvs) == 0 {
return fmt.Errorf("service %s not found", args[0])
}
for _, srv := range srvs {
var b []byte
var err error
if ctx.String("format") == "json" {
b, err = json.MarshalIndent(srv, "", " ")
} else if ctx.String("format") == "yaml" {
b, err = yaml.Marshal(srv)
}
if err != nil {
return err
}
fmt.Println(string(b))
}
return nil
}
-142
View File
@@ -1,142 +0,0 @@
package generate
import (
"bufio"
"fmt"
"os"
"strings"
"github.com/asim/go-micro/cmd/gomu/cmd"
"github.com/asim/go-micro/cmd/gomu/generator"
tmpl "github.com/asim/go-micro/cmd/gomu/generator/template"
"github.com/urfave/cli/v2"
)
func init() {
cmd.Register(&cli.Command{
Name: "generate",
Usage: "Generate project template files after the fact",
Subcommands: []*cli.Command{
{
Name: "kubernetes",
Usage: "Generate Kubernetes resource template files",
Action: Kubernetes,
},
{
Name: "skaffold",
Usage: "Generate Skaffold template files",
Action: Skaffold,
},
},
})
}
// Kubernetes generates Kubernetes resource template files in the current
// working directory. Exits on error.
func Kubernetes(ctx *cli.Context) error {
service, err := getService()
if err != nil {
return err
}
vendor, err := getServiceVendor(service)
if err != nil {
return err
}
g := generator.New(
generator.Service(service),
generator.Vendor(vendor),
generator.Directory("."),
generator.Client(strings.HasSuffix(service, "-client")),
)
files := []generator.File{
{"plugins.go", tmpl.Plugins},
{"resources/clusterrole.yaml", tmpl.KubernetesClusterRole},
{"resources/configmap.yaml", tmpl.KubernetesEnv},
{"resources/deployment.yaml", tmpl.KubernetesDeployment},
{"resources/rolebinding.yaml", tmpl.KubernetesRoleBinding},
}
g.Generate(files)
return nil
}
// Skaffold generates Skaffold template files in the current working directory.
// Exits on error.
func Skaffold(ctx *cli.Context) error {
service, err := getService()
if err != nil {
return err
}
vendor, err := getServiceVendor(service)
if err != nil {
return err
}
g := generator.New(
generator.Service(service),
generator.Vendor(vendor),
generator.Directory("."),
generator.Client(strings.HasSuffix(service, "-client")),
generator.Skaffold(true),
)
files := []generator.File{
{".dockerignore", tmpl.DockerIgnore},
{"go.mod", tmpl.Module},
{"plugins.go", tmpl.Plugins},
{"resources/clusterrole.yaml", tmpl.KubernetesClusterRole},
{"resources/configmap.yaml", tmpl.KubernetesEnv},
{"resources/deployment.yaml", tmpl.KubernetesDeployment},
{"resources/rolebinding.yaml", tmpl.KubernetesRoleBinding},
{"skaffold.yaml", tmpl.SkaffoldCFG},
}
if err := g.Generate(files); err != nil {
return err
}
fmt.Println("skaffold project template files generated")
return nil
}
func getService() (string, error) {
dir, err := os.Getwd()
if err != nil {
return "", err
}
return dir[strings.LastIndex(dir, "/")+1:], nil
}
func getServiceVendor(s string) (string, error) {
f, err := os.Open("go.mod")
if err != nil {
return "", err
}
defer f.Close()
line := ""
scanner := bufio.NewScanner(f)
for scanner.Scan() {
if strings.HasPrefix(scanner.Text(), "module ") {
line = scanner.Text()
break
}
}
if line == "" {
return "", nil
}
module := line[strings.LastIndex(line, " ")+1:]
if module == s {
return "", nil
}
return module[:strings.LastIndex(module, "/")] + "/", nil
}
-203
View File
@@ -1,203 +0,0 @@
package new
import (
"fmt"
"os"
"path"
"strings"
"github.com/asim/go-micro/cmd/gomu/cmd"
"github.com/asim/go-micro/cmd/gomu/generator"
tmpl "github.com/asim/go-micro/cmd/gomu/generator/template"
"github.com/urfave/cli/v2"
)
var flags []cli.Flag = []cli.Flag{
&cli.BoolFlag{
Name: "jaeger",
Usage: "Generate Jaeger tracer files",
},
&cli.BoolFlag{
Name: "kubernetes",
Usage: "Generate Kubernetes resource files",
},
&cli.BoolFlag{
Name: "skaffold",
Usage: "Generate Skaffold files",
},
}
// NewCommand returns a new new cli command.
func init() {
cmd.Register(&cli.Command{
Name: "new",
Usage: "Create a project template",
Subcommands: []*cli.Command{
{
Name: "client",
Usage: "Create a client template, e.g. " + cmd.App().Name + " new client [github.com/auditemarlow/]helloworld",
Action: Client,
Flags: flags,
},
{
Name: "function",
Usage: "Create a function template, e.g. " + cmd.App().Name + " new function [github.com/auditemarlow/]helloworld",
Action: Function,
Flags: flags,
},
{
Name: "service",
Usage: "Create a service template, e.g. " + cmd.App().Name + " new service [github.com/auditemarlow/]helloworld",
Action: Service,
Flags: flags,
},
},
})
}
func Client(ctx *cli.Context) error {
return createProject(ctx, "client")
}
// Function creates a new function project template. Exits on error.
func Function(ctx *cli.Context) error {
return createProject(ctx, "function")
}
// Service creates a new service project template. Exits on error.
func Service(ctx *cli.Context) error {
return createProject(ctx, "service")
}
func createProject(ctx *cli.Context, pt string) error {
arg := ctx.Args().First()
if len(arg) == 0 {
return cli.ShowSubcommandHelp(ctx)
}
client := pt == "client"
name, vendor := getNameAndVendor(arg)
dir := name
if client {
dir += "-client"
}
if path.IsAbs(dir) {
fmt.Println("must provide a relative path as service name")
return nil
}
if _, err := os.Stat(dir); !os.IsNotExist(err) {
return fmt.Errorf("%s already exists", dir)
}
fmt.Printf("creating %s %s\n", pt, name)
g := generator.New(
generator.Service(name),
generator.Vendor(vendor),
generator.Directory(dir),
generator.Client(client),
generator.Jaeger(ctx.Bool("jaeger")),
generator.Skaffold(ctx.Bool("skaffold")),
)
files := []generator.File{
{".dockerignore", tmpl.DockerIgnore},
{".gitignore", tmpl.GitIgnore},
{"Dockerfile", tmpl.Dockerfile},
{"Makefile", tmpl.Makefile},
{"go.mod", tmpl.Module},
}
switch pt {
case "client":
files = append(files, []generator.File{
{"main.go", tmpl.MainCLT},
}...)
case "function":
files = append(files, []generator.File{
{"handler/" + name + ".go", tmpl.HandlerFNC},
{"main.go", tmpl.MainFNC},
{"proto/" + name + ".proto", tmpl.ProtoFNC},
}...)
case "service":
files = append(files, []generator.File{
{"handler/" + name + ".go", tmpl.HandlerSRV},
{"main.go", tmpl.MainSRV},
{"proto/" + name + ".proto", tmpl.ProtoSRV},
}...)
default:
return fmt.Errorf("%s project type not supported", pt)
}
if ctx.Bool("kubernetes") || ctx.Bool("skaffold") {
files = append(files, []generator.File{
{"plugins.go", tmpl.Plugins},
{"resources/clusterrole.yaml", tmpl.KubernetesClusterRole},
{"resources/configmap.yaml", tmpl.KubernetesEnv},
{"resources/deployment.yaml", tmpl.KubernetesDeployment},
{"resources/rolebinding.yaml", tmpl.KubernetesRoleBinding},
}...)
}
if ctx.Bool("skaffold") {
files = append(files, []generator.File{
{"skaffold.yaml", tmpl.SkaffoldCFG},
}...)
}
if err := g.Generate(files); err != nil {
return err
}
var comments []string
if client {
comments = clientComments(name, dir)
} else {
comments = protoComments(name, dir)
}
for _, comment := range comments {
fmt.Println(comment)
}
return nil
}
func clientComments(name, dir string) []string {
return []string{
"cd " + dir,
"make tidy\n",
}
}
func protoComments(name, dir string) []string {
return []string{
"\ndownload protoc zip packages (protoc-$VERSION-$PLATFORM.zip) and install:\n",
"visit https://github.com/protocolbuffers/protobuf/releases/latest",
"\ndownload protobuf for go-micro:\n",
"go get -u google.golang.org/protobuf/proto",
"go install github.com/golang/protobuf/protoc-gen-go@latest",
"go install github.com/asim/go-micro/cmd/protoc-gen-micro/v3@latest",
"\ncompile the proto file " + name + ".proto:\n",
"cd " + dir,
"make proto tidy\n",
}
}
func getNameAndVendor(s string) (string, string) {
var n string
var v string
if i := strings.LastIndex(s, "/"); i == -1 {
n = s
v = ""
} else {
n = s[i+1:]
v = s[:i+1]
}
return n, v
}
-158
View File
@@ -1,158 +0,0 @@
package run
import (
"fmt"
"os"
"os/signal"
"path/filepath"
"strings"
"github.com/asim/go-micro/cmd/gomu/cmd"
"github.com/asim/go-micro/v3/runtime"
"github.com/asim/go-micro/v3/runtime/local/git"
"github.com/fsnotify/fsnotify"
"github.com/urfave/cli/v2"
)
var (
DefaultRetries = 3
flags []cli.Flag = []cli.Flag{
&cli.StringFlag{
Name: "command",
Usage: "command to execute",
},
&cli.StringFlag{
Name: "args",
Usage: "command arguments",
},
&cli.StringFlag{
Name: "type",
Usage: "the type of service to operate on",
},
}
)
func init() {
cmd.Register(&cli.Command{
Name: "run",
Usage: "Build and run a service continuously, e.g. gomu run [github.com/auditemarlow/helloworld]",
Flags: flags,
Action: Run,
})
}
// Run runs a service and watches the project directory for change events. On
// write, the service is restarted. Exits on error.
func Run(ctx *cli.Context) error {
wd, err := os.Getwd()
if err != nil {
return err
}
source, err := git.ParseSourceLocal(wd, ctx.Args().First())
if err != nil {
return err
}
svc := &runtime.Service{
Name: source.RuntimeName(),
Source: source.RuntimeSource(),
Version: source.Ref,
Metadata: make(map[string]string),
}
typ := ctx.String("type")
command := strings.TrimSpace(ctx.String("command"))
args := strings.TrimSpace(ctx.String("args"))
r := *cmd.DefaultCmd.Options().Runtime
var retries = DefaultRetries
if ctx.IsSet("retries") {
retries = ctx.Int("retries")
}
opts := []runtime.CreateOption{
runtime.WithOutput(os.Stdout),
runtime.WithRetries(retries),
runtime.CreateType(typ),
}
if len(command) > 0 {
opts = append(opts, runtime.WithCommand(command))
}
if len(args) > 0 {
opts = append(opts, runtime.WithArgs(args))
}
if err := r.Create(svc, opts...); err != nil {
return err
}
done := make(chan bool)
if r.String() == "local" {
sig := make(chan os.Signal)
signal.Notify(sig, os.Interrupt)
go func() {
<-sig
r.Delete(svc)
done <- true
}()
}
if source.Local {
watcher, err := fsnotify.NewWatcher()
if err != nil {
fmt.Println(err)
}
defer watcher.Close()
go func() {
for {
select {
case event, ok := <-watcher.Events:
if !ok {
return
}
if event.Op&fsnotify.Write == fsnotify.Write {
r.Update(svc)
}
if event.Op&fsnotify.Create == fsnotify.Create {
watcher.Add(event.Name)
}
if event.Op&fsnotify.Remove == fsnotify.Remove {
watcher.Remove(event.Name)
}
case err, ok := <-watcher.Errors:
if !ok {
return
}
fmt.Println("ERROR", err)
}
}
}()
var files []string
filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
files = append(files, path)
return nil
})
for _, file := range files {
if err := watcher.Add(file); err != nil {
return err
}
}
}
if r.String() == "local" {
<-done
}
return nil
}
-39
View File
@@ -1,39 +0,0 @@
package services
import (
"fmt"
"sort"
"github.com/asim/go-micro/cmd/gomu/cmd"
"github.com/urfave/cli/v2"
)
func init() {
cmd.Register(&cli.Command{
Name: "services",
Usage: "List services in the registry",
Action: List,
})
}
// List fetches running services from the registry and lists them. Exits on
// error.
func List(ctx *cli.Context) error {
r := *cmd.DefaultOptions().Registry
srvs, err := r.ListServices()
if err != nil {
return err
}
var services []string
for _, srv := range srvs {
services = append(services, srv.Name)
}
sort.Strings(services)
for _, srv := range services {
fmt.Println(srv)
}
return nil
}
-69
View File
@@ -1,69 +0,0 @@
package stream
import (
"encoding/json"
"fmt"
"strings"
"github.com/asim/go-micro/v3"
"github.com/asim/go-micro/v3/client"
"github.com/urfave/cli/v2"
)
// Bidirectional streams client requests and prints the server stream responses
// it receives. Exits on error.
func Bidirectional(ctx *cli.Context) error {
args := ctx.Args().Slice()
if len(args) < 2 {
return cli.ShowSubcommandHelp(ctx)
}
service := args[0]
endpoint := args[1]
requests := args[2:]
srv := micro.NewService()
srv.Init()
c := srv.Client()
var r interface{}
request := c.NewRequest(service, endpoint, r, client.WithContentType("application/json"))
var rsp map[string]interface{}
stream, err := c.Stream(ctx.Context, request)
if err != nil {
return err
}
for _, req := range requests {
d := json.NewDecoder(strings.NewReader(req))
d.UseNumber()
var creq map[string]interface{}
if err := d.Decode(&creq); err != nil {
return err
}
if err := stream.Send(creq); err != nil {
return err
}
err := stream.Recv(&rsp)
if err != nil {
return err
}
b, err := json.Marshal(rsp)
if err != nil {
return err
}
fmt.Println(string(b))
}
if stream.Error() != nil {
return stream.Error()
}
if err := stream.Close(); err != nil {
return err
}
return nil
}
-76
View File
@@ -1,76 +0,0 @@
package stream
import (
"context"
"encoding/json"
"fmt"
"io"
"strings"
"github.com/asim/go-micro/v3"
"github.com/asim/go-micro/v3/client"
"github.com/urfave/cli/v2"
)
// Server sends a single client request and prints the server stream responses
// it receives. Exits on error.
func Server(ctx *cli.Context) error {
args := ctx.Args().Slice()
if len(args) < 2 {
return cli.ShowSubcommandHelp(ctx)
}
service := args[0]
endpoint := args[1]
req := strings.Join(args[2:], " ")
if len(req) == 0 {
req = `{}`
}
d := json.NewDecoder(strings.NewReader(req))
d.UseNumber()
var creq map[string]interface{}
if err := d.Decode(&creq); err != nil {
return err
}
srv := micro.NewService()
srv.Init()
c := srv.Client()
var r interface{}
request := c.NewRequest(service, endpoint, r, client.WithContentType("application/json"))
stream, err := c.Stream(context.Background(), request)
if err != nil {
return err
}
if err := stream.Send(creq); err != nil {
return err
}
for stream.Error() == nil {
rsp := &map[string]interface{}{}
err := stream.Recv(rsp)
if err == io.EOF {
return nil
}
if err != nil {
return err
}
b, err := json.Marshal(rsp)
if err != nil {
return err
}
fmt.Println(string(b))
}
if stream.Error() != nil {
return stream.Error()
}
if err := stream.Close(); err != nil {
return err
}
return nil
}
-27
View File
@@ -1,27 +0,0 @@
package stream
import (
"github.com/asim/go-micro/cmd/gomu/cmd"
"github.com/urfave/cli/v2"
)
func init() {
cmd.Register(&cli.Command{
Name: "stream",
Usage: "Create a service stream",
Subcommands: []*cli.Command{
{
Name: "bidi",
Aliases: []string{"b"},
Usage: "Create a bidirectional service stream, e.g. " + cmd.App().Name + " stream bidirectional helloworld Helloworld.PingPong '{\"stroke\": 1}' '{\"stroke\": 2}'",
Action: Bidirectional,
},
{
Name: "server",
Aliases: []string{"s"},
Usage: "Create a server service stream, e.g. " + cmd.App().Name + " stream server helloworld Helloworld.ServerStream '{\"count\": 10}'",
Action: Server,
},
},
})
}
-118
View File
@@ -1,118 +0,0 @@
package cmd
import (
"fmt"
"os"
mcmd "github.com/asim/go-micro/v3/cmd"
"github.com/urfave/cli/v2"
)
var (
// DefaultCmd is the default, unmodified root command.
DefaultCmd Cmd = NewCmd()
name string = "gomu"
description string = "The Go Micro CLI tool"
version string = "latest"
)
// Cmd is the interface that wraps the cli app.
//
// Cmd embeds the Cmd interface from the github.com/asim/go-micro/v3/cmd
// package and adds a Run method.
//
// Run runs the cli app within this command and exits on error.
type Cmd interface {
mcmd.Cmd
Run() error
}
type cmd struct {
app *cli.App
opts mcmd.Options
}
// App returns the cli app within this command.
func (c *cmd) App() *cli.App {
return c.app
}
// Options returns the options set within this command.
func (c *cmd) Options() mcmd.Options {
return c.opts
}
// Init adds options, parses flags and exits on error.
func (c *cmd) Init(opts ...mcmd.Option) error {
return mcmd.Init(opts...)
}
// Run runs the cli app within this command and exits on error.
func (c *cmd) Run() error {
return c.app.Run(os.Args)
}
// DefaultOptions returns the options passed to the default command.
func DefaultOptions() mcmd.Options {
return DefaultCmd.Options()
}
// App returns the cli app within the default command.
func App() *cli.App {
return DefaultCmd.App()
}
// Register appends commands to the default app.
func Register(cmds ...*cli.Command) {
app := DefaultCmd.App()
app.Commands = append(app.Commands, cmds...)
}
// Run runs the cli app within the default command. On error, it prints the
// error message and exits.
func Run() {
if err := DefaultCmd.Run(); err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
}
// NewCmd returns a new command.
func NewCmd(opts ...mcmd.Option) Cmd {
options := mcmd.DefaultOptions()
// Clear the name, version and description parameters from the default
// options so the options passed may override them.
options.Name = ""
options.Version = ""
options.Description = ""
for _, o := range opts {
o(&options)
}
if len(options.Name) == 0 {
options.Name = name
}
if len(options.Description) == 0 {
options.Description = description
}
if len(options.Version) == 0 {
options.Version = version
}
c := new(cmd)
c.opts = options
c.app = cli.NewApp()
c.app.Name = c.opts.Name
c.app.Usage = c.opts.Description
c.app.Version = c.opts.Version
c.app.Flags = mcmd.DefaultFlags
if len(options.Version) == 0 {
c.app.HideVersion = true
}
return c
}
-47
View File
@@ -1,47 +0,0 @@
package jaeger
import (
"io"
"github.com/opentracing/opentracing-go"
jaegercfg "github.com/uber/jaeger-client-go/config"
)
// NewTracer returns a new Jaeger tracer based on the current configuration,
// using the given options, and a closer func that can be used to flush buffers
// before shutdown.
func NewTracer(opts ...Option) (opentracing.Tracer, io.Closer, error) {
options := newOptions(opts...)
cfg := &jaegercfg.Configuration{}
if options.FromEnv {
c, err := jaegercfg.FromEnv()
if err != nil {
return nil, nil, err
}
cfg = c
}
if options.Name != "" {
cfg.ServiceName = options.Name
}
var jOptions []jaegercfg.Option
if options.Logger != nil {
jOptions = append(jOptions, jaegercfg.Logger(options.Logger))
}
if options.Metrics != nil {
jOptions = append(jOptions, jaegercfg.Metrics(options.Metrics))
}
tracer, closer, err := cfg.NewTracer(jOptions...)
if err != nil {
return nil, nil, err
}
if options.GlobalTracer {
opentracing.SetGlobalTracer(tracer)
}
return tracer, closer, nil
}
-76
View File
@@ -1,76 +0,0 @@
package jaeger
import (
"github.com/uber/jaeger-client-go"
"github.com/uber/jaeger-lib/metrics"
)
var (
// DefaultLogger is the default Jaeger logger.
DefaultLogger = jaeger.StdLogger
// DefaultMetrics is the default Jaeger metrics factory.
DefaultMetrics = metrics.NullFactory
)
// Options represents the options passed to the Jaeger tracer.
type Options struct {
Name string
FromEnv bool
GlobalTracer bool
Logger jaeger.Logger
Metrics metrics.Factory
}
// Option manipulates the passed Options struct.
type Option func(o *Options)
func newOptions(opts ...Option) Options {
options := Options{
Logger: DefaultLogger,
Metrics: DefaultMetrics,
}
for _, o := range opts {
o(&options)
}
return options
}
// Name sets the service name for the Jaeger tracer.
func Name(s string) Option {
return func(o *Options) {
o.Name = s
}
}
// FromEnv determines whether the Jaeger tracer configuration should use
// environment variables.
func FromEnv(e bool) Option {
return func(o *Options) {
o.FromEnv = e
}
}
// GlobalTracer determines whether the Jaeger tracer should be set as the
// global tracer.
func GlobalTracer(e bool) Option {
return func(o *Options) {
o.GlobalTracer = e
}
}
// Logger sets the logger for the Jaeger tracer.
func Logger(l jaeger.Logger) Option {
return func(o *Options) {
o.Logger = l
}
}
// Metrics sets the metrics factory for the Jaeger tracer.
func Metrics(m metrics.Factory) Option {
return func(o *Options) {
o.Metrics = m
}
}
-20
View File
@@ -1,20 +0,0 @@
package trace
import (
"context"
"runtime"
"github.com/opentracing/opentracing-go"
)
// NewSpan accepts a context and returns an OpenTracing span. Can be used to
// nest spans.
func NewSpan(ctx context.Context) opentracing.Span {
pc := make([]uintptr, 10) // at least 1 entry needed
runtime.Callers(2, pc)
span := opentracing.StartSpan(
runtime.FuncForPC(pc[0]).Name(),
opentracing.ChildOf(opentracing.SpanFromContext(ctx).Context()),
)
return span
}
-79
View File
@@ -1,79 +0,0 @@
package generator
import (
"os"
"path/filepath"
"strings"
"text/template"
)
// Generator is the interface that generates project template files.
//
// Generate accepts a list of files and generates them based on their template.
type Generator interface {
Generate([]File) error
}
type generator struct {
opts Options
}
// File represents a file to generate.
type File struct {
// Path specifies where the file will reside.
Path string
// Template is the template used to generate the file.
Template string
}
// Generate generates project template files.
func (g *generator) Generate(files []File) error {
for _, file := range files {
fp := filepath.Join(g.opts.Directory, file.Path)
dir := filepath.Dir(fp)
if _, err := os.Stat(dir); os.IsNotExist(err) {
if err := os.MkdirAll(dir, 0755); err != nil {
return err
}
}
f, err := os.Create(fp)
if err != nil {
return err
}
fn := template.FuncMap{
"dehyphen": func(s string) string {
return strings.ReplaceAll(s, "-", "")
},
"lower": strings.ToLower,
"title": func(s string) string {
return strings.ReplaceAll(strings.Title(s), "-", "")
},
}
t, err := template.New(fp).Funcs(fn).Parse(file.Template)
if err != nil {
return err
}
err = t.Execute(f, g.opts)
if err != nil {
return err
}
}
return nil
}
// New returns a new generator struct.
func New(opts ...Option) Generator {
var options Options
for _, o := range opts {
o(&options)
}
return &generator{
opts: options,
}
}
-64
View File
@@ -1,64 +0,0 @@
package generator
// Options represents the options for the generator.
type Options struct {
// Service is the name of the service the generator will generate files
// for.
Service string
// Vendor is the service vendor.
Vendor string
// Directory is the directory where the files will be generated to.
Directory string
// Client determines whether or not the project is a client project.
Client bool
// Jaeger determines whether or not Jaeger integration is enabled.
Jaeger bool
// Jaeger determines whether or not Skaffold integration is enabled.
Skaffold bool
}
// Option manipulates the Options passed.
type Option func(o *Options)
// Service sets the service name.
func Service(s string) Option {
return func(o *Options) {
o.Service = s
}
}
// Vendor sets the service vendor.
func Vendor(v string) Option {
return func(o *Options) {
o.Vendor = v
}
}
// Directory sets the directory in which files are generated.
func Directory(d string) Option {
return func(o *Options) {
o.Directory = d
}
}
// Client sets whether or not the project is a client project.
func Client(c bool) Option {
return func(o *Options) {
o.Client = c
}
}
// Jaeger sets whether or not Jaeger integration is enabled.
func Jaeger(j bool) Option {
return func(o *Options) {
o.Jaeger = j
}
}
// Skaffold sets whether or not Skaffold integration is enabled.
func Skaffold(s bool) Option {
return func(o *Options) {
o.Skaffold = s
}
}
-25
View File
@@ -1,25 +0,0 @@
package template
// Dockerfile is the Dockerfile template used for new projects.
var Dockerfile = `FROM golang:alpine AS builder
ENV CGO_ENABLED=0 GOOS=linux
WORKDIR /go/src/{{.Service}}{{if .Client}}-client{{end}}
RUN apk --update --no-cache add ca-certificates gcc libtool make musl-dev protoc
COPY {{if not .Client}}Makefile {{end}}go.mod go.sum ./
RUN {{if not .Client}}make init && {{end}}go mod download
COPY . .
RUN make {{if not .Client}}proto {{end}}tidy build
FROM scratch
COPY --from=builder /etc/ssl/certs /etc/ssl/certs
COPY --from=builder /go/src/{{.Service}}{{if .Client}}-client{{end}}/{{.Service}}{{if .Client}}-client{{end}} /{{.Service}}{{if .Client}}-client{{end}}
ENTRYPOINT ["/{{.Service}}{{if .Client}}-client{{end}}"]
CMD []
`
// DockerIgnore is the .dockerignore template used for new projects.
var DockerIgnore = `.gitignore
Dockerfile{{if .Skaffold}}
resources/
skaffold.yaml{{end}}
`
-6
View File
@@ -1,6 +0,0 @@
package template
// GitIgnore is the .gitignore template used for new projects.
var GitIgnore = `# don't commit the service binary to vcs
{{.Service}}{{if .Client}}-client{{end}}
`
-89
View File
@@ -1,89 +0,0 @@
package template
// HandlerFNC is the handler template used for new function projects.
var HandlerFNC = `package handler
import (
"context"
log "github.com/asim/go-micro/v3/logger"
pb "{{.Vendor}}{{.Service}}/proto"
)
type {{title .Service}} struct{}
func (e *{{title .Service}}) Call(ctx context.Context, req *pb.CallRequest, rsp *pb.CallResponse) error {
log.Infof("Received {{title .Service}}.Call request: %v", req)
rsp.Msg = "Hello " + req.Name
return nil
}
`
// HandlerSRV is the handler template used for new service projects.
var HandlerSRV = `package handler
import (
"context"
"io"
"time"
log "github.com/asim/go-micro/v3/logger"
pb "{{.Vendor}}{{.Service}}/proto"
)
type {{title .Service}} struct{}
func (e *{{title .Service}}) Call(ctx context.Context, req *pb.CallRequest, rsp *pb.CallResponse) error {
log.Infof("Received {{title .Service}}.Call request: %v", req)
rsp.Msg = "Hello " + req.Name
return nil
}
func (e *{{title .Service}}) ClientStream(ctx context.Context, stream pb.{{title .Service}}_ClientStreamStream) error {
var count int64
for {
req, err := stream.Recv()
if err == io.EOF {
log.Infof("Got %v pings total", count)
return stream.SendMsg(&pb.ClientStreamResponse{Count: count})
}
if err != nil {
return err
}
log.Infof("Got ping %v", req.Stroke)
count++
}
}
func (e *{{title .Service}}) ServerStream(ctx context.Context, req *pb.ServerStreamRequest, stream pb.{{title .Service}}_ServerStreamStream) error {
log.Infof("Received {{title .Service}}.ServerStream request: %v", req)
for i := 0; i < int(req.Count); i++ {
log.Infof("Sending %d", i)
if err := stream.Send(&pb.ServerStreamResponse{
Count: int64(i),
}); err != nil {
return err
}
time.Sleep(time.Millisecond * 250)
}
return nil
}
func (e *{{title .Service}}) BidiStream(ctx context.Context, stream pb.{{title .Service}}_BidiStreamStream) error {
for {
req, err := stream.Recv()
if err == io.EOF {
return nil
}
if err != nil {
return err
}
log.Infof("Got ping %v", req.Stroke)
if err := stream.Send(&pb.BidiStreamResponse{Stroke: req.Stroke}); err != nil {
return err
}
}
}
`
-78
View File
@@ -1,78 +0,0 @@
package template
// KubernetesEnv is a Kubernetes configmap manifest template used for
// environment variables in new projects.
var KubernetesEnv = `---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{.Service}}{{if .Client}}-client{{end}}-env
data:
MICRO_REGISTRY: kubernetes
`
// KubernetesClusterRole is a Kubernetes cluster role manifest template
// required for the Kubernetes registry plugin to function correctly.
var KubernetesClusterRole = `---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: micro-registry
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- list
- patch
- watch
`
// KubernetesRoleBinding is a Kubernetes role binding manifest template
// required for the Kubernetes registry plugin to function correctly.
var KubernetesRoleBinding = `---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: micro-registry
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: micro-registry
subjects:
- kind: ServiceAccount
name: default
namespace: default
`
// KubernetesDeployment is a Kubernetes deployment manifest template used for
// new projects.
var KubernetesDeployment = `---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{.Service}}{{if .Client}}-client{{end}}
labels:
app: {{.Service}}{{if .Client}}-client{{end}}
spec:
replicas: 1
selector:
matchLabels:
app: {{.Service}}{{if .Client}}-client{{end}}
template:
metadata:
labels:
app: {{.Service}}{{if .Client}}-client{{end}}
spec:
containers:
- name: {{.Service}}{{if .Client}}-client{{end}}
image: {{.Service}}{{if .Client}}-client{{end}}:latest
envFrom:
- configMapRef:
name: {{.Service}}{{if .Client}}-client{{end}}-env
`
-144
View File
@@ -1,144 +0,0 @@
package template
// MainCLT is the main template used for new client projects.
var MainCLT = `package main
import (
"context"
"time"
pb "{{.Vendor}}{{lower .Service}}/proto"
"github.com/asim/go-micro/v3"
log "github.com/asim/go-micro/v3/logger"
)
var (
service = "{{lower .Service}}"
version = "latest"
)
func main() {
// Create service
srv := micro.NewService()
srv.Init()
// Create client
c := pb.NewHelloworldService(service, srv.Client())
for {
// Call service
rsp, err := c.Call(context.Background(), &pb.CallRequest{Name: "John"})
if err != nil {
log.Fatal(err)
}
log.Info(rsp)
time.Sleep(1 * time.Second)
}
}
`
// MainFNC is the main template used for new function projects.
var MainFNC = `package main
import (
"{{.Vendor}}{{.Service}}/handler"
{{if .Jaeger}} ot "github.com/asim/go-micro/plugins/wrapper/trace/opentracing/v3"
{{end}} "github.com/asim/go-micro/v3"
log "github.com/asim/go-micro/v3/logger"{{if .Jaeger}}
"github.com/asim/go-micro/cmd/gomu/debug/trace/jaeger"{{end}}
)
var (
service = "{{lower .Service}}"
version = "latest"
)
func main() {
{{if .Jaeger}} // Create tracer
tracer, closer, err := jaeger.NewTracer(
jaeger.Name(service),
jaeger.FromEnv(true),
jaeger.GlobalTracer(true),
)
if err != nil {
log.Fatal(err)
}
defer closer.Close()
{{end}} // Create function
fnc := micro.NewFunction(
micro.Name(service),
micro.Version(version),
{{if .Jaeger}} micro.WrapCall(ot.NewCallWrapper(tracer)),
micro.WrapClient(ot.NewClientWrapper(tracer)),
micro.WrapHandler(ot.NewHandlerWrapper(tracer)),
micro.WrapSubscriber(ot.NewSubscriberWrapper(tracer)),
{{end}} )
fnc.Init()
// Handle function
fnc.Handle(new(handler.{{title .Service}}))
// Run function
if err := fnc.Run(); err != nil {
log.Fatal(err)
}
}
`
// MainSRV is the main template used for new service projects.
var MainSRV = `package main
import (
"{{.Vendor}}{{.Service}}/handler"
pb "{{.Vendor}}{{.Service}}/proto"
{{if .Jaeger}} ot "github.com/asim/go-micro/plugins/wrapper/trace/opentracing/v3"
{{end}} "github.com/asim/go-micro/v3"
log "github.com/asim/go-micro/v3/logger"{{if .Jaeger}}
"github.com/asim/go-micro/cmd/gomu/debug/trace/jaeger"{{end}}
)
var (
service = "{{lower .Service}}"
version = "latest"
)
func main() {
{{if .Jaeger}} // Create tracer
tracer, closer, err := jaeger.NewTracer(
jaeger.Name(service),
jaeger.FromEnv(true),
jaeger.GlobalTracer(true),
)
if err != nil {
log.Fatal(err)
}
defer closer.Close()
{{end}} // Create service
srv := micro.NewService(
micro.Name(service),
micro.Version(version),
{{if .Jaeger}} micro.WrapCall(ot.NewCallWrapper(tracer)),
micro.WrapClient(ot.NewClientWrapper(tracer)),
micro.WrapHandler(ot.NewHandlerWrapper(tracer)),
micro.WrapSubscriber(ot.NewSubscriberWrapper(tracer)),
{{end}} )
srv.Init()
// Register handler
pb.Register{{title .Service}}Handler(srv.Server(), new(handler.{{title .Service}}))
// Run service
if err := srv.Run(); err != nil {
log.Fatal(err)
}
}
`
-31
View File
@@ -1,31 +0,0 @@
package template
// Makefile is the Makefile template used for new projects.
var Makefile = `GOPATH:=$(shell go env GOPATH)
.PHONY: init
init:
@go get -u google.golang.org/protobuf/proto
@go install github.com/golang/protobuf/protoc-gen-go@latest
@go install github.com/asim/go-micro/cmd/protoc-gen-micro/v3@latest
.PHONY: proto
proto:
@protoc --proto_path=. --micro_out=. --go_out=:. proto/{{.Service}}.proto
.PHONY: tidy
tidy:
@go mod tidy
.PHONY: build
build:
@go build -o {{.Service}}{{if .Client}}-client{{end}} *.go
.PHONY: test
test:
@go test -v ./... -cover
.PHONY: docker
docker:
@docker build -t {{.Service}}{{if .Client}}-client{{end}}:latest .
`
-17
View File
@@ -1,17 +0,0 @@
package template
// Module is the go.mod template used for new projects.
var Module = `module {{.Vendor}}{{.Service}}{{if .Client}}-client{{end}}
go 1.16
require (
github.com/asim/go-micro/v3 v3.5.2
)
// This can be removed once etcd becomes go gettable, version 3.4 and 3.5 is not,
// see https://github.com/etcd-io/etcd/issues/11154 and https://github.com/etcd-io/etcd/issues/11931.
replace google.golang.org/grpc => google.golang.org/grpc v1.26.0{{if .Vendor}}{{if not .Skaffold}}
replace {{.Vendor}}{{lower .Service}} => ../{{lower .Service}}{{end}}{{end}}
`
-9
View File
@@ -1,9 +0,0 @@
package template
// Plugins is the plugins template used for new projects.
var Plugins = `package main
import (
_ "github.com/asim/go-micro/plugins/registry/kubernetes/v3"
)
`
-68
View File
@@ -1,68 +0,0 @@
package template
// ProtoFNC is the .proto file template used for new function projects.
var ProtoFNC = `syntax = "proto3";
package {{dehyphen .Service}};
option go_package = "./proto;{{dehyphen .Service}}";
service {{title .Service}} {
rpc Call(CallRequest) returns (CallResponse) {}
}
message CallRequest {
string name = 1;
}
message CallResponse {
string msg = 1;
}
`
// ProtoSRV is the .proto file template used for new service projects.
var ProtoSRV = `syntax = "proto3";
package {{dehyphen .Service}};
option go_package = "./proto;{{dehyphen .Service}}";
service {{title .Service}} {
rpc Call(CallRequest) returns (CallResponse) {}
rpc ClientStream(stream ClientStreamRequest) returns (ClientStreamResponse) {}
rpc ServerStream(ServerStreamRequest) returns (stream ServerStreamResponse) {}
rpc BidiStream(stream BidiStreamRequest) returns (stream BidiStreamResponse) {}
}
message CallRequest {
string name = 1;
}
message CallResponse {
string msg = 1;
}
message ClientStreamRequest {
int64 stroke = 1;
}
message ClientStreamResponse {
int64 count = 1;
}
message ServerStreamRequest {
int64 count = 1;
}
message ServerStreamResponse {
int64 count = 1;
}
message BidiStreamRequest {
int64 stroke = 1;
}
message BidiStreamResponse {
int64 stroke = 1;
}
`
-17
View File
@@ -1,17 +0,0 @@
package template
// SkaffoldCFG is the Skaffold config template used for new projects.
var SkaffoldCFG = `---
apiVersion: skaffold/v2beta21
kind: Config
metadata:
name: {{.Service}}{{if .Client}}-client{{end}}
build:
artifacts:
- image: {{.Service}}{{if .Client}}-client{{end}}
deploy:
kubectl:
manifests:
- resources/*.yaml
`
-14
View File
@@ -1,14 +0,0 @@
module github.com/asim/go-micro/cmd/gomu
go 1.16
require (
github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect
github.com/asim/go-micro/v3 v3.6.1-0.20210831082736-088ccb50019c
github.com/fsnotify/fsnotify v1.4.9
github.com/opentracing/opentracing-go v1.2.0
github.com/uber/jaeger-client-go v2.29.1+incompatible
github.com/uber/jaeger-lib v2.4.1+incompatible
github.com/urfave/cli/v2 v2.3.0
gopkg.in/yaml.v2 v2.4.0
)
-12
View File
@@ -1,12 +0,0 @@
package main
import (
"github.com/asim/go-micro/cmd/gomu/cmd"
// register commands
_ "github.com/asim/go-micro/cmd/gomu/cmd/cli"
)
func main() {
cmd.Run()
}
+13 -13
View File
@@ -3,19 +3,19 @@ package cmd
import (
"context"
"github.com/asim/go-micro/v3/auth"
"github.com/asim/go-micro/v3/broker"
"github.com/asim/go-micro/v3/cache"
"github.com/asim/go-micro/v3/client"
"github.com/asim/go-micro/v3/config"
"github.com/asim/go-micro/v3/debug/profile"
"github.com/asim/go-micro/v3/debug/trace"
"github.com/asim/go-micro/v3/registry"
"github.com/asim/go-micro/v3/runtime"
"github.com/asim/go-micro/v3/selector"
"github.com/asim/go-micro/v3/server"
"github.com/asim/go-micro/v3/store"
"github.com/asim/go-micro/v3/transport"
"go-micro.dev/v4/auth"
"go-micro.dev/v4/broker"
"go-micro.dev/v4/cache"
"go-micro.dev/v4/client"
"go-micro.dev/v4/config"
"go-micro.dev/v4/debug/profile"
"go-micro.dev/v4/debug/trace"
"go-micro.dev/v4/registry"
"go-micro.dev/v4/runtime"
"go-micro.dev/v4/selector"
"go-micro.dev/v4/server"
"go-micro.dev/v4/store"
"go-micro.dev/v4/transport"
)
type Options struct {
+10 -4
View File
@@ -5,7 +5,7 @@ This is protobuf code generation for go-micro. We use protoc-gen-micro to reduce
## Install
```
go install github.com/asim/go-micro/cmd/protoc-gen-micro/v3@latest
go install go-micro.dev/v4/cmd/protoc-gen-micro@v4
```
Also required:
@@ -20,6 +20,9 @@ Define your service as `greeter.proto`
```
syntax = "proto3";
package greeter;
option go_package = "/proto;greeter";
service Greeter {
rpc Hello(Request) returns (Response) {}
}
@@ -36,7 +39,7 @@ message Response {
Generate the code
```
protoc --proto_path=$GOPATH/src:. --micro_out=. --go_out=. greeter.proto
protoc --proto_path=. --micro_out=. --go_out=. greeter.proto
```
Your output result should be:
@@ -80,7 +83,7 @@ If you see an error about `protoc-gen-micro` not being found or executable, it's
Alternative specify the Go plugin paths as arguments to the `protoc` command
```
protoc --plugin=protoc-gen-go=$GOPATH/bin/protoc-gen-go --plugin=protoc-gen-micro=$GOPATH/bin/protoc-gen-micro --proto_path=$GOPATH/src:. --micro_out=. --go_out=. greeter.proto
protoc --plugin=protoc-gen-go=$GOPATH/bin/protoc-gen-go --plugin=protoc-gen-micro=$GOPATH/bin/protoc-gen-micro --proto_path=. --micro_out=. --go_out=. greeter.proto
```
### Endpoint
@@ -95,6 +98,9 @@ Usage:
```diff
syntax = "proto3";
package greeter;
option go_package = "/proto;greeter";
import "google/api/annotations.proto";
service Greeter {
@@ -112,7 +118,7 @@ message Response {
}
```
The proto generates a `RegisterGreeterHandler` function with a [api.Endpoint](https://godoc.org/github.com/asim/go-micro/v3/api#Endpoint).
The proto generates a `RegisterGreeterHandler` function with a [api.Endpoint](https://godoc.org/go-micro.dev/v3/api#Endpoint).
```diff
func RegisterGreeterHandler(s server.Server, hdlr GreeterHandler, opts ...server.HandlerOption) error {
@@ -12,9 +12,9 @@ import (
import (
context "context"
api "github.com/asim/go-micro/v3/api"
client "github.com/asim/go-micro/v3/client"
server "github.com/asim/go-micro/v3/server"
api "go-micro.dev/v4/api"
client "go-micro.dev/v4/client"
server "go-micro.dev/v4/server"
)
// Reference imports to suppress errors if they are not otherwise used.
+25 -5
View File
@@ -305,7 +305,7 @@ func (d *FileDescriptor) goPackageOption() (impPath GoImportPath, pkg GoPackageN
}
// goFileName returns the output name for the generated Go file.
func (d *FileDescriptor) goFileName(pathType pathType) string {
func (d *FileDescriptor) goFileName(pathType pathType, moduleRoot string) string {
name := *d.Name
if ext := path.Ext(name); ext == ".proto" || ext == ".protodevel" {
name = name[:len(name)-len(ext)]
@@ -319,9 +319,18 @@ func (d *FileDescriptor) goFileName(pathType pathType) string {
// Does the file have a "go_package" option?
// If it does, it may override the filename.
if impPath, _, ok := d.goPackageOption(); ok && impPath != "" {
// Replace the existing dirname with the declared import path.
_, name = path.Split(name)
name = path.Join(string(impPath), name)
if pathType == pathModuleRoot && moduleRoot != "" {
root := moduleRoot
if !strings.HasSuffix(root, "/") {
root = root + "/"
}
name = strings.TrimPrefix(name, root)
} else {
// Replace the existing dirname with the declared import path.
_, name = path.Split(name)
name = path.Join(string(impPath), name)
}
return name
}
@@ -405,6 +414,7 @@ type Generator struct {
PackageImportPath string // Go import path of the package we're generating code for
ImportPrefix string // String to prefix to imported package file names.
ImportMap map[string]string // Mapping from .proto file name to import path
ModuleRoot string // Mapping from the module prefix
Pkg map[string]string // The names under which we import support packages
@@ -429,6 +439,7 @@ type pathType int
const (
pathTypeImport pathType = iota
pathTypeSourceRelative
pathModuleRoot
)
// New creates a new generator and allocates the request and response protobufs.
@@ -475,11 +486,20 @@ func (g *Generator) CommandLineParameters(parameter string) {
g.ImportPrefix = v
case "import_path":
g.PackageImportPath = v
case "module":
if g.pathType == pathTypeSourceRelative {
g.Fail(fmt.Sprintf(`Cannot set module=%q after paths=source_relative`, v))
}
g.pathType = pathModuleRoot
g.ModuleRoot = v
case "paths":
switch v {
case "import":
g.pathType = pathTypeImport
case "source_relative":
if g.pathType == pathModuleRoot {
g.Fail("Cannot set paths=source_relative after setting module=<module_root>")
}
g.pathType = pathTypeSourceRelative
default:
g.Fail(fmt.Sprintf(`Unknown path type %q: want "import" or "source_relative".`, v))
@@ -1069,7 +1089,7 @@ func (g *Generator) GenerateAllFiles() {
if !g.writeOutput {
continue
}
fname := file.goFileName(g.pathType)
fname := file.goFileName(g.pathType, g.ModuleRoot)
g.Response.File = append(g.Response.File, &plugin.CodeGeneratorResponse_File{
Name: proto.String(fname),
Content: proto.String(g.String()),
-9
View File
@@ -1,9 +0,0 @@
module github.com/asim/go-micro/cmd/protoc-gen-micro/v3
go 1.16
require (
github.com/asim/go-micro/v3 v3.6.0
google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8
google.golang.org/protobuf v1.27.1
)
+4 -4
View File
@@ -49,11 +49,11 @@
package main
import (
"io/ioutil"
"io"
"os"
"github.com/asim/go-micro/cmd/protoc-gen-micro/v3/generator"
_ "github.com/asim/go-micro/cmd/protoc-gen-micro/v3/plugin/micro"
"go-micro.dev/v4/cmd/protoc-gen-micro/generator"
_ "go-micro.dev/v4/cmd/protoc-gen-micro/plugin/micro"
"google.golang.org/protobuf/proto"
)
@@ -63,7 +63,7 @@ func main() {
// report failure.
g := generator.New()
data, err := ioutil.ReadAll(os.Stdin)
data, err := io.ReadAll(os.Stdin)
if err != nil {
g.Error(err, "reading input")
}
+20 -7
View File
@@ -6,7 +6,7 @@ import (
"strconv"
"strings"
"github.com/asim/go-micro/cmd/protoc-gen-micro/v3/generator"
"go-micro.dev/v4/cmd/protoc-gen-micro/generator"
options "google.golang.org/genproto/googleapis/api/annotations"
"google.golang.org/protobuf/proto"
pb "google.golang.org/protobuf/types/descriptorpb"
@@ -15,10 +15,10 @@ import (
// Paths for packages used by code generated in this file,
// relative to the import_prefix of the generator.Generator.
const (
apiPkgPath = "github.com/asim/go-micro/v3/api"
apiPkgPath = "go-micro.dev/v4/api"
contextPkgPath = "context"
clientPkgPath = "github.com/asim/go-micro/v3/client"
serverPkgPath = "github.com/asim/go-micro/v3/server"
clientPkgPath = "go-micro.dev/v4/client"
serverPkgPath = "go-micro.dev/v4/server"
)
func init() {
@@ -131,7 +131,8 @@ func (g *micro) generateService(file *generator.FileDescriptor, service *pb.Serv
origServName := service.GetName()
serviceName := strings.ToLower(service.GetName())
if pkg := file.GetPackage(); pkg != "" {
pkg := file.GetPackage()
if pkg != "" {
serviceName = pkg
}
servName := generator.CamelCase(origServName)
@@ -209,7 +210,7 @@ func (g *micro) generateService(file *generator.FileDescriptor, service *pb.Serv
descExpr = fmt.Sprintf("&%s.Streams[%d]", serviceDescVar, streamIndex)
streamIndex++
}
g.generateClientMethod(serviceName, servName, serviceDescVar, method, descExpr)
g.generateClientMethod(pkg, serviceName, servName, serviceDescVar, method, descExpr)
}
g.P("// Server API for ", servName, " service")
@@ -331,8 +332,12 @@ func (g *micro) generateClientSignature(servName string, method *pb.MethodDescri
return fmt.Sprintf("%s(ctx %s.Context%s, opts ...%s.CallOption) (%s, error)", methName, contextPkg, reqArg, clientPkg, respName)
}
func (g *micro) generateClientMethod(reqServ, servName, serviceDescVar string, method *pb.MethodDescriptorProto, descExpr string) {
func (g *micro) generateClientMethod(pkg, reqServ, servName, serviceDescVar string, method *pb.MethodDescriptorProto, descExpr string) {
reqMethod := fmt.Sprintf("%s.%s", servName, method.GetName())
useGrpc := g.gen.Param["use_grpc"]
if useGrpc != "" {
reqMethod = fmt.Sprintf("/%s.%s/%s", pkg, servName, method.GetName())
}
methName := generator.CamelCase(method.GetName())
inType := g.typeName(method.GetInputType())
outType := g.typeName(method.GetOutputType())
@@ -363,6 +368,8 @@ func (g *micro) generateClientMethod(reqServ, servName, serviceDescVar string, m
if !method.GetClientStreaming() {
g.P("if err := stream.Send(in); err != nil { return nil, err }")
// TODO: currently only grpc support CloseSend
// g.P("if err := stream.CloseSend(); err != nil { return nil, err }")
}
g.P("return &", streamType, "{stream}, nil")
@@ -377,6 +384,7 @@ func (g *micro) generateClientMethod(reqServ, servName, serviceDescVar string, m
g.P("Context() context.Context")
g.P("SendMsg(interface{}) error")
g.P("RecvMsg(interface{}) error")
g.P("CloseSend() error")
g.P("Close() error")
if genSend {
@@ -393,6 +401,11 @@ func (g *micro) generateClientMethod(reqServ, servName, serviceDescVar string, m
g.P("}")
g.P()
g.P("func (x *", streamType, ") CloseSend() error {")
g.P("return x.stream.CloseSend()")
g.P("}")
g.P()
g.P("func (x *", streamType, ") Close() error {")
g.P("return x.stream.Close()")
g.P("}")
+2 -3
View File
@@ -4,9 +4,8 @@ package bytes
import (
"fmt"
"io"
"io/ioutil"
"github.com/asim/go-micro/v3/codec"
"go-micro.dev/v4/codec"
)
type Codec struct {
@@ -24,7 +23,7 @@ func (c *Codec) ReadHeader(m *codec.Message, t codec.MessageType) error {
func (c *Codec) ReadBody(b interface{}) error {
// read bytes
buf, err := ioutil.ReadAll(c.Conn)
buf, err := io.ReadAll(c.Conn)
if err != nil {
return err
}
+3 -1
View File
@@ -1,7 +1,7 @@
package bytes
import (
"github.com/asim/go-micro/v3/codec"
"go-micro.dev/v4/codec"
)
type Marshaler struct{}
@@ -27,8 +27,10 @@ func (n Marshaler) Unmarshal(d []byte, v interface{}) error {
switch ve := v.(type) {
case *[]byte:
*ve = d
return nil
case *Message:
ve.Body = d
return nil
}
return codec.ErrInvalidMessage
}
+1 -1
View File
@@ -8,8 +8,8 @@ import (
"io"
"strings"
"github.com/asim/go-micro/v3/codec"
"github.com/golang/protobuf/proto"
"go-micro.dev/v4/codec"
)
type Codec struct {
+1 -1
View File
@@ -5,9 +5,9 @@ import (
"encoding/json"
"io"
"github.com/asim/go-micro/v3/codec"
"github.com/golang/protobuf/jsonpb"
"github.com/golang/protobuf/proto"
"go-micro.dev/v4/codec"
)
type Codec struct {

Some files were not shown because too many files have changed in this diff Show More