diff --git a/Makefile b/Makefile index d80ddb7351ba22863ea00e254d49d61fd409fb04..9a64367046d3ac93fdf4ec05437cfb15ffc43777 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,7 @@ +.PHONY: proto logging mocks .FORCE + +SHELL = bash + PROTODIR=perxis-proto/proto DSTDIR=./proto ALLPROTO?=$(shell find $(PROTODIR) -name '*.proto' ) @@ -6,6 +10,10 @@ PROTOFILES= $(filter-out $(PROTODIR)/status/status.proto, $(ALLPROTO)) PROTOGOFILES=$(PROTOFILES:.proto=.pb.go) PROTOGOGRPCFILES=$(PROTOFILES:.proto=_grpc.pb.go) +PKGDIR=pkg +ACCESSLOGGING=$(shell find $(PKGDIR) -name "logging_middleware.go" -type f) +ERRORLOGGING=$(shell find $(PKGDIR) -name "error_logging_middleware.go" -type f) + # Генерация grpc-клиентов для go proto: protoc-check protoc-gen-go-check $(PROTOGOFILES) @echo "Generated all protobuf Go files" @@ -33,26 +41,19 @@ ifeq (,$(wildcard $(GOPATH)/bin/protoc-gen-go)) or visit \"https://github.com/golang/protobuf/tree/v1.3.2#installation\" for more.\n") endif -SERVICESDIR=pkg -SERVICELOGGING=$(shell find $(SERVICESDIR) -name "logging_middleware.go" -type f) -ERRORLOGGING=$(shell find $(SERVICESDIR) -name "error_logging_middleware.go" -type f) - # Генерация логгирования (access & error) для всех сервисов. Предполагается наличие файлов `logging_middleware.go/error_middleware.go` # СЃ директивой go:generate Рё командой генерации РєРѕРґР° РІ директориях `/pkg` сервисов # Для установки инструмента генерации выполнить команду `go get -u github.com/hexdigest/gowrap/cmd/gowrap` -logging: $(ERRORLOGGING) $(SERVICELOGGING) +logging: $(ERRORLOGGING) $(ACCESSLOGGING) -%/middleware/logging_middleware.go: % .FORCE +%/middleware/logging_middleware.go: .FORCE + @echo "$@" @go generate "$@" -%/middleware/error_logging_middleware.go: % .FORCE +%/middleware/error_logging_middleware.go: .FORCE + @echo "$@" @go generate "$@" - -#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) diff --git a/go.mod b/go.mod index 597d3b27af4db4829c5b634cb9dbfacecb74ee80..c4bc532e1b85714da9e5a283f5b60f65748fa1f5 100644 --- a/go.mod +++ b/go.mod @@ -17,27 +17,38 @@ require ( github.com/stretchr/testify v1.8.0 go.mongodb.org/mongo-driver v1.11.4 go.uber.org/zap v1.19.1 - golang.org/x/crypto v0.5.0 - golang.org/x/net v0.8.0 + golang.org/x/crypto v0.8.0 + golang.org/x/net v0.9.0 google.golang.org/grpc v1.54.0 google.golang.org/protobuf v1.28.1 gopkg.in/yaml.v3 v3.0.1 ) require ( + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver/v3 v3.2.1 // indirect + github.com/Masterminds/sprig/v3 v3.2.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-kit/log v0.2.0 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/golang/snappy v0.0.1 // indirect + github.com/google/uuid v1.3.0 // indirect github.com/gosimple/unidecode v1.0.1 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect + github.com/hexdigest/gowrap v1.3.2 // indirect + github.com/huandu/xstrings v1.4.0 // indirect + github.com/imdario/mergo v0.3.15 // indirect github.com/klauspost/compress v1.13.6 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect github.com/nats-io/nkeys v0.3.0 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/shopspring/decimal v1.3.1 // indirect + github.com/spf13/cast v1.5.0 // indirect github.com/stretchr/objx v0.4.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.1 // indirect @@ -45,8 +56,10 @@ require ( github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.7.0 // indirect - golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect - golang.org/x/sys v0.6.0 // indirect - golang.org/x/text v0.8.0 // indirect + golang.org/x/mod v0.10.0 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.7.0 // indirect + golang.org/x/text v0.9.0 // indirect + golang.org/x/tools v0.8.0 // indirect google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect ) diff --git a/go.sum b/go.sum index 4860de219faa273cc4d3b494faded8fe08297813..53493f56d5ddbe17ec5350541663552f0dcb311c 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,11 @@ github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= +github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= github.com/antonmedv/expr v1.9.0 h1:j4HI3NHEdgDnN9p6oI6Ndr0G5QryMY0FNxT4ONrFDGU= github.com/antonmedv/expr v1.9.0/go.mod h1:5qsM3oLGDND7sDmQGDXHkYfkjYMUX14qsgqmHhwGEk8= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= @@ -26,6 +33,9 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gosimple/slug v1.13.1 h1:bQ+kpX9Qa6tHRaK+fZR0A0M2Kd7Pa5eHPPsb1JpHD+Q= github.com/gosimple/slug v1.13.1/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ= github.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6T/o= @@ -36,6 +46,14 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hexdigest/gowrap v1.3.2 h1:ZDhDFhrbAHYRdt9ZnULKZyggC/3+W9EpfX6R8DjlggY= +github.com/hexdigest/gowrap v1.3.2/go.mod h1:g8N2jI4n9AKrf843erksNTrt4sdkG+TGVfhWe8dWrJQ= +github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= +github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= +github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= @@ -55,8 +73,14 @@ github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo= github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -83,10 +107,17 @@ github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/sanity-io/litter v1.2.0/go.mod h1:JF6pZUFgu2Q0sBZ+HSV35P8TVPI1TTzEwyu9FXAw2W4= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= +github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= +github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -105,6 +136,7 @@ github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgk github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.mongodb.org/mongo-driver v1.11.4 h1:4ayjakA013OdpGyL2K3ZqylTac/rMjrJOMZ1EHizXas= go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -120,22 +152,36 @@ go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= 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-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= +golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -145,21 +191,34 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/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-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= 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= @@ -178,6 +237,7 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/pkg/clients/middleware/error_logging_middleware.go b/pkg/clients/middleware/error_logging_middleware.go index 3e60cc1d8e49f0712362a7e3e8f072571333a97a..0b96827a0c620ad1ca1aa5aaf6b93a821af6279d 100644 --- a/pkg/clients/middleware/error_logging_middleware.go +++ b/pkg/clients/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ +package middleware + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap -package middleware - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/clients -i Clients -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/clients/middleware/logging_middleware.go b/pkg/clients/middleware/logging_middleware.go index 1bf9b763e40232dd7b5ef87a1e049394e152e021..ef3ea5947a637bfa9caffa3af64f1f7cd2b8e019 100644 --- a/pkg/clients/middleware/logging_middleware.go +++ b/pkg/clients/middleware/logging_middleware.go @@ -1,9 +1,9 @@ +package middleware + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/access_log // gowrap: http://github.com/hexdigest/gowrap -package middleware - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/clients -i Clients -t ../../../assets/templates/middleware/access_log -o logging_middleware.go -l "" import ( diff --git a/pkg/collaborators/middleware/error_logging_middleware.go b/pkg/collaborators/middleware/error_logging_middleware.go index 304552a2fb8b9e0181ace20d76068f2d256d8848..a45dfd8053e1718fdc139f1792a9f0b1547c08d1 100644 --- a/pkg/collaborators/middleware/error_logging_middleware.go +++ b/pkg/collaborators/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/collaborators -i Collaborators -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/collaborators/middleware/logging_middleware.go b/pkg/collaborators/middleware/logging_middleware.go index f024149569452d3902ccb8f512487b22da59b069..41f541e6cc0e09f2fc6240d585159bda09c10a74 100644 --- a/pkg/collaborators/middleware/logging_middleware.go +++ b/pkg/collaborators/middleware/logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. -// template: ../../../../assets/templates/middleware/access_log +// template: ../../../assets/templates/middleware/access_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/collaborators -i Collaborators -t ../../../assets/templates/middleware/access_log -o logging_middleware.go -l "" import ( diff --git a/pkg/collections/middleware/error_logging_middleware.go b/pkg/collections/middleware/error_logging_middleware.go index cdee51d65d5c7b72d9132f1d29e08f32181de846..d1be7f66c8564cc162d93a926652c63d0a670e1d 100644 --- a/pkg/collections/middleware/error_logging_middleware.go +++ b/pkg/collections/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/collections -i Collections -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/collections/middleware/logging_middleware.go b/pkg/collections/middleware/logging_middleware.go index 53fcc84690189585c24d302e4410b69c670799bb..dd43cb9ffd3e662241a1bb08e7174cfd1c5677df 100644 --- a/pkg/collections/middleware/logging_middleware.go +++ b/pkg/collections/middleware/logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/access_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/collections -i Collections -t ../../../assets/templates/middleware/access_log -o logging_middleware.go -l "" import ( diff --git a/pkg/environments/middleware/error_logging_middleware.go b/pkg/environments/middleware/error_logging_middleware.go index b365f36d591257fe74ad49f8350755b8f6da9815..6d6cb544f129f2925d33be91f6666dcf8ebb8936 100644 --- a/pkg/environments/middleware/error_logging_middleware.go +++ b/pkg/environments/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/environments -i Environments -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/environments/middleware/logging_middleware.go b/pkg/environments/middleware/logging_middleware.go index 74a2efbf83a466387219ad4fba8e0c0241d71735..26f4eb279126e6a008db8998b83012c8a316ca2f 100644 --- a/pkg/environments/middleware/logging_middleware.go +++ b/pkg/environments/middleware/logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/access_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/environments -i Environments -t ../../../assets/templates/middleware/access_log -o logging_middleware.go -l "" import ( diff --git a/pkg/invitations/middleware/error_logging_middleware.go b/pkg/invitations/middleware/error_logging_middleware.go index b83d054478cafa8a5dbf3ab823adf0715dae90bc..39c823ae6fdf7fb7cb5c181c42099ca16c1a2bad 100644 --- a/pkg/invitations/middleware/error_logging_middleware.go +++ b/pkg/invitations/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/invitations -i Invitations -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/invitations/middleware/logging_middleware.go b/pkg/invitations/middleware/logging_middleware.go index d0e4d9c4c4d9e51c2d219112bcfce644475e7d88..8f1ceb9959497794cc4bc7a2d6a963a949d9b1a3 100644 --- a/pkg/invitations/middleware/logging_middleware.go +++ b/pkg/invitations/middleware/logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/access_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/invitations -i Invitations -t ../../../assets/templates/middleware/access_log -o logging_middleware.go -l "" import ( diff --git a/pkg/items/middleware/error_logging_middleware.go b/pkg/items/middleware/error_logging_middleware.go index 553461112586322dfddf38ccdddf31d373a4b29a..97967808d150cf951f3fb22b16b2836765fc611f 100644 --- a/pkg/items/middleware/error_logging_middleware.go +++ b/pkg/items/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/items -i Items -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/items/middleware/logging_middleware.go b/pkg/items/middleware/logging_middleware.go index ed47170e07c15f0b3d2189aa64b2a404259a4156..102b91874c63655c169e5c101b10490e375833b9 100644 --- a/pkg/items/middleware/logging_middleware.go +++ b/pkg/items/middleware/logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/access_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/items -i Items -t ../../../assets/templates/middleware/access_log -o logging_middleware.go -l "" import ( diff --git a/pkg/items/pagination.go b/pkg/items/pagination.go new file mode 100644 index 0000000000000000000000000000000000000000..7f990dc6c6e8d0684553e4039b86580236cc2ef0 --- /dev/null +++ b/pkg/items/pagination.go @@ -0,0 +1,137 @@ +package items + +import ( + "context" + + "git.perx.ru/perxis/perxis-go/pkg/content" + "git.perx.ru/perxis/perxis-go/pkg/data" + "git.perx.ru/perxis/perxis-go/pkg/errors" + "git.perx.ru/perxis/perxis-go/pkg/options" + "google.golang.org/grpc/codes" +) + +type BatchProcessor struct { + Content *content.Content + SpaceID, EnvID, CollectionID string + FindOptions *FindOptions + FindPublishedOptions *FindPublishedOptions + Filter *Filter + + pageSize, pageNum int + sort []string + processed int +} + +func (b *BatchProcessor) getBatch(ctx context.Context) ([]*Item, bool, error) { + var res []*Item + var err error + var total int + + if b.FindPublishedOptions != nil { + res, total, err = b.Content.Items.FindPublished( + ctx, + b.SpaceID, + b.EnvID, + b.CollectionID, + b.Filter, + &FindPublishedOptions{ + Regular: b.FindPublishedOptions.Regular, + Hidden: b.FindPublishedOptions.Hidden, + Templates: b.FindPublishedOptions.Templates, + FindOptions: *options.NewFindOptions(b.pageNum, b.pageSize, b.sort...), + }, + ) + } else { + res, total, err = b.Content.Items.Find( + ctx, + b.SpaceID, + b.EnvID, + b.CollectionID, + b.Filter, + &FindOptions{ + Deleted: b.FindOptions.Deleted, + Regular: b.FindOptions.Regular, + Hidden: b.FindOptions.Hidden, + Templates: b.FindOptions.Templates, + FindOptions: *options.NewFindOptions(b.pageNum, b.pageSize, b.sort...), + }, + ) + } + + if err == nil { + b.processed += len(res) + b.pageNum++ + } + + return res, b.processed != total, err +} + +func (b *BatchProcessor) next(ctx context.Context) (res []*Item, next bool, err error) { + + for { + res, next, err = b.getBatch(ctx) + if err != nil { + if errors.GetStatusCode(err) == codes.ResourceExhausted && b.reducePageSize() { + continue + } + + return nil, false, err + } + + break + } + + return res, next, nil +} + +func (b *BatchProcessor) reducePageSize() bool { + if b.pageSize == 1 { + return false + } + + b.pageNum = 2 * b.pageNum + b.pageSize = b.pageSize / 2 + + return true +} + +func (b *BatchProcessor) Do(ctx context.Context, f func(batch []*Item) error) (int, error) { + + if b.FindOptions == nil && b.FindPublishedOptions == nil { + b.FindOptions = new(FindOptions) + } + if b.FindOptions != nil { + b.pageSize = b.FindOptions.PageSize + b.sort = b.FindOptions.Sort + } + if b.FindPublishedOptions != nil { + b.pageSize = b.FindPublishedOptions.PageSize + b.sort = b.FindPublishedOptions.Sort + } + + if b.pageSize == 0 { + b.pageSize = 128 + } + + if b.Filter != nil && (len(b.Filter.ID) > 0 || len(b.Filter.Q) > 0) && !data.Contains("_id", b.sort) { + b.sort = append(b.sort, "_id") + } + + var err error + + next := true + for next { + + var batch []*Item + + batch, next, err = b.next(ctx) + if err != nil { + return 0, err + } + + if err = f(batch); err != nil { + return 0, err + } + } + return b.processed, nil +} diff --git a/pkg/locales/middleware/error_logging_middleware.go b/pkg/locales/middleware/error_logging_middleware.go index 171482568af8d1988bb1e2e6625884e78683c71e..695c91128d6f093d93f022468d464bedbd571e04 100644 --- a/pkg/locales/middleware/error_logging_middleware.go +++ b/pkg/locales/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/locales -i Locales -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/locales/middleware/logging_middleware.go b/pkg/locales/middleware/logging_middleware.go index 7e9a16b14ba1b2c619271d746245de4f1ddbcaae..fb98d25759e87d199e8c65a204f30b3acb48c1f4 100644 --- a/pkg/locales/middleware/logging_middleware.go +++ b/pkg/locales/middleware/logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/access_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/locales -i Locales -t ../../../assets/templates/middleware/access_log -o logging_middleware.go -l "" import ( diff --git a/pkg/members/middleware/error_logging_middleware.go b/pkg/members/middleware/error_logging_middleware.go index 5eb4e3b3ff6ba6417fdb96310916cca0345a055f..08d2814bf4fc8f16f0df57462770342a93e191c8 100644 --- a/pkg/members/middleware/error_logging_middleware.go +++ b/pkg/members/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/members -i Members -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/members/middleware/logging_middleware.go b/pkg/members/middleware/logging_middleware.go index 3b1687039af00f3747cf75b52bd0e18bc4512f1e..1b9ead6d06d694945c89638c52d4bce07e4ee938 100644 --- a/pkg/members/middleware/logging_middleware.go +++ b/pkg/members/middleware/logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/access_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/members -i Members -t ../../../assets/templates/middleware/access_log -o logging_middleware.go -l "" import ( diff --git a/pkg/organizations/middleware/error_logging_middleware.go b/pkg/organizations/middleware/error_logging_middleware.go index 5c2612fced88cb38fdf9bb56104b75bcd12f2db6..c9631f9144db6244044379219250ca334893d0d6 100644 --- a/pkg/organizations/middleware/error_logging_middleware.go +++ b/pkg/organizations/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/organizations -i Organizations -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/organizations/middleware/logging_middleware.go b/pkg/organizations/middleware/logging_middleware.go index ac446d73ef04a3f82191b686bf4b11354caaa3b0..6f33296d5cecbee19be4bff65da4280486cd1958 100644 --- a/pkg/organizations/middleware/logging_middleware.go +++ b/pkg/organizations/middleware/logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/access_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/organizations -i Organizations -t ../../../assets/templates/middleware/access_log -o logging_middleware.go -l "" import ( diff --git a/pkg/references/middleware/error_logging_middleware.go b/pkg/references/middleware/error_logging_middleware.go index e68bade9e992ead9699df8d0059d5d529167a480..9a62947f240842c6afb099a9b03cc966d9bd99b5 100644 --- a/pkg/references/middleware/error_logging_middleware.go +++ b/pkg/references/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/references -i References -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/references/middleware/logging_middleware.go b/pkg/references/middleware/logging_middleware.go index 692e298dc4e9ace0be13a0a6bc639e2aff4bf9c3..62a0e9d5cf26c6ab0d131fff2fd443cffd8fb8f3 100644 --- a/pkg/references/middleware/logging_middleware.go +++ b/pkg/references/middleware/logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/access_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/references -i References -t ../../../assets/templates/middleware/access_log -o logging_middleware.go -l "" import ( diff --git a/pkg/roles/middleware/error_logging_middleware.go b/pkg/roles/middleware/error_logging_middleware.go index a6ff0af444ed4154354d0d732f2b5edae612bcdc..7afe8f1f1003031ddedb437d0422dfb4123d4526 100644 --- a/pkg/roles/middleware/error_logging_middleware.go +++ b/pkg/roles/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/roles -i Roles -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/roles/middleware/logging_middleware.go b/pkg/roles/middleware/logging_middleware.go index 764a0136fc2bc72d040d3cb429ccc40103678190..ab536b6ad9e168adc79691a3127be8a47f9e5ba7 100644 --- a/pkg/roles/middleware/logging_middleware.go +++ b/pkg/roles/middleware/logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/access_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/roles -i Roles -t ../../../assets/templates/middleware/access_log -o logging_middleware.go -l "" import ( diff --git a/pkg/schemaloader/context.go b/pkg/schemaloader/context.go new file mode 100644 index 0000000000000000000000000000000000000000..7407b6b30939981f917c50d734ac770ec69b9e4e --- /dev/null +++ b/pkg/schemaloader/context.go @@ -0,0 +1,30 @@ +package schemaloader + +import "context" + +type LoaderContext struct { + SpaceID string + EnvID string +} + +type loaderCtxKey struct{} + +func WithContext(ctx context.Context, loaderContext *LoaderContext) context.Context { + if ctx == nil { + ctx = context.Background() + } + p, _ := ctx.Value(loaderCtxKey{}).(*LoaderContext) + if p != nil { + *p = *loaderContext + return ctx + } + return context.WithValue(ctx, loaderCtxKey{}, loaderContext) +} + +func GetContext(ctx context.Context) *LoaderContext { + p, _ := ctx.Value(loaderCtxKey{}).(*LoaderContext) + if p == nil { + return new(LoaderContext) + } + return p +} diff --git a/pkg/schemaloader/loader.go b/pkg/schemaloader/loader.go new file mode 100644 index 0000000000000000000000000000000000000000..e27baf4ea8b509adff88f7b9c5e99a48f15960b7 --- /dev/null +++ b/pkg/schemaloader/loader.go @@ -0,0 +1,92 @@ +package schemaloader + +import ( + "context" + "net/url" + "strings" + + "git.perx.ru/perxis/perxis-go/pkg/collections" + "git.perx.ru/perxis/perxis-go/pkg/errors" + "git.perx.ru/perxis/perxis-go/pkg/schema/field" +) + +// NewLoader возвращает новый загрузчик схем РёР· коллекций +// используется только РЅР° сервере +// РЅР° клиенте РЅСѓР¶РЅРѕ использовать методы получения полностью загруженных схем, для которых разрешение РїСЂРѕРёСЃС…РѕРґРёС‚ РЅР° сервере +func NewLoader(svc collections.Collections) field.Loader { + return &loader{svc: svc} +} + +type loader struct { + svc collections.Collections +} + +// Load - возвращает поля РїРѕ референсу РёР· коллекций (РЅРµ загруженные) +func (l *loader) Load(ctx context.Context, ref string) ([]*field.Field, error) { + spaceID, envID, colID, err := parseRef(ctx, ref) + if err != nil { + return nil, err + } + + filter := &collections.Filter{ID: []string{colID}} + + collections, err := l.svc.List(ctx, spaceID, envID, filter) + if err != nil { + return nil, errors.Wrapf(err, "schemaloader: failed to get collections for \"%s\"", ref) + } + + var schemas []*field.Field + for _, s := range collections { + if s.Schema != nil { + schemas = append(schemas, &s.Schema.Field) + } + } + + if len(schemas) == 0 { + return nil, errors.Errorf("schema not found \"%s\"", ref) + } + + return schemas, nil +} + +func parseRef(ctx context.Context, ref string) (spaceID, envID, colID string, err error) { + var u *url.URL + if u, err = url.Parse(ref); err != nil { + return + } + + parts := strings.SplitN(u.Path, "/", 3) + + switch len(parts) { + case 1: + colID = parts[0] + case 2: + spaceID = parts[0] + envID = "master" + colID = parts[1] + case 3: + spaceID = parts[0] + envID = parts[1] + colID = parts[2] + } + + if colID == "" { + err = errors.Errorf("invalid schema reference \"%s\"", ref) + } + + if loaderCtx := GetContext(ctx); loaderCtx != nil { + if spaceID == "" { + spaceID = loaderCtx.SpaceID + } + + if envID == "" { + envID = loaderCtx.EnvID + } + } + + if spaceID == "" { + err = errors.Errorf("can't identify space for reference \"%s\"", ref) + } + + return +} diff --git a/pkg/schemaloader/loader_test.go b/pkg/schemaloader/loader_test.go new file mode 100644 index 0000000000000000000000000000000000000000..f796fd8f669e31140e4171955c4d7db8723cec26 --- /dev/null +++ b/pkg/schemaloader/loader_test.go @@ -0,0 +1,141 @@ +package schemaloader + +import ( + "context" + "fmt" + "testing" + + "github.com/stretchr/testify/assert" +) + +//func Test_Load(t *testing.T) { +// +// const ( +// spaceID = "SpaceID" +// envID = "envID" +// colID = "colID" +// uri = "/colID#fieldID" +// ) +// +// t.Run("Load schema (success)", func(t *testing.T) { +// collSvs := &mocks.Collections{} +// +// sch := schema.New( +// "first_name", field.String(), +// "last_name", field.String(), +// ) +// +// cl := &collections.Collection{ID: colID, SpaceID: spaceID, EnvID: envID, Name: "Collection", Schema: sch} +// collSvs.On("List", mock.Anything, spaceID, envID, mock.AnythingOfType("*collections.Filter")).Run(func(args mock.Arguments) { +// filter := args[3].(*collections.Filter) +// +// assert.Equal(t, &collections.Filter{ID: []string{"colID"}}, filter, "Фильтр должен содержать идентификатор коллекции") +// }).Return([]*collections.Collection{cl}, nil).Once() +// +// loader := NewLoader(collSvs, spaceID, envID) +// schemas, err := loader.Load(nil, uri) +// +// require.NoError(t, err, "Ожидается успешное завершение") +// require.Equal(t, []*field.Field{&sch.Field}, schemas, "Метод должен возвращать срез схем") +// collSvs.AssertExpectations(t) +// }) +// +// t.Run("Collection doesn't have schema", func(t *testing.T) { +// collSvs := &mocks.Collections{} +// +// cl := &collections.Collection{ID: colID, SpaceID: spaceID, EnvID: envID, Name: "Collection"} +// collSvs.On("List", mock.Anything, spaceID, envID, mock.AnythingOfType("*collections.Filter")).Run(func(args mock.Arguments) { +// filter := args[3].(*collections.Filter) +// +// assert.Equal(t, &collections.Filter{ID: []string{"colID"}}, filter, "Фильтр должен содержать идентификатор коллекции") +// }).Return([]*collections.Collection{cl}, nil).Once() +// +// loader := NewLoader(collSvs, spaceID, envID) +// schemas, err := loader.Load(nil, uri) +// +// require.Error(t, err, "Ожидается ошибка") +// require.Contains(t, err.Error(), "schema not found") +// require.Nil(t, schemas, "Метод должен вернуть nil") +// //assert.Nil(t, schemas, "Метод должен вернуть nil") +// collSvs.AssertExpectations(t) +// }) +// +// t.Run("Loader not found collection", func(t *testing.T) { +// collSvs := &mocks.Collections{} +// +// collSvs.On("List", mock.Anything, spaceID, envID, mock.AnythingOfType("*collections.Filter")).Run(func(args mock.Arguments) { +// filter := args[3].(*collections.Filter) +// +// assert.Equal(t, &collections.Filter{ID: []string{"colID"}}, filter, "Фильтр должен содержать идентификатор коллекции") +// }).Return([]*collections.Collection{}, nil).Once() +// +// loader := NewLoader(collSvs, spaceID, envID) +// schemas, err := loader.Load(nil, uri) +// +// require.Error(t, err, "Ожидается ошибка") +// require.Contains(t, err.Error(), "schema not found") +// require.Nil(t, schemas, "Метод должен вернуть nil") +// collSvs.AssertExpectations(t) +// }) +// +// t.Run("Collection service return error", func(t *testing.T) { +// collSvs := &mocks.Collections{} +// +// collSvs.On("List", mock.Anything, spaceID, envID, mock.AnythingOfType("*collections.Filter")).Run(func(args mock.Arguments) { +// filter := args[3].(*collections.Filter) +// +// assert.Equal(t, &collections.Filter{ID: []string{"colID"}}, filter, "Фильтр должен содержать идентификатор коллекции") +// }).Return(nil, errors.New("storage error")).Once() +// +// loader := NewLoader(collSvs, spaceID, envID) +// schemas, err := loader.Load(nil, uri) +// +// require.Error(t, err, "Ожидается ошибка") +// require.Contains(t, err.Error(), "failed to get schema") +// require.Nil(t, schemas, "Метод должен вернуть nil") +// collSvs.AssertExpectations(t) +// }) +// +// t.Run("ParseMask return error", func(t *testing.T) { +// collSvs := &mocks.Collections{} +// +// loader := NewLoader(collSvs, spaceID, envID) +// schemas, err := loader.Load(nil, "") +// +// require.Error(t, err, "Ожидается ошибка") +// require.Contains(t, err.Error(), "invalid schema reference") +// require.Nil(t, schemas, "Метод должен вернуть nil") +// collSvs.AssertExpectations(t) +// }) +//} + +func Test_parseRef(t *testing.T) { + ctx := WithContext(nil, &LoaderContext{SpaceID: "spc", EnvID: "env"}) + tests := []struct { + ref string + ctx context.Context + wantSpaceID string + wantEnvId string + wantCollection string + wantErr assert.ErrorAssertionFunc + }{ + {"col", ctx, "spc", "env", "col", assert.NoError}, + {"/col", ctx, "spc", "master", "col", assert.NoError}, + {"spc1/env1/col", ctx, "spc1", "env1", "col", assert.NoError}, + {"spc1/env1/col#fld", ctx, "spc1", "env1", "col", assert.NoError}, + {"col%3f*", ctx, "spc", "env", "col?*", assert.NoError}, + {"#fld", ctx, "spc", "env", "", assert.Error}, + } + + for _, tt := range tests { + t.Run(tt.ref, func(t *testing.T) { + gotSpaceID, gotEnvId, gotCollection, err := parseRef(tt.ctx, tt.ref) + if !tt.wantErr(t, err, fmt.Sprintf("parseRef(%v)", tt.ref)) { + return + } + assert.Equalf(t, tt.wantSpaceID, gotSpaceID, "parseRef(%v)", tt.ref) + assert.Equalf(t, tt.wantEnvId, gotEnvId, "parseRef(%v)", tt.ref) + assert.Equalf(t, tt.wantCollection, gotCollection, "parseRef(%v)", tt.ref) + }) + } +} diff --git a/pkg/spaces/middleware/error_logging_middleware.go b/pkg/spaces/middleware/error_logging_middleware.go index d41b6678ecba526842c64aa519742eedab7e7779..85b629ba32abe38e5030077e8fe81b04206650b0 100644 --- a/pkg/spaces/middleware/error_logging_middleware.go +++ b/pkg/spaces/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/spaces -i Spaces -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/spaces/middleware/logging_middleware.go b/pkg/spaces/middleware/logging_middleware.go index c2b62dbbcdd111a19538b00b5c22ceeb52896dca..1471ea19535139210e79968e5a4522001a0b2ae3 100644 --- a/pkg/spaces/middleware/logging_middleware.go +++ b/pkg/spaces/middleware/logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/access_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/spaces -i Spaces -t ../../../assets/templates/middleware/access_log -o logging_middleware.go -l "" import ( diff --git a/pkg/template/builder.go b/pkg/template/builder.go new file mode 100644 index 0000000000000000000000000000000000000000..9a4ddcdb73e6b5c585d77088630096351d19b2bd --- /dev/null +++ b/pkg/template/builder.go @@ -0,0 +1,171 @@ +package template + +import ( + "bytes" + "context" + "text/template" + + "git.perx.ru/perxis/perxis-go/pkg/content" +) + +type Builder struct { + ctx context.Context + cnt *content.Content + SpaceID string + EnvID string + funcs template.FuncMap + data map[string]interface{} +} + +func NewBuilder(cnt *content.Content, space, env string) *Builder { + return &Builder{ + ctx: context.Background(), + cnt: cnt, + SpaceID: space, + EnvID: env, + funcs: make(template.FuncMap), + } +} + +func (b *Builder) getFuncs() template.FuncMap { + return template.FuncMap{ + "lookup": getLookup(b), + "system": getSystem(b), + } +} + +func (b *Builder) WithData(data map[string]interface{}) *Builder { + bld := *b + bld.data = data + return &bld +} + +func (b *Builder) WithKV(kv ...any) *Builder { + bld := *b + if bld.data == nil { + bld.data = make(map[string]interface{}, 10) + } + for i := 0; i < len(kv)-1; i += 2 { + k, _ := kv[i].(string) + v := kv[i+1] + if k != "" && v != nil { + bld.data[k] = v + } + } + return &bld +} + +func (b *Builder) GetData() map[string]interface{} { + return b.data +} + +func (b *Builder) WithSpace(space, env string) *Builder { + bld := *b + bld.SpaceID = space + bld.EnvID = env + return &bld +} + +func (b *Builder) WithContext(ctx context.Context) *Builder { + bld := *b + bld.ctx = ctx + return &bld +} + +func (b *Builder) Context() context.Context { + return b.ctx +} + +func (b *Builder) Template() *template.Template { + return template.New("main").Funcs(b.getFuncs()) +} + +func (b *Builder) Execute(str string, data ...any) (string, error) { + t := b.Template() + buf := new(bytes.Buffer) + t, err := t.Parse(str) + if err != nil { + return "", err + } + if err = t.Execute(buf, b.getData(data...)); err != nil { + return "", err + } + return buf.String(), nil +} + +func (b *Builder) ExecuteList(str []string, data ...any) ([]string, error) { + t := b.Template() + result := make([]string, len(str)) + buffer := new(bytes.Buffer) + for i, tmpl := range str { + if tmpl == "" { + continue + } + t, err := t.Parse(tmpl) + if err != nil { + return []string{}, err + } + if err = t.Execute(buffer, b.getData(data...)); err != nil { + return []string{}, err + } + result[i] = buffer.String() + buffer.Reset() + } + return result, nil +} + +func (b *Builder) ExecuteMap(str map[string]interface{}, data ...any) (map[string]interface{}, error) { + result := make(map[string]interface{}, len(str)) + for k, v := range str { + switch t := v.(type) { + case string: + value, err := b.Execute(t, data...) + if err != nil { + return nil, err + } + v = value + case []string: + values, err := b.ExecuteList(append([]string{k}, t...), data...) + if err != nil { + return nil, err + } + k = values[0] + vv := make([]interface{}, 0, len(t)) + for _, val := range values[1:] { + vv = append(vv, val) + } + v = vv + } + + result[k] = v + } + return result, nil +} + +func (b *Builder) getData(data ...any) any { + if len(data) == 0 { + return b.data + } + + var res map[string]interface{} + for _, v := range data { + if m, ok := v.(map[string]interface{}); ok && b.data != nil { + res = mergeMaps(b.data, m) + } + } + if res != nil { + return res + } + + return data[0] +} + +func mergeMaps(in ...map[string]interface{}) map[string]interface{} { + out := make(map[string]interface{}) + for _, i := range in { + for k, v := range i { + out[k] = v + } + } + return out +} diff --git a/pkg/template/builder_test.go b/pkg/template/builder_test.go new file mode 100644 index 0000000000000000000000000000000000000000..f8e2b34440dd73259a6ccd3ce9202a556caa5298 --- /dev/null +++ b/pkg/template/builder_test.go @@ -0,0 +1,272 @@ +package template + +import ( + "context" + "errors" + "testing" + "text/template" + + "git.perx.ru/perxis/perxis-go/pkg/content" + "git.perx.ru/perxis/perxis-go/pkg/items" + mocksitems "git.perx.ru/perxis/perxis-go/pkg/items/mocks" + "github.com/stretchr/testify/assert" +) + +func TestBuilder_Execute(t *testing.T) { + tests := []struct { + name string + ctx context.Context + cnt *content.Content + SpaceID string + EnvID string + funcs template.FuncMap + str string + data any + want any + wantErr bool + + itemsCall func(itemsSvc *mocksitems.Items) + }{ + {name: "error", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: "hello {{ .a }}", data: "world", want: "", wantErr: true}, + {name: "empty", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: "", data: "", want: "", wantErr: false}, + {name: "#1", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: "hello {{ . }}", data: "world", want: "hello world", wantErr: false}, + {name: "#2", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: "{{ . }}", data: "world", want: "world", wantErr: false}, + {name: "#3 ", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: "", data: "world", want: "", wantErr: false}, + {name: "#4 ", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: "hello", data: "world", want: "hello", wantErr: false}, + {name: "lookup", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: "hello, {{ lookup \"secrets.dev.key\" }}", data: "", want: "hello, Luk", wantErr: false, itemsCall: func(itemsSvc *mocksitems.Items) { + itemsSvc.On("Get", context.Background(), "space", "env", "secrets", "dev").Return(&items.Item{ + ID: "dev", + SpaceID: "space", + EnvID: "env", + CollectionID: "secrets", + Data: map[string]interface{}{ + "id": "dev", + "key": "Luk", + }, + }, nil).Once() + }}, + {name: "lookup with slice", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: "numbers {{ lookup \"secrets.dev.slice\" }}", data: "", want: "numbers [1 2 3]", wantErr: false, itemsCall: func(itemsSvc *mocksitems.Items) { + itemsSvc.On("Get", context.Background(), "space", "env", "secrets", "dev").Return(&items.Item{ + ID: "dev", + SpaceID: "space", + EnvID: "env", + CollectionID: "secrets", + Data: map[string]interface{}{ + "id": "dev", + "slice": []int{1, 2, 3}, + }, + }, nil).Once() + }}, + {name: "lookup with empty Data", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: "numbers {{ lookup \"secrets.dev.slice\" }}", data: "", want: "numbers <no value>", wantErr: false, itemsCall: func(itemsSvc *mocksitems.Items) { + itemsSvc.On("Get", context.Background(), "space", "env", "secrets", "dev").Return(&items.Item{ + ID: "dev", + SpaceID: "space", + EnvID: "env", + CollectionID: "secrets", + Data: map[string]interface{}{}, + }, nil).Once() + }}, + {name: "lookup with incorrect field", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: "hello {{ lookup \"secrets.dev.incorrect\" }}", data: "", want: "hello <no value>", wantErr: false, itemsCall: func(itemsSvc *mocksitems.Items) { + itemsSvc.On("Get", context.Background(), "space", "env", "secrets", "dev").Return(&items.Item{ + ID: "dev", + SpaceID: "space", + EnvID: "env", + CollectionID: "secrets", + Data: map[string]interface{}{ + "id": "dev", + "key": "1234", + }, + }, nil).Once() + }}, + {name: "lookup not found", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: "hello {{ lookup \"secrets.prod.pass\" }}", data: "", want: "", wantErr: true, itemsCall: func(itemsSvc *mocksitems.Items) { + itemsSvc.On("Get", context.Background(), "space", "env", "secrets", "prod").Return(nil, errors.New("not found")).Once() + }}, + {name: "lookup without itemID", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: "hello {{ lookup \"secrets.pass\" }}", data: "", want: "", wantErr: true}, + {name: "system ", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: "hello {{ system.SpaceID }}", data: "", want: "hello space", wantErr: false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + itemsSvc := &mocksitems.Items{} + if tt.itemsCall != nil { + tt.itemsCall(itemsSvc) + } + tt.cnt = &content.Content{ + Items: itemsSvc, + } + b := &Builder{ + ctx: tt.ctx, + cnt: tt.cnt, + SpaceID: tt.SpaceID, + EnvID: tt.EnvID, + funcs: tt.funcs, + } + + got, err := b.Execute(tt.str, tt.data) + if tt.wantErr == true { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + assert.Equal(t, tt.want, got) + if tt.itemsCall != nil { + itemsSvc.AssertExpectations(t) + } + }) + } +} + +func TestBuilder_ExecuteList(t *testing.T) { + tests := []struct { + name string + ctx context.Context + cnt *content.Content + SpaceID string + EnvID string + funcs template.FuncMap + str []string + data any + want []string + wantErr bool + + itemsCall func(itemsSvc *mocksitems.Items) + }{ + {name: "error", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: []string{"hello { . }}", "go {{ . }"}, data: "world", want: []string{}, wantErr: true}, + {name: "empty", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: []string{""}, data: "world", want: []string{""}, wantErr: false}, + {name: "#1", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: []string{"hello {{ . }}", "go {{ . }}"}, data: "world", want: []string{"hello world", "go world"}, wantErr: false}, + {name: "#2", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: []string{"{{ . }}"}, data: "world", want: []string{"world"}, wantErr: false}, + {name: "#3 ", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: []string{""}, data: "world", want: []string{""}, wantErr: false}, + {name: "#4 ", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: []string{"hello"}, data: "world", want: []string{"hello"}, wantErr: false}, + {name: "lookup", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: []string{"hello {{ lookup \"secrets.dev.key\" }}"}, data: "", want: []string{"hello 1234"}, wantErr: false, itemsCall: func(itemsSvc *mocksitems.Items) { + itemsSvc.On("Get", context.Background(), "space", "env", "secrets", "dev").Return(&items.Item{ + ID: "dev", + SpaceID: "space", + EnvID: "env", + CollectionID: "secrets", + Data: map[string]interface{}{ + "id": "dev", + "key": "1234", + }, + }, nil).Once() + }}, + {name: "lookup with incorrect field", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: []string{"hello {{ lookup \"secrets.dev.incorrect\" }}"}, data: "", want: []string{"hello <no value>"}, wantErr: false, itemsCall: func(itemsSvc *mocksitems.Items) { + itemsSvc.On("Get", context.Background(), "space", "env", "secrets", "dev").Return(&items.Item{ + ID: "dev", + SpaceID: "space", + EnvID: "env", + CollectionID: "secrets", + Data: map[string]interface{}{ + "id": "dev", + "key": "1234", + }, + }, nil).Once() + }}, + {name: "system ", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: []string{"hello {{ system.SpaceID }}"}, data: "", want: []string{"hello space"}, wantErr: false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + itemsSvc := &mocksitems.Items{} + if tt.itemsCall != nil { + tt.itemsCall(itemsSvc) + } + tt.cnt = &content.Content{ + Items: itemsSvc, + } + b := &Builder{ + ctx: tt.ctx, + cnt: tt.cnt, + SpaceID: tt.SpaceID, + EnvID: tt.EnvID, + funcs: tt.funcs, + } + + got, err := b.ExecuteList(tt.str, tt.data) + if tt.wantErr == true { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + assert.Equal(t, tt.want, got) + if tt.itemsCall != nil { + itemsSvc.AssertExpectations(t) + } + }) + } +} + +func TestBuilder_ExecuteMap(t *testing.T) { + tests := []struct { + name string + ctx context.Context + cnt *content.Content + SpaceID string + EnvID string + funcs template.FuncMap + str map[string]interface{} + data any + want map[string]interface{} + wantErr bool + + itemsCall func(itemsSvc *mocksitems.Items) + }{ + {name: "error", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: map[string]interface{}{"hello": "{{ . }"}, data: "world", want: nil, wantErr: true}, + {name: "empty", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: map[string]interface{}{}, data: "", want: map[string]interface{}{}, wantErr: false}, + {name: "#1", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: map[string]interface{}{"hello": "{{ . }}"}, data: "world", want: map[string]interface{}{"hello": "world"}, wantErr: false}, + {name: "#2", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: map[string]interface{}{"hello": "{{ . }}", "go": "{{ . }}"}, data: "world", want: map[string]interface{}{"hello": "world", "go": "world"}, wantErr: false}, + {name: "#3 ", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: map[string]interface{}{}, data: "world", want: map[string]interface{}{}, wantErr: false}, + {name: "#4 ", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: map[string]interface{}{"a": "b"}, data: "world", want: map[string]interface{}{"a": "b"}, wantErr: false}, + {name: "lookup ", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: map[string]interface{}{"hello": "{{ lookup \"secrets.dev.key\" }}"}, data: "", want: map[string]interface{}{"hello": "1234"}, wantErr: false, itemsCall: func(itemsSvc *mocksitems.Items) { + itemsSvc.On("Get", context.Background(), "space", "env", "secrets", "dev").Return(&items.Item{ + ID: "dev", + SpaceID: "space", + EnvID: "env", + CollectionID: "secrets", + Data: map[string]interface{}{ + "id": "dev", + "key": "1234", + }, + }, nil).Once() + }}, + {name: "lookup with incorrect field", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: map[string]interface{}{"hello": "{{ lookup \"secrets.dev.incorrect\" }}"}, data: "", want: map[string]interface{}{"hello": "<no value>"}, wantErr: false, itemsCall: func(itemsSvc *mocksitems.Items) { + itemsSvc.On("Get", context.Background(), "space", "env", "secrets", "dev").Return(&items.Item{ + ID: "dev", + SpaceID: "space", + EnvID: "env", + CollectionID: "secrets", + Data: map[string]interface{}{ + "id": "dev", + "key": "1234", + }, + }, nil).Once() + }}, + {name: "system ", ctx: context.Background(), cnt: &content.Content{}, SpaceID: "space", EnvID: "env", funcs: template.FuncMap{}, str: map[string]interface{}{"hello": "{{ system.SpaceID }}"}, data: "", want: map[string]interface{}{"hello": "space"}, wantErr: false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + itemsSvc := &mocksitems.Items{} + if tt.itemsCall != nil { + tt.itemsCall(itemsSvc) + } + tt.cnt = &content.Content{ + Items: itemsSvc, + } + b := &Builder{ + ctx: tt.ctx, + cnt: tt.cnt, + SpaceID: tt.SpaceID, + EnvID: tt.EnvID, + funcs: tt.funcs, + } + + got, err := b.ExecuteMap(tt.str, tt.data) + if tt.wantErr == true { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + assert.Equal(t, tt.want, got) + if tt.itemsCall != nil { + itemsSvc.AssertExpectations(t) + } + }) + } +} diff --git a/pkg/template/funcs.go b/pkg/template/funcs.go new file mode 100644 index 0000000000000000000000000000000000000000..0c320ad139e964f002b691ce097b24e70e6cfaf3 --- /dev/null +++ b/pkg/template/funcs.go @@ -0,0 +1,43 @@ +package template + +import ( + "strings" + + "git.perx.ru/perxis/perxis-go/pkg/errors" +) + +// getLookup возвращает функцию для шаблонизатора для получения значений РёР· записи коллекции +// name указывается РІ РІРёРґРµ "<collection id>.<item id>.<field>" +// Рспользование РІ шаблонах: {{ lookup "secrets.key.value" }} +func getLookup(b *Builder) any { + return func(name string) (any, error) { + parsedName := strings.Split(name, ".") + if len(parsedName) < 3 { + return "", errors.Errorf("incorrect parameter \"%s\"", name) + } + + collectionID := parsedName[0] + itemID := parsedName[1] + field := parsedName[2] + item, err := b.cnt.Items.Get(b.Context(), b.SpaceID, b.EnvID, collectionID, itemID) + if err != nil { + return "", errors.Wrapf(err, "failed to get \"%s\"") + } + + if len(item.Data) > 0 { + if v, ok := item.Data[field]; ok { + return v, nil + } + } + + return nil, nil + } +} + +// getSys возвращает функцию получения System +// Рспользование РІ шаблонах: {{ system.SpaceID }} +func getSystem(b *Builder) any { + return func() *System { + return &System{builder: b} + } +} diff --git a/pkg/template/system.go b/pkg/template/system.go new file mode 100644 index 0000000000000000000000000000000000000000..8f8548eb11444e72ad4f003b9225f4d4a38e4e2a --- /dev/null +++ b/pkg/template/system.go @@ -0,0 +1,13 @@ +package template + +type System struct { + builder *Builder +} + +func (s *System) SpaceID() string { + return s.builder.SpaceID +} + +func (s *System) EnvID() string { + return s.builder.EnvID +} diff --git a/pkg/users/middleware/error_logging_middleware.go b/pkg/users/middleware/error_logging_middleware.go index b0ec1fea8fa9fda00ac08a73e2e35e2dad51a549..a9084fa7a05608e45f7c5436934b5738c685a0e9 100644 --- a/pkg/users/middleware/error_logging_middleware.go +++ b/pkg/users/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/users -i Users -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/users/middleware/logging_middleware.go b/pkg/users/middleware/logging_middleware.go index a4bfb5fc53d8bc64a539eded9da47b2b6fa209c3..1fcae0626b75992ae563ff87adfd4e33edd49af6 100644 --- a/pkg/users/middleware/logging_middleware.go +++ b/pkg/users/middleware/logging_middleware.go @@ -1,9 +1,9 @@ +package service + // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/access_log // gowrap: http://github.com/hexdigest/gowrap -package service - //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/users -i Users -t ../../../assets/templates/middleware/access_log -o logging_middleware.go -l "" import (