diff options
author | Valery Piashchynski <[email protected]> | 2021-09-07 18:12:26 +0300 |
---|---|---|
committer | Valery Piashchynski <[email protected]> | 2021-09-07 18:12:26 +0300 |
commit | 2f41909aeb6a01ae1a0b5ebabe9a9afc1360744a (patch) | |
tree | 9609019ad2ba4b6ae3a241aa5e6f68872b89feaf | |
parent | 6749db4a2d39fa70b426bcf50edf66a176c07f57 (diff) |
Initial commit for the GRPC plugin
Signed-off-by: Valery Piashchynski <[email protected]>
28 files changed, 1042 insertions, 19 deletions
diff --git a/.golangci.yml b/.golangci.yml index f6ead63e..f623ed70 100755 --- a/.golangci.yml +++ b/.golangci.yml @@ -91,3 +91,4 @@ issues: - noctx - gosimple - revive + - gochecknoinits @@ -20,8 +20,10 @@ test_coverage: go test -v -race -cover -tags=debug -coverpkg=./... -coverprofile=./coverage-ci/server_cmd.txt -covermode=atomic ./plugins/server go test -v -race -cover -tags=debug -coverpkg=./... -coverprofile=./coverage-ci/struct_jobs.txt -covermode=atomic ./plugins/jobs/job go test -v -race -cover -tags=debug -coverpkg=./... -coverprofile=./coverage-ci/pipeline_jobs.txt -covermode=atomic ./plugins/jobs/pipeline + go test -v -race -cover -tags=debug -coverpkg=./... -coverprofile=./coverage-ci/grpc_plugin.txt -covermode=atomic ./plugins/grpc go test -v -race -cover -tags=debug -coverpkg=./... -coverprofile=./coverage-ci/jobs_core.txt -covermode=atomic ./tests/plugins/jobs go test -v -race -cover -tags=debug -coverpkg=./... -coverprofile=./coverage-ci/kv_plugin.txt -covermode=atomic ./tests/plugins/kv + go test -v -race -cover -tags=debug -coverpkg=./... -coverprofile=./coverage-ci/grpc_plugin.txt -covermode=atomic ./tests/plugins/grpc go test -v -race -cover -tags=debug -coverpkg=./... -coverprofile=./coverage-ci/broadcast_plugin.txt -covermode=atomic ./tests/plugins/broadcast go test -v -race -cover -tags=debug -coverpkg=./... -coverprofile=./coverage-ci/websockets.txt -covermode=atomic ./tests/plugins/websockets go test -v -race -cover -tags=debug -coverpkg=./... -coverprofile=./coverage-ci/http.txt -covermode=atomic ./tests/plugins/http @@ -53,11 +55,13 @@ test: ## Run application tests go test -v -race -tags=debug ./plugins/http/config go test -v -race -tags=debug ./plugins/server go test -v -race -tags=debug ./plugins/jobs/job + go test -v -race -tags=debug ./tests/plugins/grpc go test -v -race -tags=debug ./tests/plugins/jobs go test -v -race -tags=debug ./tests/plugins/kv go test -v -race -tags=debug ./tests/plugins/broadcast go test -v -race -tags=debug ./tests/plugins/websockets go test -v -race -tags=debug ./plugins/websockets + go test -v -race -tags=debug ./plugins/grpc go test -v -race -tags=debug ./tests/plugins/http go test -v -race -tags=debug ./tests/plugins/informer go test -v -race -tags=debug ./tests/plugins/reload @@ -6,9 +6,9 @@ require ( github.com/Shopify/toxiproxy v2.1.4+incompatible // ========= AWS SDK v2 github.com/aws/aws-sdk-go-v2 v1.9.0 - github.com/aws/aws-sdk-go-v2/config v1.7.0 + github.com/aws/aws-sdk-go-v2/config v1.8.0 github.com/aws/aws-sdk-go-v2/credentials v1.4.0 - github.com/aws/aws-sdk-go-v2/service/sqs v1.8.0 + github.com/aws/aws-sdk-go-v2/service/sqs v1.9.0 github.com/aws/smithy-go v1.8.0 // ===================== github.com/beanstalkd/go-beanstalk v0.1.0 @@ -37,9 +37,10 @@ require ( go.etcd.io/bbolt v1.3.6 go.uber.org/multierr v1.7.0 go.uber.org/zap v1.19.0 - golang.org/x/net v0.0.0-20210825183410-e898025ed96a + golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e + golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34 + google.golang.org/grpc v1.40.0 google.golang.org/protobuf v1.27.1 gopkg.in/natefinch/lumberjack.v2 v2.0.0 ) @@ -62,12 +63,12 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/magiconair/properties v1.8.5 // indirect github.com/mattn/go-colorable v0.1.8 // indirect - github.com/mattn/go-isatty v0.0.13 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/mitchellh/mapstructure v1.4.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.1 // indirect - github.com/pelletier/go-toml v1.9.3 // indirect + github.com/pelletier/go-toml v1.9.4 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.30.0 // indirect @@ -87,7 +88,7 @@ require ( go.uber.org/atomic v1.9.0 // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/tools v0.1.5 // indirect - gopkg.in/ini.v1 v1.62.0 // indirect + gopkg.in/ini.v1 v1.63.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) @@ -40,6 +40,7 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= @@ -59,8 +60,8 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aws/aws-sdk-go-v2 v1.9.0 h1:+S+dSqQCN3MSU5vJRu1HqHrq00cJn6heIMU7X9hcsoo= github.com/aws/aws-sdk-go-v2 v1.9.0/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= -github.com/aws/aws-sdk-go-v2/config v1.7.0 h1:J2cZ7qe+3IpqBEXnHUrFrOjoB9BlsXg7j53vxcl5IVg= -github.com/aws/aws-sdk-go-v2/config v1.7.0/go.mod h1:w9+nMZ7soXCe5nT46Ri354SNhXDQ6v+V5wqDjnZE+GY= +github.com/aws/aws-sdk-go-v2/config v1.8.0 h1:O8EMFBOl6tue5gdJJV6U3Ikyl3lqgx6WrulCYrcy2SQ= +github.com/aws/aws-sdk-go-v2/config v1.8.0/go.mod h1:w9+nMZ7soXCe5nT46Ri354SNhXDQ6v+V5wqDjnZE+GY= github.com/aws/aws-sdk-go-v2/credentials v1.4.0 h1:kmvesfjY861FzlCU9mvAfe01D9aeXcG2ZuC+k9F2YLM= github.com/aws/aws-sdk-go-v2/credentials v1.4.0/go.mod h1:dgGR+Qq7Wjcd4AOAW5Rf5Tnv3+x7ed6kETXyS9WCuAY= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.5.0 h1:OxTAgH8Y4BXHD6PGCJ8DHx2kaZPCQfSTqmDsdRZFezE= @@ -69,8 +70,8 @@ github.com/aws/aws-sdk-go-v2/internal/ini v1.2.2 h1:d95cddM3yTm4qffj3P6EnP+TzX1S github.com/aws/aws-sdk-go-v2/internal/ini v1.2.2/go.mod h1:BQV0agm+JEhqR+2RT5e1XTFIDcAAV0eW6z2trp+iduw= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.0 h1:VNJ5NLBteVXEwE2F1zEXVmyIH58mZ6kIQGJoC7C+vkg= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.0/go.mod h1:R1KK+vY8AfalhG1AOu5e35pOD2SdoPKQCFLTvnxiohk= -github.com/aws/aws-sdk-go-v2/service/sqs v1.8.0 h1:BI05Jbkaqp5IDxiobr3B59mX07lfpLJDv5NwAEx3wSs= -github.com/aws/aws-sdk-go-v2/service/sqs v1.8.0/go.mod h1:BXA1CVaEd9TBOQ8G2ke7lMWdVggAeh35+h2HDO50z7s= +github.com/aws/aws-sdk-go-v2/service/sqs v1.9.0 h1:g6EHC3RFpgbRR8/Yk6BTbzfPn+E3o6J3zWPrcjvVJTw= +github.com/aws/aws-sdk-go-v2/service/sqs v1.9.0/go.mod h1:BXA1CVaEd9TBOQ8G2ke7lMWdVggAeh35+h2HDO50z7s= github.com/aws/aws-sdk-go-v2/service/sso v1.4.0 h1:sHXMIKYS6YiLPzmKSvDpPmOpJDHxmAUgbiF49YNVztg= github.com/aws/aws-sdk-go-v2/service/sso v1.4.0/go.mod h1:+1fpWnL96DL23aXPpMGbsmKe8jLTEfbjuQoA4WS1VaA= github.com/aws/aws-sdk-go-v2/service/sts v1.7.0 h1:1at4e5P+lvHNl2nUktdM2/v+rpICg/QSEr9TO/uW9vU= @@ -92,6 +93,8 @@ github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQ github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -102,6 +105,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -115,6 +119,7 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fasthttp/websocket v1.4.3 h1:qjhRJ/rTy4KB8oBxljEC00SDt6HUY9jLRfM601SUdS4= github.com/fasthttp/websocket v1.4.3/go.mod h1:5r4oKssgS7W6Zn6mPWap3NWzNPJNzUUh3baWTOhcYQk= @@ -280,8 +285,8 @@ github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= -github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= @@ -314,8 +319,9 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.15.0 h1:WjP/FQ/sk43MRmnEcT+MlDw2TFvkrXlprrPST/IudjU= github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= +github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -364,6 +370,7 @@ github.com/smartystreets/assertions v1.1.1 h1:T/YLemO5Yp7KPzS+lVtu+WsHn8yoSwTfIt github.com/smartystreets/assertions v1.1.1/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= @@ -428,6 +435,7 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -527,8 +535,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210825183410-e898025ed96a h1:bRuuGXV8wwSdGTB+CtJf+FjgO1APK1CoO39T4BN/XBw= -golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f h1:w6wWR0H+nyVpbSAQbzVEIACVyr/h8l/BEkY6Sokc7Eg= +golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -614,8 +622,8 @@ golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e h1:XMgFehsDnnLGtjvjOfqWSUzt0alpTR1RSEuznObga2c= -golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34 h1:GkvMjFtXUmahfDtashnc1mnrCtuBVcwse5QV2lUk/tI= +golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -782,6 +790,8 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -804,8 +814,9 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.38.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.63.0 h1:2t0h8NA59dpVQpa5Yh8cIcR6nHAeBIEk0zlLVqfw4N4= +gopkg.in/ini.v1 v1.63.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= diff --git a/plugins/grpc/codec.go b/plugins/grpc/codec.go new file mode 100644 index 00000000..5938e238 --- /dev/null +++ b/plugins/grpc/codec.go @@ -0,0 +1,35 @@ +package grpc + +import "google.golang.org/grpc/encoding" + +type rawMessage []byte + +func (r rawMessage) Reset() {} +func (rawMessage) ProtoMessage() {} +func (rawMessage) String() string { return "rawMessage" } + +type codec struct{ base encoding.Codec } + +// Marshal returns the wire format of v. rawMessages would be returned without encoding. +func (c *codec) Marshal(v interface{}) ([]byte, error) { + if raw, ok := v.(rawMessage); ok { + return raw, nil + } + + return c.base.Marshal(v) +} + +// Unmarshal parses the wire format into v. rawMessages would not be unmarshalled. +func (c *codec) Unmarshal(data []byte, v interface{}) error { + if raw, ok := v.(*rawMessage); ok { + *raw = data + return nil + } + + return c.base.Unmarshal(data, v) +} + +// String return codec name. +func (c *codec) String() string { + return "raw:" + c.base.Name() +} diff --git a/plugins/grpc/codec_test.go b/plugins/grpc/codec_test.go new file mode 100644 index 00000000..5f94b745 --- /dev/null +++ b/plugins/grpc/codec_test.go @@ -0,0 +1,79 @@ +package grpc + +import ( + "testing" + + json "github.com/json-iterator/go" + "github.com/stretchr/testify/assert" +) + +type jsonCodec struct{} + +func (jsonCodec) Marshal(v interface{}) ([]byte, error) { + return json.Marshal(v) +} + +func (jsonCodec) Unmarshal(data []byte, v interface{}) error { + return json.Unmarshal(data, v) +} + +func (jsonCodec) Name() string { + return "json" +} + +func TestCodec_String(t *testing.T) { + c := codec{jsonCodec{}} + + assert.Equal(t, "raw:json", c.String()) + + r := rawMessage{} + r.Reset() + r.ProtoMessage() + assert.Equal(t, "rawMessage", r.String()) +} + +func TestCodec_Unmarshal_ByPass(t *testing.T) { + c := codec{jsonCodec{}} + + s := struct { + Name string + }{} + + assert.NoError(t, c.Unmarshal([]byte(`{"name":"name"}`), &s)) + assert.Equal(t, "name", s.Name) +} + +func TestCodec_Marshal_ByPass(t *testing.T) { + c := codec{jsonCodec{}} + + s := struct { + Name string + }{ + Name: "name", + } + + d, err := c.Marshal(s) + assert.NoError(t, err) + + assert.Equal(t, `{"Name":"name"}`, string(d)) +} + +func TestCodec_Unmarshal_Raw(t *testing.T) { + c := codec{jsonCodec{}} + + s := rawMessage{} + + assert.NoError(t, c.Unmarshal([]byte(`{"name":"name"}`), &s)) + assert.Equal(t, `{"name":"name"}`, string(s)) +} + +func TestCodec_Marshal_Raw(t *testing.T) { + c := codec{jsonCodec{}} + + s := rawMessage(`{"Name":"name"}`) + + d, err := c.Marshal(s) + assert.NoError(t, err) + + assert.Equal(t, `{"Name":"name"}`, string(d)) +} diff --git a/plugins/grpc/plugin.go b/plugins/grpc/plugin.go new file mode 100644 index 00000000..5da60d75 --- /dev/null +++ b/plugins/grpc/plugin.go @@ -0,0 +1,11 @@ +package grpc + +import "github.com/spiral/errors" + +type Plugin struct { +} + +func (p *Plugin) Init() error { + const op = errors.Op("grpc_plugin_init") + return nil +} diff --git a/plugins/grpc/protoc-gen-php-grpc/main.go b/plugins/grpc/protoc-gen-php-grpc/main.go new file mode 100644 index 00000000..c9c4a573 --- /dev/null +++ b/plugins/grpc/protoc-gen-php-grpc/main.go @@ -0,0 +1,68 @@ +// MIT License +// +// Copyright (c) 2018 SpiralScout +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +package main + +import ( + "io" + "io/ioutil" + "os" + + "github.com/spiral/roadrunner/v2/plugins/grpc/protoc-gen-php-grpc/php" + "google.golang.org/protobuf/proto" + plugin "google.golang.org/protobuf/types/pluginpb" +) + +func main() { + req, err := readRequest(os.Stdin) + if err != nil { + panic(err) + } + + if err = writeResponse(os.Stdout, php.Generate(req)); err != nil { + panic(err) + } +} + +func readRequest(in io.Reader) (*plugin.CodeGeneratorRequest, error) { + data, err := ioutil.ReadAll(in) + if err != nil { + return nil, err + } + + req := new(plugin.CodeGeneratorRequest) + if err = proto.Unmarshal(data, req); err != nil { + return nil, err + } + + return req, nil +} + +func writeResponse(out io.Writer, resp *plugin.CodeGeneratorResponse) error { + data, err := proto.Marshal(resp) + if err != nil { + return err + } + + _, err = out.Write(data) + return err +} diff --git a/plugins/grpc/protoc-gen-php-grpc/php/generate.go b/plugins/grpc/protoc-gen-php-grpc/php/generate.go new file mode 100644 index 00000000..03c48ac8 --- /dev/null +++ b/plugins/grpc/protoc-gen-php-grpc/php/generate.go @@ -0,0 +1,57 @@ +// MIT License +// +// Copyright (c) 2018 SpiralScout +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +package php + +import ( + desc "google.golang.org/protobuf/types/descriptorpb" + plugin "google.golang.org/protobuf/types/pluginpb" +) + +// Generate generates needed service classes +func Generate(req *plugin.CodeGeneratorRequest) *plugin.CodeGeneratorResponse { + resp := &plugin.CodeGeneratorResponse{} + + for _, file := range req.ProtoFile { + for _, service := range file.Service { + resp.File = append(resp.File, generate(req, file, service)) + } + } + + return resp +} + +func generate( + req *plugin.CodeGeneratorRequest, + file *desc.FileDescriptorProto, + service *desc.ServiceDescriptorProto, +) *plugin.CodeGeneratorResponse_File { + return &plugin.CodeGeneratorResponse_File{ + Name: str(filename(file, service.Name)), + Content: str(body(req, file, service)), + } +} + +// helper to convert string into string pointer +func str(str string) *string { + return &str +} diff --git a/plugins/grpc/protoc-gen-php-grpc/php/keywords.go b/plugins/grpc/protoc-gen-php-grpc/php/keywords.go new file mode 100644 index 00000000..32579e33 --- /dev/null +++ b/plugins/grpc/protoc-gen-php-grpc/php/keywords.go @@ -0,0 +1,139 @@ +// MIT License +// +// Copyright (c) 2018 SpiralScout +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +package php + +import ( + "bytes" + "strings" + "unicode" +) + +// @see https://github.com/protocolbuffers/protobuf/blob/master/php/ext/google/protobuf/protobuf.c#L168 +var reservedKeywords = []string{ + "abstract", "and", "array", "as", "break", + "callable", "case", "catch", "class", "clone", + "const", "continue", "declare", "default", "die", + "do", "echo", "else", "elseif", "empty", + "enddeclare", "endfor", "endforeach", "endif", "endswitch", + "endwhile", "eval", "exit", "extends", "final", + "for", "foreach", "function", "global", "goto", + "if", "implements", "include", "include_once", "instanceof", + "insteadof", "interface", "isset", "list", "namespace", + "new", "or", "print", "private", "protected", + "public", "require", "require_once", "return", "static", + "switch", "throw", "trait", "try", "unset", + "use", "var", "while", "xor", "int", + "float", "bool", "string", "true", "false", + "null", "void", "iterable", +} + +// Check if given name/keyword is reserved by php. +func isReserved(name string) bool { + name = strings.ToLower(name) + for _, k := range reservedKeywords { + if name == k { + return true + } + } + + return false +} + +// generate php namespace or path +func namespace(pkg *string, sep string) string { + if pkg == nil { + return "" + } + + result := bytes.NewBuffer(nil) + for _, p := range strings.Split(*pkg, ".") { + result.WriteString(identifier(p, "")) + result.WriteString(sep) + } + + return strings.Trim(result.String(), sep) +} + +// create php identifier for class or message +func identifier(name string, suffix string) string { + name = Camelize(name) + if suffix != "" { + return name + Camelize(suffix) + } + + return name +} + +func resolveReserved(identifier string, pkg string) string { + if isReserved(strings.ToLower(identifier)) { + if pkg == ".google.protobuf" { + return "GPB" + identifier + } + return "PB" + identifier + } + + return identifier +} + +// Camelize "dino_party" -> "DinoParty" +func Camelize(word string) string { + words := splitAtCaseChangeWithTitlecase(word) + return strings.Join(words, "") +} + +func splitAtCaseChangeWithTitlecase(s string) []string { + words := make([]string, 0) + word := make([]rune, 0) + for _, c := range s { + spacer := isSpacerChar(c) + if len(word) > 0 { + if unicode.IsUpper(c) || spacer { + words = append(words, string(word)) + word = make([]rune, 0) + } + } + if !spacer { + if len(word) > 0 { + word = append(word, unicode.ToLower(c)) + } else { + word = append(word, unicode.ToUpper(c)) + } + } + } + words = append(words, string(word)) + return words +} + +func isSpacerChar(c rune) bool { + switch { + case c == rune("_"[0]): + return true + case c == rune(" "[0]): + return true + case c == rune(":"[0]): + return true + case c == rune("-"[0]): + return true + } + return false +} diff --git a/plugins/grpc/protoc-gen-php-grpc/php/ns.go b/plugins/grpc/protoc-gen-php-grpc/php/ns.go new file mode 100644 index 00000000..c1dc3898 --- /dev/null +++ b/plugins/grpc/protoc-gen-php-grpc/php/ns.go @@ -0,0 +1,103 @@ +package php + +import ( + "bytes" + "fmt" + "strings" + + desc "google.golang.org/protobuf/types/descriptorpb" + plugin "google.golang.org/protobuf/types/pluginpb" +) + +// manages internal name representation of the package +type ns struct { + // Package defines file package. + Package string + + // Root namespace of the package + Namespace string + + // Import declares what namespaces to be imported + Import map[string]string +} + +// newNamespace creates new work namespace. +func newNamespace(req *plugin.CodeGeneratorRequest, file *desc.FileDescriptorProto, service *desc.ServiceDescriptorProto) *ns { + ns := &ns{ + Package: *file.Package, + Namespace: namespace(file.Package, "\\"), + Import: make(map[string]string), + } + + if file.Options != nil && file.Options.PhpNamespace != nil { + ns.Namespace = *file.Options.PhpNamespace + } + + for k := range service.Method { + ns.importMessage(req, service.Method[k].InputType) + ns.importMessage(req, service.Method[k].OutputType) + } + + return ns +} + +// importMessage registers new import message namespace (only the namespace). +func (ns *ns) importMessage(req *plugin.CodeGeneratorRequest, msg *string) { + if msg == nil { + return + } + + chunks := strings.Split(*msg, ".") + pkg := strings.Join(chunks[:len(chunks)-1], ".") + + result := bytes.NewBuffer(nil) + for _, p := range chunks[:len(chunks)-1] { + result.WriteString(identifier(p, "")) + result.WriteString(`\`) + } + + if pkg == "."+ns.Package { + // root package + return + } + + for _, f := range req.ProtoFile { + if pkg == "."+*f.Package { + if f.Options != nil && f.Options.PhpNamespace != nil { + // custom imported namespace + ns.Import[pkg] = *f.Options.PhpNamespace + return + } + } + } + + ns.Import[pkg] = strings.Trim(result.String(), `\`) +} + +// resolve message alias +func (ns *ns) resolve(msg *string) string { + chunks := strings.Split(*msg, ".") + pkg := strings.Join(chunks[:len(chunks)-1], ".") + + if pkg == "."+ns.Package { + // root message + return identifier(chunks[len(chunks)-1], "") + } + + for iPkg, ns := range ns.Import { + if pkg == iPkg { + // use last namespace chunk + nsChunks := strings.Split(ns, `\`) + identifier := identifier(chunks[len(chunks)-1], "") + + return fmt.Sprintf( + `%s\%s`, + nsChunks[len(nsChunks)-1], + resolveReserved(identifier, pkg), + ) + } + } + + // fully clarified name (fallback) + return "\\" + namespace(msg, "\\") +} diff --git a/plugins/grpc/protoc-gen-php-grpc/php/template.go b/plugins/grpc/protoc-gen-php-grpc/php/template.go new file mode 100644 index 00000000..e00c6fdd --- /dev/null +++ b/plugins/grpc/protoc-gen-php-grpc/php/template.go @@ -0,0 +1,103 @@ +// MIT License +// +// Copyright (c) 2018 SpiralScout +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +package php + +import ( + "bytes" + "fmt" + "strings" + "text/template" + + desc "google.golang.org/protobuf/types/descriptorpb" + plugin "google.golang.org/protobuf/types/pluginpb" +) + +const phpBody = `<?php +# Generated by the protocol buffer compiler (spiral/php-grpc). DO NOT EDIT! +# source: {{ .File.Name }} +{{ $ns := .Namespace -}} +{{if $ns.Namespace}} +namespace {{ $ns.Namespace }}; +{{end}} +use Spiral\GRPC; +{{- range $n := $ns.Import}} +use {{ $n }}; +{{- end}} + +interface {{ .Service.Name | interface }} extends GRPC\ServiceInterface +{ + // GRPC specific service name. + public const NAME = "{{ .File.Package }}.{{ .Service.Name }}";{{ "\n" }} +{{- range $m := .Service.Method}} + /** + * @param GRPC\ContextInterface $ctx + * @param {{ name $ns $m.InputType }} $in + * @return {{ name $ns $m.OutputType }} + * + * @throws GRPC\Exception\InvokeException + */ + public function {{ $m.Name }}(GRPC\ContextInterface $ctx, {{ name $ns $m.InputType }} $in): {{ name $ns $m.OutputType }}; +{{end -}} +} +` + +// generate php filename +func filename(file *desc.FileDescriptorProto, name *string) string { + ns := namespace(file.Package, "/") + if file.Options != nil && file.Options.PhpNamespace != nil { + ns = strings.ReplaceAll(*file.Options.PhpNamespace, `\`, `/`) + } + + return fmt.Sprintf("%s/%s.php", ns, identifier(*name, "interface")) +} + +// generate php file body +func body(req *plugin.CodeGeneratorRequest, file *desc.FileDescriptorProto, service *desc.ServiceDescriptorProto) string { + out := bytes.NewBuffer(nil) + + data := struct { + Namespace *ns + File *desc.FileDescriptorProto + Service *desc.ServiceDescriptorProto + }{ + Namespace: newNamespace(req, file, service), + File: file, + Service: service, + } + + tpl := template.Must(template.New("phpBody").Funcs(template.FuncMap{ + "interface": func(name *string) string { + return identifier(*name, "interface") + }, + "name": func(ns *ns, name *string) string { + return ns.resolve(name) + }, + }).Parse(phpBody)) + + err := tpl.Execute(out, data) + if err != nil { + panic(err) + } + + return out.String() +} diff --git a/tests/plugins/grpc/grpc_plugin_test.go b/tests/plugins/grpc/grpc_plugin_test.go new file mode 100644 index 00000000..85dd5723 --- /dev/null +++ b/tests/plugins/grpc/grpc_plugin_test.go @@ -0,0 +1,7 @@ +package grpc_test + +import "testing" + +func GrpcInit(t *testing.T) { + +} diff --git a/tests/plugins/grpc/plugin_test.go b/tests/plugins/grpc/plugin_test.go new file mode 100644 index 00000000..74a71c62 --- /dev/null +++ b/tests/plugins/grpc/plugin_test.go @@ -0,0 +1,178 @@ +package grpc + +import ( + "io/ioutil" + "os" + "os/exec" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func init() { + err := build() + if err != nil { + panic(err) + } +} + +func build() error { + cmd := exec.Command("go", "build", "-o", "plugin", "../../../plugins/grpc/protoc-gen-php-grpc") + return cmd.Run() +} + +func protoc(t *testing.T, args []string) { + cmd := exec.Command("protoc", "--plugin=protoc-gen-php-grpc=./plugin") + cmd.Args = append(cmd.Args, args...) + out, err := cmd.CombinedOutput() + + if len(out) > 0 || err != nil { + t.Log("RUNNING: ", strings.Join(cmd.Args, " ")) + } + + if len(out) > 0 { + t.Log(string(out)) + } + + if err != nil { + t.Fatalf("protoc: %v", err) + } +} + +func Test_Simple(t *testing.T) { + workdir, _ := os.Getwd() + tmpdir, err := ioutil.TempDir("", "proto-test") + require.NoError(t, err) + + defer func() { + assert.NoError(t, os.RemoveAll(tmpdir)) + }() + + args := []string{ + "-Itestdata", + "--php-grpc_out=" + tmpdir, + "simple/simple.proto", + } + + protoc(t, args) + + assertEqualFiles( + t, + workdir+"/testdata/simple/TestSimple/SimpleServiceInterface.php", + tmpdir+"/TestSimple/SimpleServiceInterface.php", + ) +} + +func Test_PhpNamespaceOption(t *testing.T) { + workdir, _ := os.Getwd() + tmpdir, err := ioutil.TempDir("", "proto-test") + require.NoError(t, err) + + defer func() { + assert.NoError(t, os.RemoveAll(tmpdir)) + }() + + args := []string{ + "-Itestdata", + "--php-grpc_out=" + tmpdir, + "php_namespace/service.proto", + } + protoc(t, args) + + assertEqualFiles( + t, + workdir+"/testdata/php_namespace/Test/CustomNamespace/ServiceInterface.php", + tmpdir+"/Test/CustomNamespace/ServiceInterface.php", + ) +} + +func Test_UseImportedMessage(t *testing.T) { + workdir, _ := os.Getwd() + tmpdir, err := ioutil.TempDir("", "proto-test") + require.NoError(t, err) + + defer func() { + assert.NoError(t, os.RemoveAll(tmpdir)) + }() + + args := []string{ + "-Itestdata", + "--php-grpc_out=" + tmpdir, + "import/service.proto", + } + protoc(t, args) + + assertEqualFiles( + t, + workdir+"/testdata/import/Import/ServiceInterface.php", + tmpdir+"/Import/ServiceInterface.php", + ) +} + +func Test_PhpNamespaceOptionInUse(t *testing.T) { + workdir, _ := os.Getwd() + tmpdir, err := ioutil.TempDir("", "proto-test") + require.NoError(t, err) + + defer func() { + assert.NoError(t, os.RemoveAll(tmpdir)) + }() + + args := []string{ + "-Itestdata", + "--php-grpc_out=" + tmpdir, + "import_custom/service.proto", + } + protoc(t, args) + + assertEqualFiles( + t, + workdir+"/testdata/import_custom/Test/CustomImport/ServiceInterface.php", + tmpdir+"/Test/CustomImport/ServiceInterface.php", + ) +} + +func Test_UseOfGoogleEmptyMessage(t *testing.T) { + workdir, _ := os.Getwd() + tmpdir, err := ioutil.TempDir("", "proto-test") + require.NoError(t, err) + + defer func() { + assert.NoError(t, os.RemoveAll(tmpdir)) + }() + + args := []string{ + "-Itestdata", + "--php-grpc_out=" + tmpdir, + "use_empty/service.proto", + } + protoc(t, args) + + assertEqualFiles( + t, + workdir+"/testdata/use_empty/Test/ServiceInterface.php", + tmpdir+"/Test/ServiceInterface.php", + ) + + assert.NoError(t, os.RemoveAll("plugin")) +} + +func assertEqualFiles(t *testing.T, original, generated string) { + assert.FileExists(t, generated) + + originalData, err := ioutil.ReadFile(original) + if err != nil { + t.Fatal("Can't find original file for comparison") + } + + generatedData, err := ioutil.ReadFile(generated) + if err != nil { + t.Fatal("Can't find generated file for comparison") + } + + // every OS has a special boy + r := strings.NewReplacer("\r\n", "", "\n", "") + assert.Equal(t, r.Replace(string(originalData)), r.Replace(string(generatedData))) +} diff --git a/tests/plugins/grpc/testdata/import/Import/ServiceInterface.php b/tests/plugins/grpc/testdata/import/Import/ServiceInterface.php new file mode 100644 index 00000000..13e58daf --- /dev/null +++ b/tests/plugins/grpc/testdata/import/Import/ServiceInterface.php @@ -0,0 +1,32 @@ +<?php +# Generated by the protocol buffer compiler (spiral/php-grpc). DO NOT EDIT! +# source: import/service.proto + +namespace Import; + +use Spiral\GRPC; +use Import\Sub; + +interface ServiceInterface extends GRPC\ServiceInterface +{ + // GRPC specific service name. + public const NAME = "import.Service"; + + /** + * @param GRPC\ContextInterface $ctx + * @param Message $in + * @return Message + * + * @throws GRPC\Exception\InvokeException + */ + public function SimpleMethod(GRPC\ContextInterface $ctx, Message $in): Message; + + /** + * @param GRPC\ContextInterface $ctx + * @param Sub\Message $in + * @return Sub\Message + * + * @throws GRPC\Exception\InvokeException + */ + public function ImportMethod(GRPC\ContextInterface $ctx, Sub\Message $in): Sub\Message; +} diff --git a/tests/plugins/grpc/testdata/import/service.proto b/tests/plugins/grpc/testdata/import/service.proto new file mode 100644 index 00000000..5d888f09 --- /dev/null +++ b/tests/plugins/grpc/testdata/import/service.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +package import; + +import "import/sub/message.proto"; + +service Service { + rpc SimpleMethod (Message) returns (Message) { + } + + rpc ImportMethod (import.sub.Message) returns (import.sub.Message) { + } +} + +message Message { + int64 id = 1; +}
\ No newline at end of file diff --git a/tests/plugins/grpc/testdata/import/sub/message.proto b/tests/plugins/grpc/testdata/import/sub/message.proto new file mode 100644 index 00000000..1db0313b --- /dev/null +++ b/tests/plugins/grpc/testdata/import/sub/message.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +package import.sub; + +message Message { + int64 id = 1; +}
\ No newline at end of file diff --git a/tests/plugins/grpc/testdata/import_custom/Test/CustomImport/ServiceInterface.php b/tests/plugins/grpc/testdata/import_custom/Test/CustomImport/ServiceInterface.php new file mode 100644 index 00000000..b010ce4f --- /dev/null +++ b/tests/plugins/grpc/testdata/import_custom/Test/CustomImport/ServiceInterface.php @@ -0,0 +1,32 @@ +<?php +# Generated by the protocol buffer compiler (spiral/php-grpc). DO NOT EDIT! +# source: import_custom/service.proto + +namespace Test\CustomImport; + +use Spiral\GRPC; +use Test\CustomImport\Message; + +interface ServiceInterface extends GRPC\ServiceInterface +{ + // GRPC specific service name. + public const NAME = "import.Service"; + + /** + * @param GRPC\ContextInterface $ctx + * @param Message $in + * @return Message + * + * @throws GRPC\Exception\InvokeException + */ + public function SimpleMethod(GRPC\ContextInterface $ctx, Message $in): Message; + + /** + * @param GRPC\ContextInterface $ctx + * @param Message\Message $in + * @return Message\Message + * + * @throws GRPC\Exception\InvokeException + */ + public function ImportMethod(GRPC\ContextInterface $ctx, Message\Message $in): Message\Message; +} diff --git a/tests/plugins/grpc/testdata/import_custom/service.proto b/tests/plugins/grpc/testdata/import_custom/service.proto new file mode 100644 index 00000000..872aaae3 --- /dev/null +++ b/tests/plugins/grpc/testdata/import_custom/service.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +package import; + +option php_namespace = "Test\\CustomImport"; + +import "import_custom/sub/message.proto"; + +service Service { + rpc SimpleMethod (Message) returns (Message) { + } + + rpc ImportMethod (import.sub.Message) returns (import.sub.Message) { + } +} + +message Message { + int64 id = 1; +}
\ No newline at end of file diff --git a/tests/plugins/grpc/testdata/import_custom/sub/message.proto b/tests/plugins/grpc/testdata/import_custom/sub/message.proto new file mode 100644 index 00000000..5d722ca3 --- /dev/null +++ b/tests/plugins/grpc/testdata/import_custom/sub/message.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package import.sub; +option php_namespace = "Test\\CustomImport\\Message"; + + +service Service { + rpc AnotherMethod (Message) returns (Message) { + } +} + +message Message { + int64 id = 1; +}
\ No newline at end of file diff --git a/tests/plugins/grpc/testdata/php_namespace/Test/CustomNamespace/ServiceInterface.php b/tests/plugins/grpc/testdata/php_namespace/Test/CustomNamespace/ServiceInterface.php new file mode 100644 index 00000000..2090ba97 --- /dev/null +++ b/tests/plugins/grpc/testdata/php_namespace/Test/CustomNamespace/ServiceInterface.php @@ -0,0 +1,22 @@ +<?php +# Generated by the protocol buffer compiler (spiral/php-grpc). DO NOT EDIT! +# source: php_namespace/service.proto + +namespace Test\CustomNamespace; + +use Spiral\GRPC; + +interface ServiceInterface extends GRPC\ServiceInterface +{ + // GRPC specific service name. + public const NAME = "testPhpNamespace.Service"; + + /** + * @param GRPC\ContextInterface $ctx + * @param SimpleMessage $in + * @return SimpleMessage + * + * @throws GRPC\Exception\InvokeException + */ + public function SimpleMethod(GRPC\ContextInterface $ctx, SimpleMessage $in): SimpleMessage; +} diff --git a/tests/plugins/grpc/testdata/php_namespace/service.proto b/tests/plugins/grpc/testdata/php_namespace/service.proto new file mode 100644 index 00000000..a3bfa3c0 --- /dev/null +++ b/tests/plugins/grpc/testdata/php_namespace/service.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package testPhpNamespace; + +option php_namespace = "Test\\CustomNamespace"; + +service Service { + rpc SimpleMethod (SimpleMessage) returns (SimpleMessage) { + } +} + +message SimpleMessage { + int32 id = 1; + string name = 2; +}
\ No newline at end of file diff --git a/tests/plugins/grpc/testdata/simple/TestSimple/SimpleServiceInterface.php b/tests/plugins/grpc/testdata/simple/TestSimple/SimpleServiceInterface.php new file mode 100644 index 00000000..f9e84bf7 --- /dev/null +++ b/tests/plugins/grpc/testdata/simple/TestSimple/SimpleServiceInterface.php @@ -0,0 +1,22 @@ +<?php +# Generated by the protocol buffer compiler (spiral/php-grpc). DO NOT EDIT! +# source: simple/simple.proto + +namespace TestSimple; + +use Spiral\GRPC; + +interface SimpleServiceInterface extends GRPC\ServiceInterface +{ + // GRPC specific service name. + public const NAME = "testSimple.SimpleService"; + + /** + * @param GRPC\ContextInterface $ctx + * @param SimpleMessage $in + * @return SimpleMessage + * + * @throws GRPC\Exception\InvokeException + */ + public function SimpleMethod(GRPC\ContextInterface $ctx, SimpleMessage $in): SimpleMessage; +} diff --git a/tests/plugins/grpc/testdata/simple/simple.proto b/tests/plugins/grpc/testdata/simple/simple.proto new file mode 100644 index 00000000..aca3c1d9 --- /dev/null +++ b/tests/plugins/grpc/testdata/simple/simple.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +package testSimple; + +service SimpleService { + rpc SimpleMethod (SimpleMessage) returns (SimpleMessage) { + } +} + +message SimpleMessage { + int32 id = 1; + string name = 2; +}
\ No newline at end of file diff --git a/tests/plugins/grpc/testdata/use_empty/Test/ServiceInterface.php b/tests/plugins/grpc/testdata/use_empty/Test/ServiceInterface.php new file mode 100644 index 00000000..fe6d345a --- /dev/null +++ b/tests/plugins/grpc/testdata/use_empty/Test/ServiceInterface.php @@ -0,0 +1,23 @@ +<?php +# Generated by the protocol buffer compiler (spiral/php-grpc). DO NOT EDIT! +# source: use_empty/service.proto + +namespace Test; + +use Spiral\GRPC; +use Google\Protobuf; + +interface ServiceInterface extends GRPC\ServiceInterface +{ + // GRPC specific service name. + public const NAME = "test.Service"; + + /** + * @param GRPC\ContextInterface $ctx + * @param Protobuf\GPBEmpty $in + * @return Protobuf\GPBEmpty + * + * @throws GRPC\Exception\InvokeException + */ + public function Test(GRPC\ContextInterface $ctx, Protobuf\GPBEmpty $in): Protobuf\GPBEmpty; +} diff --git a/tests/plugins/grpc/testdata/use_empty/service.proto b/tests/plugins/grpc/testdata/use_empty/service.proto new file mode 100644 index 00000000..8c68d8d3 --- /dev/null +++ b/tests/plugins/grpc/testdata/use_empty/service.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +package test; + +import "google/protobuf/empty.proto"; + +service Service { + rpc Test (google.protobuf.Empty) returns (google.protobuf.Empty) { + } +}
\ No newline at end of file diff --git a/tests/plugins/grpcplug b/tests/plugins/grpcplug Binary files differnew file mode 100755 index 00000000..21785aeb --- /dev/null +++ b/tests/plugins/grpcplug diff --git a/tests/plugins/grpcplugin b/tests/plugins/grpcplugin Binary files differnew file mode 100755 index 00000000..21785aeb --- /dev/null +++ b/tests/plugins/grpcplugin |