diff --git a/Makefile b/Makefile index 97eb43b2fe74b67270dd6b1bc1b577427c979517..edffb61feca4e592fbd263981a3ebcf5ea682477 100644 --- a/Makefile +++ b/Makefile @@ -32,3 +32,23 @@ ifeq (,$(wildcard $(GOPATH)/bin/protoc-gen-go)) Run \"go get -u google.golang.org/protobuf/cmd/protoc-gen-go google.golang.org/grpc/cmd/protoc-gen-go-grpc\" \ or visit \"https://github.com/golang/protobuf/tree/v1.3.2#installation\" for more.\n") endif + + + +#MICROGENFILES?=$(shell find $(SERVICESDIR) -name "service.go" -exec grep -Ril "microgen" {} \;) +#SERVICEDIRS?=$(shell find $(SERVICESDIR) -name "service" -type d -exec dirname {} \;) +#SERVICEFILES?=$(shell find $(SERVICESDIR) -name "service.go" -exec grep -Ril "go:generate" {} \;) + +# Генерация моков для всех интерфейсов, найденных в директории. Выходные файлы с моками сохраняются в `./mocks` +MOCKSDIRS?=$(shell find . -name "service.go" -exec dirname {} \;) +MOCKS=$(MOCKSDIRS:=/mocks) + +mocks: $(MOCKS) + @echo "Generate mocks $<" + +%/mocks: % + @echo "$@ - $<" + @mockery --log-level="error" --all --dir "$<" --output="$@" + +mocks-clean: + @rm -rf $(MOCKS) diff --git a/go.mod b/go.mod index 2fc7ac75587f92d4a4a9b31e16c288997592a4f5..94c2cfbdd2c37f7bbedc4bcc6f91bd752bd0b492 100644 --- a/go.mod +++ b/go.mod @@ -3,14 +3,26 @@ module git.perx.ru/perxis/perxis-go go 1.18 require ( + github.com/go-kit/kit v0.12.0 + github.com/golang/protobuf v1.5.2 + github.com/hashicorp/go-multierror v1.1.1 + github.com/pkg/errors v0.9.1 + github.com/rs/xid v1.4.0 + github.com/stretchr/testify v1.7.0 + golang.org/x/net v0.0.0-20210917221730-978cfadd31cf google.golang.org/grpc v1.45.0 google.golang.org/protobuf v1.28.0 ) require ( - github.com/golang/protobuf v1.5.2 // indirect - golang.org/x/net v0.0.0-20200822124328-c89045814202 // indirect - golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd // indirect - golang.org/x/text v0.3.0 // indirect - google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect + github.com/davecgh/go-spew v1.1.0 // indirect + github.com/go-kit/log v0.2.0 // indirect + github.com/go-logfmt/logfmt v0.5.1 // indirect + github.com/hashicorp/errwrap v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/objx v0.1.0 // indirect + golang.org/x/sys v0.0.0-20210917161153-d61c044b1678 // indirect + golang.org/x/text v0.3.7 // indirect + google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) diff --git a/go.sum b/go.sum index e75a1fd6adeb9088de62b9d54e80c78ccbad0acd..2dc3ca61e747e97abd24d179acc4e32112c07a4e 100644 --- a/go.sum +++ b/go.sum @@ -1,24 +1,35 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +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/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= 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.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= +github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= +github.com/go-kit/log v0.2.0 h1:7i2K3eKTos3Vc0enKCfnVcgHh2olr/MyfboYq7cAcFw= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -44,44 +55,79 @@ github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= +github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210917221730-978cfadd31cf h1:R150MpwJIv1MpS0N/pc+NhTM8ajzvlmxlY5OYsrevXQ= +golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210917161153-d61c044b1678 h1:J27LZFQBFoihqXoegpscI10HpjZ7B5WQLLKL2FZXQKw= +golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -90,14 +136,16 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4 h1:ysnBoUyeL/H6RCvNRhWHjKoDEmguI+mPU+qHgK8qv/w= +google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -111,11 +159,14 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/errors/code.go b/pkg/errors/code.go new file mode 100644 index 0000000000000000000000000000000000000000..fdb94194b49508cc0f1e3610c41fc93d2c271bdf --- /dev/null +++ b/pkg/errors/code.go @@ -0,0 +1,59 @@ +package errors + +import ( + "fmt" + "io" + "sync" +) + +var codeErrors sync.Map + +type CodeError interface { + Code() uint64 +} + +type codeError struct { + code uint64 + err error +} + +func (e *codeError) Error() string { return fmt.Sprintf("(%d) %s", e.code, e.err.Error()) } +func (e *codeError) Code() uint64 { return e.code } +func (w *codeError) Unwrap() error { return w.err } + +func (e *codeError) Format(s fmt.State, verb rune) { + switch verb { + case 'v': + if s.Flag('+') { + fmt.Fprintf(s, "\n(%d): %s", e.code, e.Error()) + return + } + fallthrough + case 's': + io.WriteString(s, e.Error()) + case 'q': + fmt.Fprintf(s, "%q", e.Error()) + } +} + +func (e *codeError) Is(err error) bool { + if ce, ok := err.(CodeError); ok { + return e.code == ce.Code() + } + return false +} + +func WithCode(err error, code uint64) error { + err = &codeError{code: code, err: err} + v, _ := codeErrors.LoadOrStore(code, err) + return v.(error) +} + +func GetCode(err error) uint64 { + for e := err; e != nil; e = Unwrap(e) { + if errCode, ok := e.(CodeError); ok { + return errCode.Code() + } + } + return 0 +} diff --git a/pkg/errors/context.go b/pkg/errors/context.go new file mode 100644 index 0000000000000000000000000000000000000000..287485e50f79c7d767be536fa7043e66fcb4ee5c --- /dev/null +++ b/pkg/errors/context.go @@ -0,0 +1,55 @@ +package errors + +type ErrContext interface{ Context() []interface{} } + +type withContext struct { + err error + kv []interface{} +} + +func (w *withContext) Context() []interface{} { return w.kv } +func (w *withContext) Error() string { return w.err.Error() } +func (w *withContext) Cause() error { return w.err } +func (w *withContext) Unwrap() error { return w.err } + +// WithContext добавляет контекст к ошибке +func WithContext(err error, kv ...interface{}) error { + for e := err; e != nil; e = Unwrap(e) { + if wc, ok := e.(*withContext); ok { + wc.kv = append(wc.kv, kv...) + return err + } + } + return &withContext{ + err: err, + kv: kv, + } +} + +// Context возвращает контекст из ошибки +func Context(err error) []interface{} { + for e := err; e != nil; e = Unwrap(e) { + if errContext, ok := e.(ErrContext); ok { + return errContext.Context() + } + } + return nil +} + +// ContextKey возвращает значение ключа из контекста ошибки +func ContextKey(err error, key interface{}) (interface{}, bool) { + if kv := Context(err); kv != nil { + var i int + for { + if i >= len(kv) { + return nil, false + } + v := kv[i] + if v == key { + return kv[i+1], true + } + i += 2 + } + } + return nil, false +} diff --git a/pkg/errors/detail.go b/pkg/errors/detail.go new file mode 100644 index 0000000000000000000000000000000000000000..a82ec3f8ad5fb7fd52f0ce0acdeeb833065e6ffa --- /dev/null +++ b/pkg/errors/detail.go @@ -0,0 +1,57 @@ +package errors + +import ( + "fmt" + "io" +) + +type ErrDetail interface{ Detail() string } + +type withDetail struct { + err error + detail string +} + +func (w *withDetail) Detail() string { return w.detail } +func (w *withDetail) Error() string { return w.err.Error() } +func (w *withDetail) Cause() error { return w.err } +func (w *withDetail) Unwrap() error { return w.err } + +func (w *withDetail) Format(s fmt.State, verb rune) { + switch verb { + case 'v': + if s.Flag('+') { + fmt.Fprintf(s, "%+v", w.Cause()) + fmt.Fprintf(s, "\nerror detail: %s", w.detail) + return + } + fallthrough + case 's': + io.WriteString(s, w.Error()) + case 'q': + fmt.Fprintf(s, "%q", w.Error()) + } +} + +func WithDetail(err error, detail string) error { + if err == nil { + return nil + } + return &withDetail{err: err, detail: detail} +} + +func WithDetailf(err error, format string, args ...interface{}) error { + if err == nil { + return nil + } + return &withDetail{err: err, detail: fmt.Sprintf(format, args...)} +} + +func GetDetail(err error) string { + for e := err; e != nil; e = Unwrap(e) { + if errDetail, ok := e.(ErrDetail); ok { + return errDetail.Detail() + } + } + return "" +} diff --git a/pkg/errors/domain.go b/pkg/errors/domain.go new file mode 100644 index 0000000000000000000000000000000000000000..35642c34e9537d236a83092855089804164a90de --- /dev/null +++ b/pkg/errors/domain.go @@ -0,0 +1,58 @@ +package errors + +import ( + "fmt" + "io" +) + +const ( + NoDomain = "" + GlobalDomain = "global" +) + +type ErrDomain interface{ Domain() string } + +type withDomain struct { + err error + domain string +} + +func (w *withDomain) Domain() string { return w.domain } +func (w *withDomain) Error() string { return w.err.Error() } +func (w *withDomain) Unwrap() error { return w.err } + +func (w *withDomain) Format(s fmt.State, verb rune) { + switch verb { + case 'v': + if s.Flag('+') { + fmt.Fprintf(s, "%+v", w.Unwrap()) + fmt.Fprintf(s, "\nerror domain: %s", w.domain) + return + } + fallthrough + case 's': + io.WriteString(s, w.Error()) + case 'q': + fmt.Fprintf(s, "%q", w.Error()) + } +} + +func WithDomain(err error, domain string) error { + if err == nil { + return nil + } + return &withDomain{err: err, domain: domain} +} + +func Global(err error) error { + return WithDomain(err, GlobalDomain) +} + +func GetDomain(err error) string { + for e := err; e != nil; e = Unwrap(e) { + if errDomain, ok := e.(ErrDomain); ok { + return errDomain.Domain() + } + } + return NoDomain +} diff --git a/pkg/errors/error.go b/pkg/errors/error.go new file mode 100644 index 0000000000000000000000000000000000000000..cb8ec386db413ecc1a8f33f6dddd45c29359ea85 --- /dev/null +++ b/pkg/errors/error.go @@ -0,0 +1,51 @@ +package errors + +//import ( +// "errors" +//) + +//var ( +// ErrSpaceRequired = errors.New("space required") +// ErrSpaceHostRequired = errors.New("space host required") +// ErrSpaceNotFound = errors.New("space not found") +// ErrSpaceAlreadyExists = errors.New("space already exists") +//) +// +//var errs = []error{ +// ErrSpaceRequired, +// ErrSpaceHostRequired, +// ErrSpaceNotFound, +// ErrSpaceAlreadyExists, +//} +// +//var errMap map[string]error +// +////func New(text string) error { +//// if errMap == nil { +//// errMap = make(map[string]error) +//// for _, e := range errs { +//// errMap[e.Error()] = e +//// } +//// } +//// +//// if e, ok := errMap[text]; ok { +//// return e +//// } +//// +//// return errors.New(text) +////} +// +//func IsAny(err error, targets ...error) bool { +// for _, t := range targets { +// if errors.Is(err, t) { +// return true +// } +// } +// return false +//} +// +//var ( +// Is = errors.Is +// As = errors.As +// Unwrap = errors.Unwrap +//) diff --git a/pkg/errors/errors.go b/pkg/errors/errors.go new file mode 100644 index 0000000000000000000000000000000000000000..952cd8688db8dffe737f63ccba6e1abd4521f715 --- /dev/null +++ b/pkg/errors/errors.go @@ -0,0 +1,72 @@ +package errors + +import ( + stderr "errors" + + "github.com/pkg/errors" +) + +var ( + Is = stderr.Is + As = stderr.As + New = stderr.New + Unwrap = stderr.Unwrap + Errorf = errors.Errorf + Wrap = errors.Wrap + Wrapf = errors.Wrapf + +//Wrap = errors.Wrap +//Wrapf = errors.Wrapf +//WithMessage = errors.WithMessage +//CombineErrors = errors.CombineErrors +////Detail = errors.Detail +////WithDetailf = errors.WithDetailf +////WithHint = errors.WithHint + +//Mark = errors.Mark +//Tags = errors.WithContextTags +// +//CoreDomain = errors.Domain("core") +//StorageDomain = errors.Domain("storage") +//ServiceDomain = errors.Domain("service") +//TransportDomain = errors.Domain("transport") +//EventsDomain = errors.Domain("events") +) + +//func New(msg string) error { +// return &Error{Message: msg} +//} + +//func Trace(err error) error { +// return WithStack(WithID(err)) +//} +// +//func Wrap(err error, msg string) error { +// return WithID(errors.Wrap(err, msg)) +//} +// +//func ErrorBuilder(domain string) func(string) error { +// return func(msg string) error { +// return WithDomain(WithID(New(msg)), domain) +// } +//} +// +//func ErrorfBuilder(domain string) func(format string, args ...interface{}) error { +// return func(format string, args ...interface{}) error { +// return WithDomain(WithID(Errorf(format, args...)), domain) +// } +//} +// +//type Error struct { +// Message string +//} +// +//func (e *Error) Error() string { return e.Message } +//func (e *Error) Is(err error) bool { +// if errr, ok := err.(*Error); ok { +// if e.Message == errr.Message { +// return true +// } +// } +// return false +//} diff --git a/pkg/errors/errors_test.go b/pkg/errors/errors_test.go new file mode 100644 index 0000000000000000000000000000000000000000..365e7120979a73209df1a5e68a10fa76882d8ad0 --- /dev/null +++ b/pkg/errors/errors_test.go @@ -0,0 +1,131 @@ +package errors + +// +//import ( +// "fmt" +// "testing" +// +// jsoniter "github.com/json-iterator/go" +// "github.com/perxteam/hoop4/yaml" +// "github.com/stretchr/testify/assert" +// "github.com/stretchr/testify/require" +//) +// +//func TestErrors_OmitemptyError(t *testing.T) { +// type Struct struct { +// Some string `json:"some"` +// Error error `json:"error,omitempty"` +// } +// +// s := &Struct{Some: "Some"} +// b, err := jsoniter.Marshal(s) +// require.NoError(t, err) +// +// var ss Struct +// err = jsoniter.Unmarshal(b, &ss) +// require.NoError(t, err) +//} +// +//func TestErrors_EmptyError(t *testing.T) { +// type Struct struct { +// Some string `json:"some"` +// Error error `json:"error"` +// } +// +// s := &Struct{Some: "Some"} +// b, err := jsoniter.Marshal(s) +// require.NoError(t, err) +// +// var ss Struct +// err = jsoniter.Unmarshal(b, &ss) +// require.NoError(t, err) +//} +// +//func TestErrors_MarshalYAML(t *testing.T) { +// type S struct { +// Error error +// } +// l1 := &S{New("test")} +// +// _, err := yaml.Marshal(l1) +// require.NoError(t, err) +//} +// +//func TestErrors_Encode(t *testing.T) { +// e := Global(WithID(New("test"))) +// e = WithStack(e) +// e = NotFound(e) +// e = fmt.Errorf("Got error %w", e) +// e = WithDetail(WithHint(e, "Hint"), "Detail") +// e = WithErrors(e, New("add1"), New("add2")) +// enc := EncodeError(e) +// err := DecodeError(enc) +// +// assert.True(t, IsNotFound(err)) +// assert.Equal(t, "Got error test", err.Error()) +// assert.True(t, Is(err, New("Got error test"))) +// assert.Equal(t, "Hint", GetHint(err)) +// assert.Equal(t, "Detail", GetDetail(err)) +// assert.NotEmpty(t, GetID(err)) +// assert.Equal(t, GetID(e), GetID(err)) +// assert.Equal(t, GlobalDomain, GetDomain(err)) +// errs := GetErrors(err) +// require.Len(t, errs, 2) +// assert.True(t, Is(errs[0], New("add1"))) +// assert.True(t, Is(errs[1], New("add2"))) +//} +// +//func TestErrors_JSONEncode(t *testing.T) { +// type Struct struct { +// Some string `json:"some"` +// Error error `json:"error,omitempty"` +// } +// +// s := &Struct{Some: "Some"} +// e := Global(WithID(New("test"))) +// e = WithStack(e) +// e = NotFound(e) +// e = fmt.Errorf("Got error %w", e) +// e = WithDetail(WithHint(e, "Hint"), "Detail") +// e = WithErrors(e, New("add1"), New("add2")) +// s.Error = e +// +// b, jerr := jsoniter.Marshal(s) +// require.NoError(t, jerr) +// +// var st Struct +// jerr = jsoniter.Unmarshal(b, &st) +// require.NoError(t, jerr) +// err := st.Error +// +// assert.True(t, IsNotFound(err)) +// assert.Equal(t, "Got error test", err.Error()) +// assert.True(t, Is(err, New("Got error test"))) +// assert.Equal(t, "Hint", GetHint(err)) +// assert.Equal(t, "Detail", GetDetail(err)) +// assert.NotEmpty(t, GetID(err)) +// assert.Equal(t, GetID(e), GetID(err)) +// assert.Equal(t, GlobalDomain, GetDomain(err)) +// errs := GetErrors(err) +// require.Len(t, errs, 2) +// assert.True(t, Is(errs[0], New("add1"))) +// assert.True(t, Is(errs[1], New("add2"))) +//} +// +//func TestErrors_MultiErrors(t *testing.T) { +// err := WithErrors(New("main"), New("add1"), New("add2")) +// errs := GetErrors(err) +// require.Len(t, errs, 2) +// assert.True(t, Is(errs[0], New("add1"))) +// assert.True(t, Is(errs[1], New("add2"))) +// assert.Equal(t, "main", err.Error()) +//} +// +////func TestErrors_NotFound(t *testing.T) { +//// e := NotFound(New("test")) +//// fmt.Println(IsNotFound(e)) +//// enc := EncodeError(e) +//// fmt.Printf("%#v", enc) +//// //require.NoError(t, e) +////} +// diff --git a/pkg/errors/field.go b/pkg/errors/field.go new file mode 100644 index 0000000000000000000000000000000000000000..891863f0471ab0215229f1eb848f8fb3822e1334 --- /dev/null +++ b/pkg/errors/field.go @@ -0,0 +1,76 @@ +package errors + +import ( + "fmt" + "io" + + "github.com/hashicorp/go-multierror" +) + +type FieldError interface { + Field() string + Error() string +} + +type withField struct { + err error + field string +} + +func (w *withField) Field() string { return w.field } +func (w *withField) Error() string { return fmt.Sprintf("field '%s': %s", w.field, w.err.Error()) } +func (w *withField) Unwrap() error { return w.err } + +func (w *withField) Format(s fmt.State, verb rune) { + switch verb { + case 'v': + if s.Flag('+') { + fmt.Fprintf(s, "%+v", w.Unwrap()) + fmt.Fprintf(s, "\nfield: %s", w.field) + return + } + fallthrough + case 's': + io.WriteString(s, w.Error()) + case 'q': + fmt.Fprintf(s, "%q", w.Error()) + } +} + +func WithField(err error, field string) error { + if err == nil { + return nil + } + + var merr *multierror.Error + if As(err, &merr) { + for i, e := range merr.Errors { + merr.Errors[i] = WithField(e, field) + } + return err + } + + var ferr *withField + if As(err, &ferr) { + if ferr.field != "" { + ferr.field = field + "." + ferr.field + } else { + ferr.field = field + } + return err + } + + return &withField{ + field: field, + err: err, + } +} + +func GetField(err error) string { + for e := err; e != nil; e = Unwrap(e) { + if errField, ok := e.(FieldError); ok { + return errField.Field() + } + } + return "" +} diff --git a/pkg/errors/grpc/middleware.go b/pkg/errors/grpc/middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..a9f51c475f3fc10371bb8a20ff53df2a78d86709 --- /dev/null +++ b/pkg/errors/grpc/middleware.go @@ -0,0 +1,32 @@ +package grpc + +import ( + "context" + + "github.com/go-kit/kit/endpoint" + "google.golang.org/grpc/status" +) + +func ServerMiddleware(ep endpoint.Endpoint) endpoint.Endpoint { + return func(ctx context.Context, request interface{}) (response interface{}, err error) { + response, err = ep(ctx, request) + if err != nil { + if st := StatusFromError(err); st != nil { + err = st.Err() + } + + } + return response, err + } +} + +func ClientMiddleware(ep endpoint.Endpoint) endpoint.Endpoint { + return func(ctx context.Context, request interface{}) (response interface{}, err error) { + response, err = ep(ctx, request) + if err != nil { + st, _ := status.FromError(err) + err = ErrorFromStatus(st) + } + return response, err + } +} diff --git a/pkg/errors/grpc/middleware_test.go b/pkg/errors/grpc/middleware_test.go new file mode 100644 index 0000000000000000000000000000000000000000..6140aaed091b46c1e214acb77dc7f6d5d2221107 --- /dev/null +++ b/pkg/errors/grpc/middleware_test.go @@ -0,0 +1,47 @@ +package grpc + +import ( + "context" + "testing" + + "git.perx.ru/perxis/perxis-go/pkg/errors" + "git.perx.ru/perxis/perxis-go/proto/common" + "github.com/go-kit/kit/endpoint" + "github.com/hashicorp/go-multierror" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func testEndopoint(e error) endpoint.Endpoint { + return func(ctx context.Context, request interface{}) (response interface{}, err error) { + return nil, e + } +} + +func TestMiddleware(t *testing.T) { + merr := multierror.Append(errors.WithField(errors.New("err1"), "fld1"), errors.WithField(errors.New("err2"), "fld2")) + err := errors.WrapErr(errors.New("test"), merr) + err = errors.WithID(err) + err = errors.NotFound(err) + err = errors.Wrap(err, "wrapped") + errID := errors.GetID(err) + + serverEp := ServerMiddleware(testEndopoint(err)) + _, grpcErr := serverEp(context.Background(), nil) + st, _ := status.FromError(grpcErr) + assert.Equal(t, "wrapped: test", st.Message()) + assert.Equal(t, codes.NotFound, st.Code()) + dt := st.Details() + require.Len(t, dt, 1) + require.IsType(t, (*common.Error)(nil), dt[0]) + + clientEp := ClientMiddleware(testEndopoint(grpcErr)) + _, cliErr := clientEp(context.Background(), nil) + assert.Equal(t, "wrapped: test", cliErr.Error(), "ожидается то же строковое значние, что и у изначальной ошибки") + assert.Equal(t, errID, errors.GetID(cliErr)) + assert.Equal(t, codes.NotFound, errors.GetStatusCode(cliErr)) + assert.ErrorAs(t, err, &merr) + assert.Len(t, merr.Errors, 2) +} diff --git a/pkg/errors/grpc/status.go b/pkg/errors/grpc/status.go new file mode 100644 index 0000000000000000000000000000000000000000..e9cc9ee08d1e962e62da1b3d9a9407bc02b3fc2d --- /dev/null +++ b/pkg/errors/grpc/status.go @@ -0,0 +1,138 @@ +package grpc + +import ( + "fmt" + + "git.perx.ru/perxis/perxis-go/pkg/errors" + "git.perx.ru/perxis/perxis-go/proto/common" + "github.com/hashicorp/go-multierror" + "google.golang.org/grpc/status" +) + +func getHelp(err error) *common.Error_Help { + if help := errors.GetHelp(err); help != nil { + pbhelp := &common.Error_Help{} + for _, hl := range help.Links { + pbhelp.Links = append(pbhelp.Links, &common.Error_Help_Link{Description: hl.Description, Url: hl.URL}) + } + return pbhelp + } + return nil +} + +func helpFromPb(err error, pberr *common.Error) error { + if pberr.Help == nil || len(pberr.Help.Links) == 0 { + return err + } + h := &errors.Help{} + for _, l := range pberr.Help.Links { + h.Links = append(h.Links, errors.HelpLink{Description: l.Description, URL: l.Url}) + } + return errors.WithHelp(err, h) +} + +func getBadRequest(err error) *common.Error_BadRequest { + br := &common.Error_BadRequest{} + + var merr *multierror.Error + if errors.As(err, &merr) { + for _, e := range merr.Errors { + var errField errors.FieldError + if errors.As(e, &errField) { + br.Errors = append(br.Errors, &common.Error_BadRequest_FieldViolation{Field: errField.Field(), Description: errors.Unwrap(errField).Error()}) + } + } + } else { + var errField errors.FieldError + if errors.As(err, &errField) { + br.Errors = append(br.Errors, &common.Error_BadRequest_FieldViolation{Field: errField.Field(), Description: errors.Unwrap(errField).Error()}) + } + } + + if len(br.Errors) > 0 { + return br + } + + return nil +} + +func getDebugInfo(err error) *common.Error_DebugInfo { + if trace, ok := errors.GetStackTrace(err); ok { + di := &common.Error_DebugInfo{} + for _, t := range trace { + di.StackTrace = append(di.StackTrace, fmt.Sprintf("%+v", t)) + } + return di + } + + return nil +} + +func badRequestFromPb(err error, pberr *common.Error) error { + if pberr.BadRequest == nil || len(pberr.BadRequest.Errors) == 0 { + return err + } + var merr error + for _, e := range pberr.BadRequest.Errors { + merr = multierror.Append(merr, errors.WithField(errors.New(e.Description), e.Field)) + } + return errors.WrapErr(err, merr) +} + +func StatusFromError(err error) *status.Status { + if err == nil { + return nil + } + err = errors.WithID(err) + pberr := &common.Error{ + ErrorCode: errors.GetCode(err), + ErrorId: errors.GetID(err), + Reason: "", // TBD + Domain: errors.GetDomain(err), + Help: getHelp(err), + Metadata: nil, // TBD + BadRequest: getBadRequest(err), + DebugInfo: getDebugInfo(err), + LocalizedMessages: nil, // TBD + } + + st := status.New(errors.GetStatusCode(err), err.Error()) + st, _ = st.WithDetails(pberr) + return st +} + +func convertProtoError(err error, pberr *common.Error) error { + if pberr == nil { + return nil + } + + // Должен быть первым в цепочке + err = badRequestFromPb(err, pberr) + + if pberr.ErrorCode != 0 { + err = errors.WithCode(err, pberr.ErrorCode) + } + + if pberr.ErrorId != "" { + err = errors.SetID(err, pberr.ErrorId) + } + + if pberr.Domain != "" { + err = errors.WithDomain(err, pberr.Domain) + } + + err = helpFromPb(err, pberr) + return err +} + +func ErrorFromStatus(st *status.Status) error { + details := st.Details() + err := errors.New(st.Message()) + if len(details) > 0 { + if pberr, ok := details[0].(*common.Error); ok { + err = convertProtoError(err, pberr) + } + } + err = errors.WithStatusCode(err, st.Code()) + return err +} diff --git a/pkg/errors/grpc/status_test.go b/pkg/errors/grpc/status_test.go new file mode 100644 index 0000000000000000000000000000000000000000..4a36f34fdb5239d9358fb05e0b345d4288cae047 --- /dev/null +++ b/pkg/errors/grpc/status_test.go @@ -0,0 +1,62 @@ +package grpc + +import ( + "reflect" + "testing" + + "git.perx.ru/perxis/perxis-go/pkg/errors" + "git.perx.ru/perxis/perxis-go/proto/common" + "github.com/hashicorp/go-multierror" +) + +func Test_getBadRequest(t *testing.T) { + tests := []struct { + name string + err error + want *common.Error_BadRequest + }{ + {"Without field error", errors.New("some"), nil}, + {"Field error", errors.WithField(errors.New("some"), "fld1"), + &common.Error_BadRequest{Errors: []*common.Error_BadRequest_FieldViolation{{Description: "some", Field: "fld1"}}}}, + {"Deep field error", errors.Wrap(errors.WithField(errors.New("some"), "fld1"), "extra"), + &common.Error_BadRequest{Errors: []*common.Error_BadRequest_FieldViolation{{Description: "some", Field: "fld1"}}}}, + {"Nested field errors", errors.WithField(errors.WithField(errors.New("some"), "fld1"), "fld2"), + &common.Error_BadRequest{Errors: []*common.Error_BadRequest_FieldViolation{{Description: "some", Field: "fld2.fld1"}}}}, + {"Deep nested field errors", errors.WithField(errors.Wrap(errors.WithField(errors.New("some"), "fld1"), "extra"), "fld2"), + &common.Error_BadRequest{Errors: []*common.Error_BadRequest_FieldViolation{{Description: "some", Field: "fld2.fld1"}}}}, + {"Multi Field error", multierror.Append(errors.WithField(errors.New("some"), "fld1"), errors.WithField(errors.New("some"), "fld2")), + &common.Error_BadRequest{Errors: []*common.Error_BadRequest_FieldViolation{{Description: "some", Field: "fld1"}, {Description: "some", Field: "fld2"}}}}, + {"Nested Multi Field error", errors.WithField(multierror.Append(errors.WithField(errors.New("some"), "fld1"), errors.WithField(errors.New("some"), "fld2")), "fld3"), + &common.Error_BadRequest{Errors: []*common.Error_BadRequest_FieldViolation{{Description: "some", Field: "fld3.fld1"}, {Description: "some", Field: "fld3.fld2"}}}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := getBadRequest(tt.err); !reflect.DeepEqual(got, tt.want) { + t.Errorf("getBadRequest() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_getHelp(t *testing.T) { + tests := []struct { + name string + err error + want *common.Error_Help + }{ + {"Without help", errors.New("some"), nil}, + {"With help", + errors.WithHelp(errors.New("some"), &errors.Help{Links: []errors.HelpLink{{Description: "Help1", URL: "Url1"}}}), + &common.Error_Help{Links: []*common.Error_Help_Link{{Description: "Help1", Url: "Url1"}}}}, + {"With nested help", + errors.WithHelp(errors.WithHelp(errors.New("some"), &errors.Help{Links: []errors.HelpLink{{Description: "Help2", URL: "Url2"}}}), &errors.Help{Links: []errors.HelpLink{{Description: "Help1", URL: "Url1"}}}), + &common.Error_Help{Links: []*common.Error_Help_Link{{Description: "Help1", Url: "Url1"}, {Description: "Help2", Url: "Url2"}}}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := getHelp(tt.err); !reflect.DeepEqual(got, tt.want) { + t.Errorf("getHelp() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/errors/help.go b/pkg/errors/help.go new file mode 100644 index 0000000000000000000000000000000000000000..caf84d8796b7d9bc8dbef424ceaec0410e062a88 --- /dev/null +++ b/pkg/errors/help.go @@ -0,0 +1,62 @@ +package errors + +type Help struct { + Links []HelpLink +} + +type HelpLink struct { + Description string + URL string +} + +type HelpError interface{ Help() *Help } + +type withHelp struct { + err error + help *Help +} + +func (w *withHelp) Help() *Help { return w.help } +func (w *withHelp) Error() string { return w.err.Error() } +func (w *withHelp) Unwrap() error { return w.err } + +//func (w *withHelp) Format(s fmt.State, verb rune) { +// switch verb { +// case 'v': +// if s.Flag('+') { +// fmt.Fprintf(s, "%+v", w.Unwrap()) +// fmt.Fprintf(s, "\nerror hint: %s", w.hint) +// return +// } +// fallthrough +// case 's': +// io.WriteString(s, w.Error()) +// case 'q': +// fmt.Fprintf(s, "%q", w.Error()) +// } +//} + +func WithHelp(err error, help *Help) error { + if err == nil { + return nil + } + return &withHelp{err: err, help: help} +} + +func GetHelp(err error) *Help { + var help Help + for e := err; e != nil; e = Unwrap(e) { + if errHelp, ok := e.(HelpError); ok { + h := errHelp.Help() + if h != nil && len(h.Links) > 0 { + help.Links = append(help.Links, h.Links...) + } + } + } + + if len(help.Links) > 0 { + return &help + } + + return nil +} diff --git a/pkg/errors/hint.go b/pkg/errors/hint.go new file mode 100644 index 0000000000000000000000000000000000000000..f654d4024936cdf19e65b89aaca2fef3070fb5bb --- /dev/null +++ b/pkg/errors/hint.go @@ -0,0 +1,57 @@ +package errors + +import ( + "fmt" + "io" +) + +type ErrHint interface{ Hint() string } + +type withHint struct { + err error + hint string +} + +func (w *withHint) Hint() string { return w.hint } +func (w *withHint) Error() string { return w.err.Error() } +func (w *withHint) Cause() error { return w.err } +func (w *withHint) Unwrap() error { return w.err } + +func (w *withHint) Format(s fmt.State, verb rune) { + switch verb { + case 'v': + if s.Flag('+') { + fmt.Fprintf(s, "%+v", w.Cause()) + fmt.Fprintf(s, "\nerror hint: %s", w.hint) + return + } + fallthrough + case 's': + io.WriteString(s, w.Error()) + case 'q': + fmt.Fprintf(s, "%q", w.Error()) + } +} + +func WithHint(err error, hint string) error { + if err == nil { + return nil + } + return &withHint{err: err, hint: hint} +} + +func WithHintf(err error, format string, args ...interface{}) error { + if err == nil { + return nil + } + return &withHint{err: err, hint: fmt.Sprintf(format, args...)} +} + +func GetHint(err error) string { + for e := err; e != nil; e = Unwrap(e) { + if errDetail, ok := e.(ErrHint); ok { + return errDetail.Hint() + } + } + return "" +} diff --git a/pkg/errors/id.go b/pkg/errors/id.go new file mode 100644 index 0000000000000000000000000000000000000000..9d9804882e0892c92998560b9be4ae7ec0fe1558 --- /dev/null +++ b/pkg/errors/id.go @@ -0,0 +1,64 @@ +package errors + +import ( + "fmt" + "io" + + "github.com/rs/xid" +) + +type ErrID interface{ ID() string } + +type withId struct { + err error + id string +} + +func (w *withId) ID() string { return w.id } +func (w *withId) Error() string { return w.err.Error() } +func (w *withId) Cause() error { return w.err } +func (w *withId) Unwrap() error { return w.err } + +func (w *withId) Format(s fmt.State, verb rune) { + switch verb { + case 'v': + if s.Flag('+') { + fmt.Fprintf(s, "%+v", w.Cause()) + fmt.Fprintf(s, "\nerror id: %s", w.id) + return + } + fallthrough + case 's': + io.WriteString(s, w.Error()) + case 'q': + fmt.Fprintf(s, "%q", w.Error()) + } +} + +func SetID(err error, id string) error { + if GetID(err) != "" { + return err + } + return &withId{err: err, id: id} +} + +func GetID(err error) string { + for e := err; e != nil; e = Unwrap(e) { + if errID, ok := e.(ErrID); ok { + return errID.ID() + } + } + return "" +} + +func WithID(err error) error { + if err == nil { + return nil + } + id := GetID(err) + if id == "" { + id = xid.New().String() + err = &withId{err: err, id: id} + } + return err +} diff --git a/pkg/errors/multi.go b/pkg/errors/multi.go new file mode 100644 index 0000000000000000000000000000000000000000..d27392c7a96ec2a8b653699052d9cbf7ee679ba8 --- /dev/null +++ b/pkg/errors/multi.go @@ -0,0 +1,58 @@ +package errors + +import ( + "fmt" + "io" +) + +type MultiError interface { + Errors() []error + Error() string +} + +type withMultiError struct { + err error + errors []error +} + +func (w *withMultiError) Errors() []error { return w.errors } +func (w *withMultiError) Error() string { return w.err.Error() } +func (w *withMultiError) Unwrap() error { return w.err } + +func (w *withMultiError) Format(s fmt.State, verb rune) { + switch verb { + case 'v': + if s.Flag('+') { + fmt.Fprintf(s, "%+v", w.Unwrap()) + if len(w.errors) > 0 { + fmt.Fprint(s, "\ninclude errors:\n") + for _, e := range w.errors { + fmt.Fprintf(s, " %s\n", e) + } + } + + return + } + fallthrough + case 's': + io.WriteString(s, w.Error()) + case 'q': + fmt.Fprintf(s, "%q", w.Error()) + } +} + +func WithErrors(err error, errs ...error) error { + if err == nil || len(errs) == 0 { + return err + } + return &withMultiError{err: err, errors: errs} +} + +func GetErrors(err error) []error { + for e := err; e != nil; e = Unwrap(e) { + if errMulti, ok := e.(MultiError); ok { + return errMulti.Errors() + } + } + return nil +} diff --git a/pkg/errors/source.go b/pkg/errors/source.go new file mode 100644 index 0000000000000000000000000000000000000000..c43df751c063b7c2e419071e22812aa890074b42 --- /dev/null +++ b/pkg/errors/source.go @@ -0,0 +1,70 @@ +package errors + +import ( + "fmt" + "io" +) + +type ErrorSource struct { + Pointer string `json:"pointer,omitempty"` + Parameter string `json:"parameter,omitempty"` + Field string `json:"field,omitempty"` +} + +func NewSource(args ...string) *ErrorSource { + s := &ErrorSource{} + if len(args) > 0 { + s.Pointer = args[0] + } + if len(args) > 1 { + s.Parameter = args[1] + } + if len(args) > 2 { + s.Field = args[2] + } + return s +} + +type ErrSource interface{ Source() *ErrorSource } + +type withSource struct { + err error + source *ErrorSource +} + +func (w *withSource) Source() *ErrorSource { return w.source } +func (w *withSource) Error() string { return w.err.Error() } +func (w *withSource) Cause() error { return w.err } +func (w *withSource) Unwrap() error { return w.err } + +func (w *withSource) Format(s fmt.State, verb rune) { + switch verb { + case 'v': + if s.Flag('+') { + fmt.Fprintf(s, "%+v", w.Cause()) + fmt.Fprintf(s, "\nerror source: %+v", w.source) + return + } + fallthrough + case 's': + io.WriteString(s, w.Error()) + case 'q': + fmt.Fprintf(s, "%q", w.Error()) + } +} + +func WithSource(err error, source *ErrorSource) error { + if err == nil { + return nil + } + return &withSource{err: err, source: source} +} + +func GetSource(err error) *ErrorSource { + for e := err; e != nil; e = Unwrap(e) { + if errSource, ok := e.(ErrSource); ok { + return errSource.Source() + } + } + return nil +} diff --git a/pkg/errors/stack.go b/pkg/errors/stack.go new file mode 100644 index 0000000000000000000000000000000000000000..0b9efc3360a4ae05f8d50ecf119464262974659a --- /dev/null +++ b/pkg/errors/stack.go @@ -0,0 +1,30 @@ +package errors + +import ( + "github.com/pkg/errors" +) + +var WithStack = errors.WithStack + +type StackTrace = errors.StackTrace + +type StackTracer interface { + StackTrace() errors.StackTrace +} + +func GetStackTrace(err error) (StackTrace, bool) { + if s := getStackTracer(err); s != nil { + return s.StackTrace(), true + } + + return nil, false +} + +func getStackTracer(err error) StackTracer { + for e := err; e != nil; e = Unwrap(e) { + if s, ok := err.(StackTracer); ok { + return s + } + } + return nil +} diff --git a/pkg/errors/status.go b/pkg/errors/status.go new file mode 100644 index 0000000000000000000000000000000000000000..04b8261296574fb72e5750edc100d8c2e805f9ff --- /dev/null +++ b/pkg/errors/status.go @@ -0,0 +1,76 @@ +package errors + +import ( + "errors" + "fmt" + "io" + + "google.golang.org/grpc/codes" +) + +type ErrStatus interface { + StatusCode() codes.Code + Error() string +} + +type withStatusError struct { + err error + code codes.Code +} + +func (w *withStatusError) StatusCode() codes.Code { return w.code } +func (w *withStatusError) Error() string { return w.err.Error() } +func (w *withStatusError) Unwrap() error { return w.err } + +func (w *withStatusError) Format(s fmt.State, verb rune) { + switch verb { + case 'v': + if s.Flag('+') { + fmt.Fprintf(s, "%+v", w.Unwrap()) + fmt.Fprintf(s, "\nerror status: %s", w.code) + return + } + fallthrough + case 's': + io.WriteString(s, w.Error()) + case 'q': + fmt.Fprintf(s, "%q", w.Error()) + } +} + +func WithStatusCode(err error, code codes.Code) error { + if err == nil || code == codes.Unknown { + return err + } + + var se *withStatusError + if errors.As(err, &se) { + if se.StatusCode() == code { + return err + } + } + + return &withStatusError{ + err: err, + code: code, + } +} + +func GetStatusCode(err error) codes.Code { + for e := err; e != nil; e = Unwrap(e) { + if errStatus, ok := e.(ErrStatus); ok { + return errStatus.StatusCode() + } + } + return codes.Unknown +} + +func InvalidArgument(err error) error { return WithStatusCode(err, codes.InvalidArgument) } +func DeadlineExceeded(err error) error { return WithStatusCode(err, codes.DeadlineExceeded) } +func NotFound(err error) error { return WithStatusCode(err, codes.NotFound) } +func AlreadyExists(err error) error { return WithStatusCode(err, codes.AlreadyExists) } +func PermissionDenied(err error) error { return WithStatusCode(err, codes.PermissionDenied) } +func FailedPrecondition(err error) error { return WithStatusCode(err, codes.FailedPrecondition) } +func Internal(err error) error { return WithStatusCode(err, codes.Internal) } +func Unavailable(err error) error { return WithStatusCode(err, codes.Unavailable) } +func Unauthenticated(err error) error { return WithStatusCode(err, codes.Unauthenticated) } diff --git a/pkg/errors/wrap.go b/pkg/errors/wrap.go new file mode 100644 index 0000000000000000000000000000000000000000..7403b3c1fae4f5a57f91f5bae992a6be1004f5ea --- /dev/null +++ b/pkg/errors/wrap.go @@ -0,0 +1,38 @@ +package errors + +import "errors" + +type wrappedErr struct { + Err error + Wrapped error +} + +func WrapErr(err, wrapped error) error { + if wrapped == nil { + return nil + } + return &wrappedErr{ + Err: err, + Wrapped: wrapped, + } +} + +func (w *wrappedErr) Error() string { + return w.Err.Error() +} + +func (w *wrappedErr) WrappedErrors() []error { + return []error{w.Err, w.Wrapped} +} + +func (w *wrappedErr) Unwrap() error { + return w.Wrapped +} + +func (w *wrappedErr) Is(target error) bool { + return errors.Is(w.Err, target) +} + +func (w *wrappedErr) As(target interface{}) bool { + return errors.As(w.Err, target) +} diff --git a/pkg/space/mocks/Spaces.go b/pkg/space/mocks/Spaces.go new file mode 100644 index 0000000000000000000000000000000000000000..6fd9ef4aaf8012c82973ed3d94815babed9acd65 --- /dev/null +++ b/pkg/space/mocks/Spaces.go @@ -0,0 +1,150 @@ +// Code generated by mockery v2.22.1. DO NOT EDIT. + +package mocks + +import ( + context "context" + + space "git.perx.ru/perxis/perxis-go/pkg/space" + mock "github.com/stretchr/testify/mock" +) + +// Spaces is an autogenerated mock type for the Spaces type +type Spaces struct { + mock.Mock +} + +// Create provides a mock function with given fields: ctx, _a1 +func (_m *Spaces) Create(ctx context.Context, _a1 *space.Space) (*space.Space, error) { + ret := _m.Called(ctx, _a1) + + var r0 *space.Space + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *space.Space) (*space.Space, error)); ok { + return rf(ctx, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *space.Space) *space.Space); ok { + r0 = rf(ctx, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*space.Space) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *space.Space) error); ok { + r1 = rf(ctx, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Delete provides a mock function with given fields: ctx, spaceId +func (_m *Spaces) Delete(ctx context.Context, spaceId string) error { + ret := _m.Called(ctx, spaceId) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { + r0 = rf(ctx, spaceId) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Get provides a mock function with given fields: ctx, spaceId +func (_m *Spaces) Get(ctx context.Context, spaceId string) (*space.Space, error) { + ret := _m.Called(ctx, spaceId) + + var r0 *space.Space + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (*space.Space, error)); ok { + return rf(ctx, spaceId) + } + if rf, ok := ret.Get(0).(func(context.Context, string) *space.Space); ok { + r0 = rf(ctx, spaceId) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*space.Space) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, spaceId) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// List provides a mock function with given fields: ctx, orgId +func (_m *Spaces) List(ctx context.Context, orgId string) ([]*space.Space, error) { + ret := _m.Called(ctx, orgId) + + var r0 []*space.Space + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) ([]*space.Space, error)); ok { + return rf(ctx, orgId) + } + if rf, ok := ret.Get(0).(func(context.Context, string) []*space.Space); ok { + r0 = rf(ctx, orgId) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*space.Space) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, orgId) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Update provides a mock function with given fields: ctx, _a1 +func (_m *Spaces) Update(ctx context.Context, _a1 *space.Space) error { + ret := _m.Called(ctx, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *space.Space) error); ok { + r0 = rf(ctx, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// UpdateConfig provides a mock function with given fields: ctx, spaceId, config +func (_m *Spaces) UpdateConfig(ctx context.Context, spaceId string, config *space.Config) error { + ret := _m.Called(ctx, spaceId, config) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string, *space.Config) error); ok { + r0 = rf(ctx, spaceId, config) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +type mockConstructorTestingTNewSpaces interface { + mock.TestingT + Cleanup(func()) +} + +// NewSpaces creates a new instance of Spaces. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewSpaces(t mockConstructorTestingTNewSpaces) *Spaces { + mock := &Spaces{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/pkg/space/service.go b/pkg/space/service.go new file mode 100644 index 0000000000000000000000000000000000000000..576f5c2f8a7fae3a2b15d658eb1f42b5df0cab51 --- /dev/null +++ b/pkg/space/service.go @@ -0,0 +1,44 @@ +package space + +import ( + "context" + + "github.com/pkg/errors" +) + +// @microgen grpc +// @protobuf git.perx.ru/perxis/perxis-go/proto/spaces +// @grpc-addr content.spaces.Spaces +type Spaces interface { + // Create - создает пространство для размещения контента + // В процессе создание пространства выполняются следующие шаги: + // 1. Создается запись о пространстве + // 2. Создается БД пространства + // 3. Создается master окружение + // 4. Создаются необходимые схема согласно указанной конфигурации + // 5. Выполняется копирование данных согласно указанной конфигурации + // Шаги могут выполняться в отложенном режиме, при этом пространство может быть недоступно для + // выполнения любых операций. Попытка обращения к пространству будет сопровождаться ошибкой + // ErrUnavailable + + Create(ctx context.Context, space *Space) (created *Space, err error) + Get(ctx context.Context, spaceId string) (space *Space, err error) + List(ctx context.Context, orgId string) (spaces []*Space, err error) + Update(ctx context.Context, space *Space) (err error) + UpdateConfig(ctx context.Context, spaceId string, config *Config) (err error) + Delete(ctx context.Context, spaceId string) (err error) +} + +func IsSpaceAvailable(ctx context.Context, spcs Spaces, spaceId string) error { + spc, err := spcs.Get(ctx, spaceId) + + if err != nil { + return errors.Wrap(err, "space not available") + } + + if spc.State != StateReady { + return errors.New("space not available") + } + + return nil +} diff --git a/pkg/space/space.go b/pkg/space/space.go new file mode 100644 index 0000000000000000000000000000000000000000..dad51255a6fa9e8e648eec346a92f45c1749c876 --- /dev/null +++ b/pkg/space/space.go @@ -0,0 +1,54 @@ +package space + +type State int + +const ( + StateUnknown State = iota + StateNew // Новое пространство, БД еще не инициализирована + StateReady // Пространство готово к использованию + StatePreparing // Пространство готовится в использованию + StateMaintenance // Пространство находится на обслуживании + StateMigration // Пространство в состоянии выполнения миграций + StateDeleting // Пространство удаляется, данные будут удалены + StateError // Произошла ошибка при конфигурации пространства (см. Space.Error) +) + +type Config struct { + Features []string //Deprecated Возможности используемые пространством +} + +const StateInfoEmpty = "EMPTY" + +type Space struct { + ID string `json:"id,omitempty" bson:"_id"` + OrgID string `json:"org_id,omitempty" bson:"org_id"` + Name string `json:"name,omitempty" bson:"name"` + Description string `json:"desc,omitempty" bson:"desc"` + State State `json:"state" bson:"state"` + StateInfo string `json:"stateInfo,omitempty" bson:"stateInfo,omitempty"` + Config *Config `json:"config" bson:"config"` +} + +func (s Space) Clone() *Space { + return &s +} + +func (s Space) Fetch(i interface{}) interface{} { + p, _ := i.(string) + switch p { + case "ID": + return s.ID + case "OrgID": + return s.OrgID + case "Name": + return s.Name + case "Description": + return s.Description + case "State": + return s.State + case "Config": + return s.Config + default: + panic("unknown parameter") + } +} diff --git a/pkg/space/transport/client.go b/pkg/space/transport/client.go new file mode 100644 index 0000000000000000000000000000000000000000..44b72b6f5c8f0786f7ad7a255b9e46b69f672647 --- /dev/null +++ b/pkg/space/transport/client.go @@ -0,0 +1,66 @@ +// Code generated by microgen 0.9.1. DO NOT EDIT. + +package transport + +import ( + "context" + + spaces "git.perx.ru/perxis/perxis-go/pkg/space" +) + +func (set EndpointsSet) Create(arg0 context.Context, arg1 *spaces.Space) (res0 *spaces.Space, res1 error) { + request := CreateRequest{Space: arg1} + response, res1 := set.CreateEndpoint(arg0, &request) + if res1 != nil { + return + } + return response.(*CreateResponse).Created, res1 +} + +func (set EndpointsSet) Get(arg0 context.Context, arg1 string) (res0 *spaces.Space, res1 error) { + request := GetRequest{SpaceId: arg1} + response, res1 := set.GetEndpoint(arg0, &request) + if res1 != nil { + return + } + return response.(*GetResponse).Space, res1 +} + +func (set EndpointsSet) List(arg0 context.Context, arg1 string) (res0 []*spaces.Space, res1 error) { + request := ListRequest{OrgId: arg1} + response, res1 := set.ListEndpoint(arg0, &request) + if res1 != nil { + return + } + return response.(*ListResponse).Spaces, res1 +} + +func (set EndpointsSet) Update(arg0 context.Context, arg1 *spaces.Space) (res0 error) { + request := UpdateRequest{Space: arg1} + _, res0 = set.UpdateEndpoint(arg0, &request) + if res0 != nil { + return + } + return res0 +} + +func (set EndpointsSet) UpdateConfig(arg0 context.Context, arg1 string, arg2 *spaces.Config) (res0 error) { + request := UpdateConfigRequest{ + Config: arg2, + SpaceId: arg1, + } + _, res0 = set.UpdateConfigEndpoint(arg0, &request) + if res0 != nil { + return + } + return res0 +} + +func (set EndpointsSet) Delete(arg0 context.Context, arg1 string) (res0 error) { + request := DeleteRequest{SpaceId: arg1} + _, res0 = set.DeleteEndpoint(arg0, &request) + if res0 != nil { + return + } + return res0 +} diff --git a/pkg/space/transport/endpoints.microgen.go b/pkg/space/transport/endpoints.microgen.go new file mode 100644 index 0000000000000000000000000000000000000000..fae8a92d5cdb23e198955db8f0c56c620db51ee3 --- /dev/null +++ b/pkg/space/transport/endpoints.microgen.go @@ -0,0 +1,15 @@ +// Code generated by microgen 0.9.1. DO NOT EDIT. + +package transport + +import endpoint "github.com/go-kit/kit/endpoint" + +// EndpointsSet implements Spaces API and used for transport purposes. +type EndpointsSet struct { + CreateEndpoint endpoint.Endpoint + GetEndpoint endpoint.Endpoint + ListEndpoint endpoint.Endpoint + UpdateEndpoint endpoint.Endpoint + UpdateConfigEndpoint endpoint.Endpoint + DeleteEndpoint endpoint.Endpoint +} diff --git a/pkg/space/transport/exchanges.microgen.go b/pkg/space/transport/exchanges.microgen.go new file mode 100644 index 0000000000000000000000000000000000000000..05ad11827f34070ebd644b44a217bcceedfecbc7 --- /dev/null +++ b/pkg/space/transport/exchanges.microgen.go @@ -0,0 +1,47 @@ +// Code generated by microgen 0.9.1. DO NOT EDIT. + +package transport + +import spaces "git.perx.ru/perxis/perxis-go/pkg/space" + +type ( + CreateRequest struct { + Space *spaces.Space `json:"space"` + } + CreateResponse struct { + Created *spaces.Space `json:"created"` + } + + GetRequest struct { + SpaceId string `json:"space_id"` + } + GetResponse struct { + Space *spaces.Space `json:"space"` + } + + ListRequest struct { + OrgId string `json:"org_id"` + } + ListResponse struct { + Spaces []*spaces.Space `json:"spaces"` + } + + UpdateRequest struct { + Space *spaces.Space `json:"space"` + } + // Formal exchange type, please do not delete. + UpdateResponse struct{} + + UpdateConfigRequest struct { + SpaceId string `json:"space_id"` + Config *spaces.Config `json:"config"` + } + // Formal exchange type, please do not delete. + UpdateConfigResponse struct{} + + DeleteRequest struct { + SpaceId string `json:"space_id"` + } + // Formal exchange type, please do not delete. + DeleteResponse struct{} +) diff --git a/pkg/space/transport/grpc/client.go b/pkg/space/transport/grpc/client.go new file mode 100644 index 0000000000000000000000000000000000000000..bfa48ae9df7c4bff443f5bbaa3d88c37f1fa26bc --- /dev/null +++ b/pkg/space/transport/grpc/client.go @@ -0,0 +1,21 @@ +// Code generated by microgen 0.9.1. DO NOT EDIT. + +package transportgrpc + +import ( + grpcerr "git.perx.ru/perxis/perxis-go/pkg/errors/grpc" + transport "git.perx.ru/perxis/perxis-go/pkg/space/transport" + grpckit "github.com/go-kit/kit/transport/grpc" + grpc "google.golang.org/grpc" +) + +func NewClient(conn *grpc.ClientConn, opts ...grpckit.ClientOption) transport.EndpointsSet { + c := NewGRPCClient(conn, "", opts...) + return transport.EndpointsSet{ + CreateEndpoint: grpcerr.ClientMiddleware(c.CreateEndpoint), + GetEndpoint: grpcerr.ClientMiddleware(c.GetEndpoint), + ListEndpoint: grpcerr.ClientMiddleware(c.ListEndpoint), + UpdateEndpoint: grpcerr.ClientMiddleware(c.UpdateEndpoint), + UpdateConfigEndpoint: grpcerr.ClientMiddleware(c.UpdateConfigEndpoint), + DeleteEndpoint: grpcerr.ClientMiddleware(c.DeleteEndpoint)} +} diff --git a/pkg/space/transport/grpc/client.microgen.go b/pkg/space/transport/grpc/client.microgen.go new file mode 100644 index 0000000000000000000000000000000000000000..b0d7d35e8e14c5ffa1d852d16e899160af5bb55e --- /dev/null +++ b/pkg/space/transport/grpc/client.microgen.go @@ -0,0 +1,61 @@ +// Code generated by microgen 0.9.1. DO NOT EDIT. + +package transportgrpc + +import ( + transport "git.perx.ru/perxis/perxis-go/pkg/space/transport" + pb "git.perx.ru/perxis/perxis-go/proto/spaces" + grpckit "github.com/go-kit/kit/transport/grpc" + empty "github.com/golang/protobuf/ptypes/empty" + grpc "google.golang.org/grpc" +) + +func NewGRPCClient(conn *grpc.ClientConn, addr string, opts ...grpckit.ClientOption) transport.EndpointsSet { + if addr == "" { + addr = "content.spaces.Spaces" + } + return transport.EndpointsSet{ + CreateEndpoint: grpckit.NewClient( + conn, addr, "Create", + _Encode_Create_Request, + _Decode_Create_Response, + pb.CreateResponse{}, + opts..., + ).Endpoint(), + DeleteEndpoint: grpckit.NewClient( + conn, addr, "Delete", + _Encode_Delete_Request, + _Decode_Delete_Response, + empty.Empty{}, + opts..., + ).Endpoint(), + GetEndpoint: grpckit.NewClient( + conn, addr, "Get", + _Encode_Get_Request, + _Decode_Get_Response, + pb.GetResponse{}, + opts..., + ).Endpoint(), + ListEndpoint: grpckit.NewClient( + conn, addr, "List", + _Encode_List_Request, + _Decode_List_Response, + pb.ListResponse{}, + opts..., + ).Endpoint(), + UpdateConfigEndpoint: grpckit.NewClient( + conn, addr, "UpdateConfig", + _Encode_UpdateConfig_Request, + _Decode_UpdateConfig_Response, + empty.Empty{}, + opts..., + ).Endpoint(), + UpdateEndpoint: grpckit.NewClient( + conn, addr, "Update", + _Encode_Update_Request, + _Decode_Update_Response, + empty.Empty{}, + opts..., + ).Endpoint(), + } +} diff --git a/pkg/space/transport/grpc/protobuf_endpoint_converters.microgen.go b/pkg/space/transport/grpc/protobuf_endpoint_converters.microgen.go new file mode 100644 index 0000000000000000000000000000000000000000..606d41cfa3335674b487cd861fd5cfb86152b90b --- /dev/null +++ b/pkg/space/transport/grpc/protobuf_endpoint_converters.microgen.go @@ -0,0 +1,235 @@ +// Code generated by microgen 0.9.1. DO NOT EDIT. + +// Please, do not change functions names! +package transportgrpc + +import ( + "context" + "errors" + + transport "git.perx.ru/perxis/perxis-go/pkg/space/transport" + pb "git.perx.ru/perxis/perxis-go/proto/spaces" + empty "github.com/golang/protobuf/ptypes/empty" +) + +func _Encode_Create_Request(ctx context.Context, request interface{}) (interface{}, error) { + if request == nil { + return nil, errors.New("nil CreateRequest") + } + req := request.(*transport.CreateRequest) + reqSpace, err := PtrSpaceToProto(req.Space) + if err != nil { + return nil, err + } + return &pb.CreateRequest{Space: reqSpace}, nil +} + +func _Encode_Get_Request(ctx context.Context, request interface{}) (interface{}, error) { + if request == nil { + return nil, errors.New("nil GetRequest") + } + req := request.(*transport.GetRequest) + return &pb.GetRequest{SpaceId: req.SpaceId}, nil +} + +func _Encode_List_Request(ctx context.Context, request interface{}) (interface{}, error) { + if request == nil { + return nil, errors.New("nil ListRequest") + } + req := request.(*transport.ListRequest) + return &pb.ListRequest{OrgId: req.OrgId}, nil +} + +func _Encode_Update_Request(ctx context.Context, request interface{}) (interface{}, error) { + if request == nil { + return nil, errors.New("nil UpdateRequest") + } + req := request.(*transport.UpdateRequest) + reqSpace, err := PtrSpaceToProto(req.Space) + if err != nil { + return nil, err + } + return &pb.UpdateRequest{Space: reqSpace}, nil +} + +func _Encode_UpdateConfig_Request(ctx context.Context, request interface{}) (interface{}, error) { + if request == nil { + return nil, errors.New("nil UpdateConfigRequest") + } + req := request.(*transport.UpdateConfigRequest) + reqConfig, err := PtrConfigToProto(req.Config) + if err != nil { + return nil, err + } + return &pb.UpdateConfigRequest{ + Config: reqConfig, + SpaceId: req.SpaceId, + }, nil +} + +func _Encode_Delete_Request(ctx context.Context, request interface{}) (interface{}, error) { + if request == nil { + return nil, errors.New("nil DeleteRequest") + } + req := request.(*transport.DeleteRequest) + return &pb.DeleteRequest{SpaceId: req.SpaceId}, nil +} + +func _Encode_Create_Response(ctx context.Context, response interface{}) (interface{}, error) { + if response == nil { + return nil, errors.New("nil CreateResponse") + } + resp := response.(*transport.CreateResponse) + respCreated, err := PtrSpaceToProto(resp.Created) + if err != nil { + return nil, err + } + return &pb.CreateResponse{Created: respCreated}, nil +} + +func _Encode_Get_Response(ctx context.Context, response interface{}) (interface{}, error) { + if response == nil { + return nil, errors.New("nil GetResponse") + } + resp := response.(*transport.GetResponse) + respSpace, err := PtrSpaceToProto(resp.Space) + if err != nil { + return nil, err + } + return &pb.GetResponse{Space: respSpace}, nil +} + +func _Encode_List_Response(ctx context.Context, response interface{}) (interface{}, error) { + if response == nil { + return nil, errors.New("nil ListResponse") + } + resp := response.(*transport.ListResponse) + respSpaces, err := ListPtrSpaceToProto(resp.Spaces) + if err != nil { + return nil, err + } + return &pb.ListResponse{Spaces: respSpaces}, nil +} + +func _Encode_Update_Response(ctx context.Context, response interface{}) (interface{}, error) { + return &empty.Empty{}, nil +} + +func _Encode_UpdateConfig_Response(ctx context.Context, response interface{}) (interface{}, error) { + return &empty.Empty{}, nil +} + +func _Encode_Delete_Response(ctx context.Context, response interface{}) (interface{}, error) { + return &empty.Empty{}, nil +} + +func _Decode_Create_Request(ctx context.Context, request interface{}) (interface{}, error) { + if request == nil { + return nil, errors.New("nil CreateRequest") + } + req := request.(*pb.CreateRequest) + reqSpace, err := ProtoToPtrSpace(req.Space) + if err != nil { + return nil, err + } + return &transport.CreateRequest{Space: reqSpace}, nil +} + +func _Decode_Get_Request(ctx context.Context, request interface{}) (interface{}, error) { + if request == nil { + return nil, errors.New("nil GetRequest") + } + req := request.(*pb.GetRequest) + return &transport.GetRequest{SpaceId: string(req.SpaceId)}, nil +} + +func _Decode_List_Request(ctx context.Context, request interface{}) (interface{}, error) { + if request == nil { + return nil, errors.New("nil ListRequest") + } + req := request.(*pb.ListRequest) + return &transport.ListRequest{OrgId: string(req.OrgId)}, nil +} + +func _Decode_Update_Request(ctx context.Context, request interface{}) (interface{}, error) { + if request == nil { + return nil, errors.New("nil UpdateRequest") + } + req := request.(*pb.UpdateRequest) + reqSpace, err := ProtoToPtrSpace(req.Space) + if err != nil { + return nil, err + } + return &transport.UpdateRequest{Space: reqSpace}, nil +} + +func _Decode_UpdateConfig_Request(ctx context.Context, request interface{}) (interface{}, error) { + if request == nil { + return nil, errors.New("nil UpdateConfigRequest") + } + req := request.(*pb.UpdateConfigRequest) + reqConfig, err := ProtoToPtrConfig(req.Config) + if err != nil { + return nil, err + } + return &transport.UpdateConfigRequest{ + Config: reqConfig, + SpaceId: string(req.SpaceId), + }, nil +} + +func _Decode_Delete_Request(ctx context.Context, request interface{}) (interface{}, error) { + if request == nil { + return nil, errors.New("nil DeleteRequest") + } + req := request.(*pb.DeleteRequest) + return &transport.DeleteRequest{SpaceId: string(req.SpaceId)}, nil +} + +func _Decode_Create_Response(ctx context.Context, response interface{}) (interface{}, error) { + if response == nil { + return nil, errors.New("nil CreateResponse") + } + resp := response.(*pb.CreateResponse) + respCreated, err := ProtoToPtrSpace(resp.Created) + if err != nil { + return nil, err + } + return &transport.CreateResponse{Created: respCreated}, nil +} + +func _Decode_Get_Response(ctx context.Context, response interface{}) (interface{}, error) { + if response == nil { + return nil, errors.New("nil GetResponse") + } + resp := response.(*pb.GetResponse) + respSpace, err := ProtoToPtrSpace(resp.Space) + if err != nil { + return nil, err + } + return &transport.GetResponse{Space: respSpace}, nil +} + +func _Decode_List_Response(ctx context.Context, response interface{}) (interface{}, error) { + if response == nil { + return nil, errors.New("nil ListResponse") + } + resp := response.(*pb.ListResponse) + respSpaces, err := ProtoToListPtrSpace(resp.Spaces) + if err != nil { + return nil, err + } + return &transport.ListResponse{Spaces: respSpaces}, nil +} + +func _Decode_Update_Response(ctx context.Context, response interface{}) (interface{}, error) { + return &empty.Empty{}, nil +} + +func _Decode_UpdateConfig_Response(ctx context.Context, response interface{}) (interface{}, error) { + return &empty.Empty{}, nil +} + +func _Decode_Delete_Response(ctx context.Context, response interface{}) (interface{}, error) { + return &empty.Empty{}, nil +} diff --git a/pkg/space/transport/grpc/protobuf_type_converters.microgen.go b/pkg/space/transport/grpc/protobuf_type_converters.microgen.go new file mode 100644 index 0000000000000000000000000000000000000000..56e2dc38265de3a9fa239b3d4d8cb37873558796 --- /dev/null +++ b/pkg/space/transport/grpc/protobuf_type_converters.microgen.go @@ -0,0 +1,76 @@ +// Code generated by microgen 0.9.1. DO NOT EDIT. + +// It is better for you if you do not change functions names! +// This file will never be overwritten. +package transportgrpc + +import ( + service "git.perx.ru/perxis/perxis-go/pkg/space" + pb "git.perx.ru/perxis/perxis-go/proto/spaces" +) + +func PtrConfigToProto(config *service.Config) (*pb.Config, error) { + if config == nil { + return nil, nil + } + return &pb.Config{ + Features: config.Features, + }, nil +} + +func ProtoToPtrConfig(protoConfig *pb.Config) (*service.Config, error) { + if protoConfig == nil { + return nil, nil + } + return &service.Config{ + Features: protoConfig.Features, + }, nil +} + +func PtrSpaceToProto(space *service.Space) (*pb.Space, error) { + if space == nil { + return nil, nil + } + cfg, _ := PtrConfigToProto(space.Config) + return &pb.Space{ + Id: space.ID, + OrgId: space.OrgID, + Name: space.Name, + Description: space.Description, + State: pb.State(space.State), + Config: cfg, + }, nil +} + +func ProtoToPtrSpace(protoSpace *pb.Space) (*service.Space, error) { + if protoSpace == nil { + return nil, nil + } + cfg, _ := ProtoToPtrConfig(protoSpace.Config) + return &service.Space{ + ID: protoSpace.Id, + OrgID: protoSpace.OrgId, + Name: protoSpace.Name, + Description: protoSpace.Description, + State: service.State(protoSpace.State), + Config: cfg, + }, nil +} + +func ListPtrSpaceToProto(spaces []*service.Space) ([]*pb.Space, error) { + protoSpaces := make([]*pb.Space, 0, len(spaces)) + for _, sp := range spaces { + protoSpace, _ := PtrSpaceToProto(sp) + protoSpaces = append(protoSpaces, protoSpace) + } + return protoSpaces, nil +} + +func ProtoToListPtrSpace(protoSpaces []*pb.Space) ([]*service.Space, error) { + spaces := make([]*service.Space, 0, len(protoSpaces)) + for _, sp := range protoSpaces { + space, _ := ProtoToPtrSpace(sp) + spaces = append(spaces, space) + } + return spaces, nil +} diff --git a/pkg/space/transport/grpc/server.go b/pkg/space/transport/grpc/server.go new file mode 100644 index 0000000000000000000000000000000000000000..f8220070b19fe5cc9a51ed7bdd8aa6fe5579d428 --- /dev/null +++ b/pkg/space/transport/grpc/server.go @@ -0,0 +1,22 @@ +package transportgrpc + +import ( + grpcerr "git.perx.ru/perxis/perxis-go/pkg/errors/grpc" + "git.perx.ru/perxis/perxis-go/pkg/space" + "git.perx.ru/perxis/perxis-go/pkg/space/transport" + pb "git.perx.ru/perxis/perxis-go/proto/spaces" + grpckit "github.com/go-kit/kit/transport/grpc" +) + +func NewServer(svc space.Spaces, opts ...grpckit.ServerOption) pb.SpacesServer { + eps := transport.Endpoints(svc) + eps = transport.EndpointsSet{ + CreateEndpoint: grpcerr.ServerMiddleware(eps.CreateEndpoint), + GetEndpoint: grpcerr.ServerMiddleware(eps.GetEndpoint), + ListEndpoint: grpcerr.ServerMiddleware(eps.ListEndpoint), + UpdateEndpoint: grpcerr.ServerMiddleware(eps.UpdateEndpoint), + UpdateConfigEndpoint: grpcerr.ServerMiddleware(eps.UpdateConfigEndpoint), + DeleteEndpoint: grpcerr.ServerMiddleware(eps.DeleteEndpoint), + } + return NewGRPCServer(&eps, opts...) +} diff --git a/pkg/space/transport/grpc/server.microgen.go b/pkg/space/transport/grpc/server.microgen.go new file mode 100644 index 0000000000000000000000000000000000000000..0d00433457f573073eeeabe5e41c4a3803d69c20 --- /dev/null +++ b/pkg/space/transport/grpc/server.microgen.go @@ -0,0 +1,112 @@ +// Code generated by microgen 0.9.1. DO NOT EDIT. + +// DO NOT EDIT. +package transportgrpc + +import ( + transport "git.perx.ru/perxis/perxis-go/pkg/space/transport" + pb "git.perx.ru/perxis/perxis-go/proto/spaces" + grpc "github.com/go-kit/kit/transport/grpc" + empty "github.com/golang/protobuf/ptypes/empty" + context "golang.org/x/net/context" +) + +type spacesServer struct { + create grpc.Handler + get grpc.Handler + list grpc.Handler + update grpc.Handler + updateConfig grpc.Handler + delete grpc.Handler + + pb.UnimplementedSpacesServer +} + +func NewGRPCServer(endpoints *transport.EndpointsSet, opts ...grpc.ServerOption) pb.SpacesServer { + return &spacesServer{ + create: grpc.NewServer( + endpoints.CreateEndpoint, + _Decode_Create_Request, + _Encode_Create_Response, + opts..., + ), + delete: grpc.NewServer( + endpoints.DeleteEndpoint, + _Decode_Delete_Request, + _Encode_Delete_Response, + opts..., + ), + get: grpc.NewServer( + endpoints.GetEndpoint, + _Decode_Get_Request, + _Encode_Get_Response, + opts..., + ), + list: grpc.NewServer( + endpoints.ListEndpoint, + _Decode_List_Request, + _Encode_List_Response, + opts..., + ), + update: grpc.NewServer( + endpoints.UpdateEndpoint, + _Decode_Update_Request, + _Encode_Update_Response, + opts..., + ), + updateConfig: grpc.NewServer( + endpoints.UpdateConfigEndpoint, + _Decode_UpdateConfig_Request, + _Encode_UpdateConfig_Response, + opts..., + ), + } +} + +func (S *spacesServer) Create(ctx context.Context, req *pb.CreateRequest) (*pb.CreateResponse, error) { + _, resp, err := S.create.ServeGRPC(ctx, req) + if err != nil { + return nil, err + } + return resp.(*pb.CreateResponse), nil +} + +func (S *spacesServer) Get(ctx context.Context, req *pb.GetRequest) (*pb.GetResponse, error) { + _, resp, err := S.get.ServeGRPC(ctx, req) + if err != nil { + return nil, err + } + return resp.(*pb.GetResponse), nil +} + +func (S *spacesServer) List(ctx context.Context, req *pb.ListRequest) (*pb.ListResponse, error) { + _, resp, err := S.list.ServeGRPC(ctx, req) + if err != nil { + return nil, err + } + return resp.(*pb.ListResponse), nil +} + +func (S *spacesServer) Update(ctx context.Context, req *pb.UpdateRequest) (*empty.Empty, error) { + _, resp, err := S.update.ServeGRPC(ctx, req) + if err != nil { + return nil, err + } + return resp.(*empty.Empty), nil +} + +func (S *spacesServer) UpdateConfig(ctx context.Context, req *pb.UpdateConfigRequest) (*empty.Empty, error) { + _, resp, err := S.updateConfig.ServeGRPC(ctx, req) + if err != nil { + return nil, err + } + return resp.(*empty.Empty), nil +} + +func (S *spacesServer) Delete(ctx context.Context, req *pb.DeleteRequest) (*empty.Empty, error) { + _, resp, err := S.delete.ServeGRPC(ctx, req) + if err != nil { + return nil, err + } + return resp.(*empty.Empty), nil +} diff --git a/pkg/space/transport/server.microgen.go b/pkg/space/transport/server.microgen.go new file mode 100644 index 0000000000000000000000000000000000000000..b4546383c62dae4fdc994a79f17ba3ee4345ceb1 --- /dev/null +++ b/pkg/space/transport/server.microgen.go @@ -0,0 +1,69 @@ +// Code generated by microgen 0.9.1. DO NOT EDIT. + +package transport + +import ( + "context" + + spaces "git.perx.ru/perxis/perxis-go/pkg/space" + endpoint "github.com/go-kit/kit/endpoint" +) + +func Endpoints(svc spaces.Spaces) EndpointsSet { + return EndpointsSet{ + CreateEndpoint: CreateEndpoint(svc), + DeleteEndpoint: DeleteEndpoint(svc), + GetEndpoint: GetEndpoint(svc), + ListEndpoint: ListEndpoint(svc), + UpdateConfigEndpoint: UpdateConfigEndpoint(svc), + UpdateEndpoint: UpdateEndpoint(svc), + } +} + +func CreateEndpoint(svc spaces.Spaces) endpoint.Endpoint { + return func(arg0 context.Context, request interface{}) (interface{}, error) { + req := request.(*CreateRequest) + res0, res1 := svc.Create(arg0, req.Space) + return &CreateResponse{Created: res0}, res1 + } +} + +func GetEndpoint(svc spaces.Spaces) endpoint.Endpoint { + return func(arg0 context.Context, request interface{}) (interface{}, error) { + req := request.(*GetRequest) + res0, res1 := svc.Get(arg0, req.SpaceId) + return &GetResponse{Space: res0}, res1 + } +} + +func ListEndpoint(svc spaces.Spaces) endpoint.Endpoint { + return func(arg0 context.Context, request interface{}) (interface{}, error) { + req := request.(*ListRequest) + res0, res1 := svc.List(arg0, req.OrgId) + return &ListResponse{Spaces: res0}, res1 + } +} + +func UpdateEndpoint(svc spaces.Spaces) endpoint.Endpoint { + return func(arg0 context.Context, request interface{}) (interface{}, error) { + req := request.(*UpdateRequest) + res0 := svc.Update(arg0, req.Space) + return &UpdateResponse{}, res0 + } +} + +func UpdateConfigEndpoint(svc spaces.Spaces) endpoint.Endpoint { + return func(arg0 context.Context, request interface{}) (interface{}, error) { + req := request.(*UpdateConfigRequest) + res0 := svc.UpdateConfig(arg0, req.SpaceId, req.Config) + return &UpdateConfigResponse{}, res0 + } +} + +func DeleteEndpoint(svc spaces.Spaces) endpoint.Endpoint { + return func(arg0 context.Context, request interface{}) (interface{}, error) { + req := request.(*DeleteRequest) + res0 := svc.Delete(arg0, req.SpaceId) + return &DeleteResponse{}, res0 + } +}