diff --git a/README.md b/README.md index ca39bb8e..0274a902 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Price Whisper -![Coverage](https://img.shields.io/badge/Coverage-82.7%25-brightgreen) +![Coverage](https://img.shields.io/badge/Coverage-77.2%25-brightgreen) ![GitHub release (by tag)](https://img.shields.io/github/v/tag/onyxmoon/hsfl-master-ai-cloud-engineering.svg?sort=semver&label=Version&color=4ccc93d) [![Run tests (http proxy service)](https://github.com/Onyxmoon/hsfl-master-ai-cloud-engineering/actions/workflows/run-tests-http-proxy-service.yml/badge.svg)](https://github.com/Onyxmoon/hsfl-master-ai-cloud-engineering/actions/workflows/run-tests-http-proxy-service.yml) [![Run tests (product-service)](https://github.com/Onyxmoon/hsfl-master-ai-cloud-engineering/actions/workflows/run-tests-product-service.yml/badge.svg)](https://github.com/Onyxmoon/hsfl-master-ai-cloud-engineering/actions/workflows/run-tests-product-service.yml) diff --git a/docker-compose.dev.native.yml b/docker-compose.dev.native.yml index 4ac05253..3f307028 100644 --- a/docker-compose.dev.native.yml +++ b/docker-compose.dev.native.yml @@ -4,8 +4,7 @@ services: context: ./ dockerfile: ./src/http-proxy-service/Dockerfile environment: - - PROXY_DOCKER_CONFIG_PATH=./config - - PROXY_DOCKER_CONFIG_FILENAME=proxyConfig.docker.native.yaml + - PROXY_CONFIG_PATH=./config/proxyConfig.docker.native.yaml ports: - 8080:8080 depends_on: @@ -28,6 +27,7 @@ services: dockerfile: ./src/product-service/Dockerfile ports: - 3003:3003 + - 50051:50051 users: build: diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 68b99a95..d3e85093 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -4,8 +4,7 @@ services: context: ./ dockerfile: ./src/http-proxy-service/Dockerfile environment: - - PROXY_DOCKER_CONFIG_PATH=./config - - PROXY_DOCKER_CONFIG_FILENAME=proxyConfig.docker.yaml + - PROXY_CONFIG_PATH=./config/proxyConfig.docker.yaml ports: - 8080:8080 depends_on: @@ -18,9 +17,7 @@ services: context: ./ dockerfile: ./src/load-balancer-service/Dockerfile environment: - - IMAGE=onyxmoon/pw-web-service:latest - - REPLICAS=5 - - NETWORK_NAME=dev-network + - LOAD_BALANCER_CONFIG_PATH=./config/config.web-service.dev.yaml ports: - 3000:3000 volumes: diff --git a/docker-compose.native.yml b/docker-compose.native.yml index 046a19f6..1883c5c0 100644 --- a/docker-compose.native.yml +++ b/docker-compose.native.yml @@ -1,14 +1,10 @@ services: proxy: - build: - context: ./ - dockerfile: ./src/http-proxy-service/Dockerfile image: onyxmoon/pw-http-proxy-service:latest environment: - - PROXY_DOCKER_CONFIG_PATH=./config - - PROXY_DOCKER_CONFIG_FILENAME=proxyConfig.docker.native.yaml + - PROXY_CONFIG_PATH=./config/proxyConfig.docker.native.yaml ports: - - 80:8080 + - 8080:8080 - 443:8443 depends_on: - web @@ -17,9 +13,6 @@ services: - internal web: - build: - context: ./ - dockerfile: ./src/web-service/Dockerfile image: onyxmoon/pw-web-service:latest ports: - 3000:3000 @@ -31,9 +24,6 @@ services: - internal products: - build: - context: ./ - dockerfile: ./src/product-service/Dockerfile image: onyxmoon/pw-product-service:latest ports: - 3003:3003 @@ -41,9 +31,6 @@ services: - internal users: - build: - context: ./ - dockerfile: ./src/user-service/Dockerfile image: onyxmoon/pw-user-service:latest ports: - 3001:3001 @@ -51,9 +38,6 @@ services: - internal shoppinglists: - build: - context: ./ - dockerfile: ./src/shoppinglist-service/Dockerfile image: onyxmoon/pw-shoppinglist-service:latest ports: - 3002:3002 diff --git a/docker-compose.yml b/docker-compose.yml index 9da8bffa..9d8d7481 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,11 +5,9 @@ services: dockerfile: ./src/http-proxy-service/Dockerfile image: onyxmoon/pw-http-proxy-service:latest environment: - - PROXY_DOCKER_CONFIG_PATH=./config - - PROXY_DOCKER_CONFIG_FILENAME=proxyConfig.docker.yaml + - PROXY_CONFIG_PATH=./config/proxyConfig.docker.yaml ports: - - 80:8080 - - 443:8443 + - 8080:8080 depends_on: - load-balancer-web networks: @@ -22,9 +20,7 @@ services: dockerfile: ./src/load-balancer-service/Dockerfile image: onyxmoon/pw-load-balancer-service:latest environment: - - IMAGE=onyxmoon/pw-web-service:latest - - REPLICAS=5 - - NETWORK_NAME=bridge + - LOAD_BALANCER_CONFIG_PATH=./config/config.web-service.yaml ports: - 3000:3000 volumes: diff --git a/go.work b/go.work index 1cbcbc50..c32bb76a 100644 --- a/go.work +++ b/go.work @@ -8,4 +8,5 @@ use ( src/user-service src/web-service src/http-proxy-service + utils/http-stress-test ) diff --git a/go.work.sum b/go.work.sum index fa23cbf2..86dd6686 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,184 +1,807 @@ cloud.google.com/go v0.110.7 h1:rJyC7nWRg2jWGZ4wSJ5nY65GTdYJkg0cd/uXb+ACI6o= cloud.google.com/go v0.110.7/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= +cloud.google.com/go v0.110.8/go.mod h1:Iz8AkXJf1qmxC3Oxoep8R1T36w8B92yU29PcBhHO5fk= +cloud.google.com/go v0.110.10 h1:LXy9GEO+timppncPIAZoOj3l58LIU9k+kn48AN7IO3Y= +cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJNnic= +cloud.google.com/go/accessapproval v1.7.4 h1:ZvLvJ952zK8pFHINjpMBY5k7LTAp/6pBf50RDMRgBUI= +cloud.google.com/go/accessapproval v1.7.4/go.mod h1:/aTEh45LzplQgFYdQdwPMR9YdX0UlhBmvB84uAmQKUc= +cloud.google.com/go/accesscontextmanager v1.8.4 h1:Yo4g2XrBETBCqyWIibN3NHNPQKUfQqti0lI+70rubeE= +cloud.google.com/go/accesscontextmanager v1.8.4/go.mod h1:ParU+WbMpD34s5JFEnGAnPBYAgUHozaTmDJU7aCU9+M= +cloud.google.com/go/aiplatform v1.52.0 h1:TbbUvAujxXlSlbG5+XBtJEEEUyGjtyJxZ/VIlvz9Dps= +cloud.google.com/go/aiplatform v1.52.0/go.mod h1:pwZMGvqe0JRkI1GWSZCtnAfrR4K1bv65IHILGA//VEU= +cloud.google.com/go/aiplatform v1.54.0 h1:wH7OYl9Vq/5tupok0BPTFY9xaTLb0GxkReHtB5PF7cI= +cloud.google.com/go/aiplatform v1.54.0/go.mod h1:pwZMGvqe0JRkI1GWSZCtnAfrR4K1bv65IHILGA//VEU= +cloud.google.com/go/analytics v0.21.6 h1:fnV7B8lqyEYxCU0LKk+vUL7mTlqRAq4uFlIthIdr/iA= +cloud.google.com/go/analytics v0.21.6/go.mod h1:eiROFQKosh4hMaNhF85Oc9WO97Cpa7RggD40e/RBy8w= +cloud.google.com/go/apigateway v1.6.4 h1:VVIxCtVerchHienSlaGzV6XJGtEM9828Erzyr3miUGs= +cloud.google.com/go/apigateway v1.6.4/go.mod h1:0EpJlVGH5HwAN4VF4Iec8TAzGN1aQgbxAWGJsnPCGGY= +cloud.google.com/go/apigeeconnect v1.6.4 h1:jSoGITWKgAj/ssVogNE9SdsTqcXnryPzsulENSRlusI= +cloud.google.com/go/apigeeconnect v1.6.4/go.mod h1:CapQCWZ8TCjnU0d7PobxhpOdVz/OVJ2Hr/Zcuu1xFx0= +cloud.google.com/go/apigeeregistry v0.8.2 h1:DSaD1iiqvELag+lV4VnnqUUFd8GXELu01tKVdWZrviE= +cloud.google.com/go/apigeeregistry v0.8.2/go.mod h1:h4v11TDGdeXJDJvImtgK2AFVvMIgGWjSb0HRnBSjcX8= +cloud.google.com/go/appengine v1.8.4 h1:Qub3fqR7iA1daJWdzjp/Q0Jz0fUG0JbMc7Ui4E9IX/E= +cloud.google.com/go/appengine v1.8.4/go.mod h1:TZ24v+wXBujtkK77CXCpjZbnuTvsFNT41MUaZ28D6vg= +cloud.google.com/go/area120 v0.8.4 h1:YnSO8m02pOIo6AEOgiOoUDVbw4pf+bg2KLHi4rky320= +cloud.google.com/go/area120 v0.8.4/go.mod h1:jfawXjxf29wyBXr48+W+GyX/f8fflxp642D/bb9v68M= +cloud.google.com/go/artifactregistry v1.14.6 h1:/hQaadYytMdA5zBh+RciIrXZQBWK4vN7EUsrQHG+/t8= +cloud.google.com/go/artifactregistry v1.14.6/go.mod h1:np9LSFotNWHcjnOgh8UVK0RFPCTUGbO0ve3384xyHfE= +cloud.google.com/go/asset v1.15.3 h1:uI8Bdm81s0esVWbWrTHcjFDFKNOa9aB7rI1vud1hO84= +cloud.google.com/go/asset v1.15.3/go.mod h1:yYLfUD4wL4X589A9tYrv4rFrba0QlDeag0CMcM5ggXU= +cloud.google.com/go/assuredworkloads v1.11.4 h1:FsLSkmYYeNuzDm8L4YPfLWV+lQaUrJmH5OuD37t1k20= +cloud.google.com/go/assuredworkloads v1.11.4/go.mod h1:4pwwGNwy1RP0m+y12ef3Q/8PaiWrIDQ6nD2E8kvWI9U= +cloud.google.com/go/automl v1.13.4 h1:i9tOKXX+1gE7+rHpWKjiuPfGBVIYoWvLNIGpWgPtF58= +cloud.google.com/go/automl v1.13.4/go.mod h1:ULqwX/OLZ4hBVfKQaMtxMSTlPx0GqGbWN8uA/1EqCP8= +cloud.google.com/go/baremetalsolution v1.2.3 h1:oQiFYYCe0vwp7J8ZmF6siVKEumWtiPFJMJcGuyDVRUk= +cloud.google.com/go/baremetalsolution v1.2.3/go.mod h1:/UAQ5xG3faDdy180rCUv47e0jvpp3BFxT+Cl0PFjw5g= +cloud.google.com/go/batch v1.6.3 h1:mPiIH20a5NU02rucbAmLeO4sLPO9hrTK0BLjdHyW8xw= +cloud.google.com/go/batch v1.6.3/go.mod h1:J64gD4vsNSA2O5TtDB5AAux3nJ9iV8U3ilg3JDBYejU= +cloud.google.com/go/beyondcorp v1.0.3 h1:VXf9SnrnSmj2BF2cHkoTHvOUp8gjsz1KJFOMW7czdsY= +cloud.google.com/go/beyondcorp v1.0.3/go.mod h1:HcBvnEd7eYr+HGDd5ZbuVmBYX019C6CEXBonXbCVwJo= cloud.google.com/go/bigquery v1.8.0 h1:PQcPefKFdaIzjQFbiyOgAqyx8q5djaE7x9Sqe712DPA= +cloud.google.com/go/bigquery v1.57.1 h1:FiULdbbzUxWD0Y4ZGPSVCDLvqRSyCIO6zKV7E2nf5uA= +cloud.google.com/go/bigquery v1.57.1/go.mod h1:iYzC0tGVWt1jqSzBHqCr3lrRn0u13E8e+AqowBsDgug= +cloud.google.com/go/billing v1.17.4 h1:77/4kCqzH6Ou5CCDzNmqmboE+WvbwFBJmw1QZQz19AI= +cloud.google.com/go/billing v1.17.4/go.mod h1:5DOYQStCxquGprqfuid/7haD7th74kyMBHkjO/OvDtk= +cloud.google.com/go/binaryauthorization v1.7.3 h1:3R6WYn1JKIaVicBmo18jXubu7xh4mMkmbIgsTXk0cBA= +cloud.google.com/go/binaryauthorization v1.7.3/go.mod h1:VQ/nUGRKhrStlGr+8GMS8f6/vznYLkdK5vaKfdCIpvU= +cloud.google.com/go/certificatemanager v1.7.4 h1:5YMQ3Q+dqGpwUZ9X5sipsOQ1fLPsxod9HNq0+nrqc6I= +cloud.google.com/go/certificatemanager v1.7.4/go.mod h1:FHAylPe/6IIKuaRmHbjbdLhGhVQ+CWHSD5Jq0k4+cCE= +cloud.google.com/go/channel v1.17.3 h1:Rd4+fBrjiN6tZ4TR8R/38elkyEkz6oogGDr7jDyjmMY= +cloud.google.com/go/channel v1.17.3/go.mod h1:QcEBuZLGGrUMm7kNj9IbU1ZfmJq2apotsV83hbxX7eE= +cloud.google.com/go/cloudbuild v1.14.3 h1:hP6LDes9iqeppgGbmCkB3C3MvS12gJe5i4ZGtnnIO5c= +cloud.google.com/go/cloudbuild v1.14.3/go.mod h1:eIXYWmRt3UtggLnFGx4JvXcMj4kShhVzGndL1LwleEM= +cloud.google.com/go/cloudbuild v1.15.0 h1:9IHfEMWdCklJ1cwouoiQrnxmP0q3pH7JUt8Hqx4Qbck= +cloud.google.com/go/cloudbuild v1.15.0/go.mod h1:eIXYWmRt3UtggLnFGx4JvXcMj4kShhVzGndL1LwleEM= +cloud.google.com/go/clouddms v1.7.3 h1:xe/wJKz55VO1+L891a1EG9lVUgfHr9Ju/I3xh1nwF84= +cloud.google.com/go/clouddms v1.7.3/go.mod h1:fkN2HQQNUYInAU3NQ3vRLkV2iWs8lIdmBKOx4nrL6Hc= +cloud.google.com/go/cloudtasks v1.12.4 h1:5xXuFfAjg0Z5Wb81j2GAbB3e0bwroCeSF+5jBn/L650= +cloud.google.com/go/cloudtasks v1.12.4/go.mod h1:BEPu0Gtt2dU6FxZHNqqNdGqIG86qyWKBPGnsb7udGY0= +cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY= cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute v1.23.1/go.mod h1:CqB3xpmPKKt3OJpW2ndFIXnA9A4xAy/F3Xp1ixncW78= +cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk= +cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/contactcenterinsights v1.11.3 h1:Ui14kRKgQ3mVrMRkiBNzjdJIfFAN2qqiu9993ec9+jw= +cloud.google.com/go/contactcenterinsights v1.11.3/go.mod h1:HHX5wrz5LHVAwfI2smIotQG9x8Qd6gYilaHcLLLmNis= +cloud.google.com/go/contactcenterinsights v1.12.0 h1:wP41IUA4ucMVooj/TP53jd7vbNjWrDkAPOeulVJGT5U= +cloud.google.com/go/contactcenterinsights v1.12.0/go.mod h1:HHX5wrz5LHVAwfI2smIotQG9x8Qd6gYilaHcLLLmNis= +cloud.google.com/go/container v1.27.1 h1:ZfLRiFM9ddFE92SlA28rknI6YJMz5Z5huAQK+FKWxIQ= +cloud.google.com/go/container v1.27.1/go.mod h1:b1A1gJeTBXVLQ6GGw9/9M4FG94BEGsqJ5+t4d/3N7O4= +cloud.google.com/go/container v1.28.0 h1:/o82CFWXIYnT9p/07SnRgybqL3Pmmu86jYIlzlJVUBY= +cloud.google.com/go/container v1.28.0/go.mod h1:b1A1gJeTBXVLQ6GGw9/9M4FG94BEGsqJ5+t4d/3N7O4= +cloud.google.com/go/containeranalysis v0.11.3 h1:5rhYLX+3a01drpREqBZVXR9YmWH45RnML++8NsCtuD8= +cloud.google.com/go/containeranalysis v0.11.3/go.mod h1:kMeST7yWFQMGjiG9K7Eov+fPNQcGhb8mXj/UcTiWw9U= +cloud.google.com/go/datacatalog v1.18.3 h1:zmdxP6nOjN5Qb1rtu9h4kbEVwerQ6Oshf+t747QJUew= +cloud.google.com/go/datacatalog v1.18.3/go.mod h1:5FR6ZIF8RZrtml0VUao22FxhdjkoG+a0866rEnObryM= +cloud.google.com/go/datacatalog v1.19.0 h1:rbYNmHwvAOOwnW2FPXYkaK3Mf1MmGqRzK0mMiIEyLdo= +cloud.google.com/go/datacatalog v1.19.0/go.mod h1:5FR6ZIF8RZrtml0VUao22FxhdjkoG+a0866rEnObryM= +cloud.google.com/go/dataflow v0.9.4 h1:7VmCNWcPJBS/srN2QnStTB6nu4Eb5TMcpkmtaPVhRt4= +cloud.google.com/go/dataflow v0.9.4/go.mod h1:4G8vAkHYCSzU8b/kmsoR2lWyHJD85oMJPHMtan40K8w= +cloud.google.com/go/dataform v0.9.1 h1:jV+EsDamGX6cE127+QAcCR/lergVeeZdEQ6DdrxW3sQ= +cloud.google.com/go/dataform v0.9.1/go.mod h1:pWTg+zGQ7i16pyn0bS1ruqIE91SdL2FDMvEYu/8oQxs= +cloud.google.com/go/datafusion v1.7.4 h1:Q90alBEYlMi66zL5gMSGQHfbZLB55mOAg03DhwTTfsk= +cloud.google.com/go/datafusion v1.7.4/go.mod h1:BBs78WTOLYkT4GVZIXQCZT3GFpkpDN4aBY4NDX/jVlM= +cloud.google.com/go/datalabeling v0.8.4 h1:zrq4uMmunf2KFDl/7dS6iCDBBAxBnKVDyw6+ajz3yu0= +cloud.google.com/go/datalabeling v0.8.4/go.mod h1:Z1z3E6LHtffBGrNUkKwbwbDxTiXEApLzIgmymj8A3S8= +cloud.google.com/go/dataplex v1.11.1 h1:+malGTMnHubsSi0D6dbr3aqp86dKs0t4yAdmxKZGUm4= +cloud.google.com/go/dataplex v1.11.1/go.mod h1:mHJYQQ2VEJHsyoC0OdNyy988DvEbPhqFs5OOLffLX0c= +cloud.google.com/go/dataplex v1.11.2 h1:AfFFR15Ifh4U+Me1IBztrSd5CrasTODzy3x8KtDyHdc= +cloud.google.com/go/dataplex v1.11.2/go.mod h1:mHJYQQ2VEJHsyoC0OdNyy988DvEbPhqFs5OOLffLX0c= +cloud.google.com/go/dataproc v1.12.0 h1:W47qHL3W4BPkAIbk4SWmIERwsWBaNnWm0P2sdx3YgGU= +cloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4= +cloud.google.com/go/dataproc/v2 v2.2.3 h1:snv4EQfh1BfQ/HZS2MGbOqCgwEzYE/j6f30XFOTsgXg= +cloud.google.com/go/dataproc/v2 v2.2.3/go.mod h1:G5R6GBc9r36SXv/RtZIVfB8SipI+xVn0bX5SxUzVYbY= +cloud.google.com/go/dataproc/v2 v2.3.0 h1:tTVP9tTxmc8fixxOd/8s6Q6Pz/+yzn7r7XdZHretQH0= +cloud.google.com/go/dataproc/v2 v2.3.0/go.mod h1:G5R6GBc9r36SXv/RtZIVfB8SipI+xVn0bX5SxUzVYbY= +cloud.google.com/go/dataqna v0.8.4 h1:NJnu1kAPamZDs/if3bJ3+Wb6tjADHKL83NUWsaIp2zg= +cloud.google.com/go/dataqna v0.8.4/go.mod h1:mySRKjKg5Lz784P6sCov3p1QD+RZQONRMRjzGNcFd0c= cloud.google.com/go/datastore v1.1.0 h1:/May9ojXjRkPBNVrq+oWLqmWCkr4OU5uRY29bu0mRyQ= +cloud.google.com/go/datastore v1.15.0 h1:0P9WcsQeTWjuD1H14JIY7XQscIPQ4Laje8ti96IC5vg= +cloud.google.com/go/datastore v1.15.0/go.mod h1:GAeStMBIt9bPS7jMJA85kgkpsMkvseWWXiaHya9Jes8= +cloud.google.com/go/datastream v1.10.3 h1:Z2sKPIB7bT2kMW5Uhxy44ZgdJzxzE5uKjavoW+EuHEE= +cloud.google.com/go/datastream v1.10.3/go.mod h1:YR0USzgjhqA/Id0Ycu1VvZe8hEWwrkjuXrGbzeDOSEA= +cloud.google.com/go/deploy v1.14.2 h1:OWVwtGy+QeQGPT3yc8bJu6yANoPFpXniCgl7bJu5u88= +cloud.google.com/go/deploy v1.14.2/go.mod h1:e5XOUI5D+YGldyLNZ21wbp9S8otJbBE4i88PtO9x/2g= +cloud.google.com/go/deploy v1.15.0 h1:ZdmYzRMTGkVyP1nXEUat9FpbJGJemDcNcx82RSSOElc= +cloud.google.com/go/deploy v1.15.0/go.mod h1:e5XOUI5D+YGldyLNZ21wbp9S8otJbBE4i88PtO9x/2g= +cloud.google.com/go/dialogflow v1.44.3 h1:cK/f88KX+YVR4tLH4clMQlvrLWD2qmKJQziusjGPjmc= +cloud.google.com/go/dialogflow v1.44.3/go.mod h1:mHly4vU7cPXVweuB5R0zsYKPMzy240aQdAu06SqBbAQ= +cloud.google.com/go/dlp v1.11.1 h1:OFlXedmPP/5//X1hBEeq3D9kUVm9fb6ywYANlpv/EsQ= +cloud.google.com/go/dlp v1.11.1/go.mod h1:/PA2EnioBeXTL/0hInwgj0rfsQb3lpE3R8XUJxqUNKI= +cloud.google.com/go/documentai v1.23.5 h1:KAlzT+q8qvRxAmhsJUvLtfFHH0PNvz3M79H6CgVBKL8= +cloud.google.com/go/documentai v1.23.5/go.mod h1:ghzBsyVTiVdkfKaUCum/9bGBEyBjDO4GfooEcYKhN+g= +cloud.google.com/go/domains v0.9.4 h1:ua4GvsDztZ5F3xqjeLKVRDeOvJshf5QFgWGg1CKti3A= +cloud.google.com/go/domains v0.9.4/go.mod h1:27jmJGShuXYdUNjyDG0SodTfT5RwLi7xmH334Gvi3fY= +cloud.google.com/go/edgecontainer v1.1.4 h1:Szy3Q/N6bqgQGyxqjI+6xJZbmvPvnFHp3UZr95DKcQ0= +cloud.google.com/go/edgecontainer v1.1.4/go.mod h1:AvFdVuZuVGdgaE5YvlL1faAoa1ndRR/5XhXZvPBHbsE= +cloud.google.com/go/errorreporting v0.3.0 h1:kj1XEWMu8P0qlLhm3FwcaFsUvXChV/OraZwA70trRR0= +cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= +cloud.google.com/go/essentialcontacts v1.6.5 h1:S2if6wkjR4JCEAfDtIiYtD+sTz/oXjh2NUG4cgT1y/Q= +cloud.google.com/go/essentialcontacts v1.6.5/go.mod h1:jjYbPzw0x+yglXC890l6ECJWdYeZ5dlYACTFL0U/VuM= +cloud.google.com/go/eventarc v1.13.3 h1:+pFmO4eu4dOVipSaFBLkmqrRYG94Xl/TQZFOeohkuqU= +cloud.google.com/go/eventarc v1.13.3/go.mod h1:RWH10IAZIRcj1s/vClXkBgMHwh59ts7hSWcqD3kaclg= +cloud.google.com/go/filestore v1.7.4 h1:twtI5/89kf9QW7MqDic9fsUbH5ZLIDV1MVsRmu9iu2E= +cloud.google.com/go/filestore v1.7.4/go.mod h1:S5JCxIbFjeBhWMTfIYH2Jx24J6BqjwpkkPl+nBA5DlI= +cloud.google.com/go/filestore v1.8.0 h1:/+wUEGwk3x3Kxomi2cP5dsR8+SIXxo7M0THDjreFSYo= +cloud.google.com/go/filestore v1.8.0/go.mod h1:S5JCxIbFjeBhWMTfIYH2Jx24J6BqjwpkkPl+nBA5DlI= cloud.google.com/go/firestore v1.13.0 h1:/3S4RssUV4GO/kvgJZB+tayjhOfyAHs+KcpJgRVu/Qk= cloud.google.com/go/firestore v1.13.0/go.mod h1:QojqqOh8IntInDUSTAh0c8ZsPYAr68Ma8c5DWOy8xb8= +cloud.google.com/go/firestore v1.14.0 h1:8aLcKnMPoldYU3YHgu4t2exrKhLQkqaXAGqT0ljrFVw= +cloud.google.com/go/firestore v1.14.0/go.mod h1:96MVaHLsEhbvkBEdZgfN+AS/GIkco1LRpH9Xp9YZfzQ= +cloud.google.com/go/functions v1.15.4 h1:ZjdiV3MyumRM6++1Ixu6N0VV9LAGlCX4AhW6Yjr1t+U= +cloud.google.com/go/functions v1.15.4/go.mod h1:CAsTc3VlRMVvx+XqXxKqVevguqJpnVip4DdonFsX28I= +cloud.google.com/go/gkebackup v1.3.4 h1:KhnOrr9A1tXYIYeXKqCKbCI8TL2ZNGiD3dm+d7BDUBg= +cloud.google.com/go/gkebackup v1.3.4/go.mod h1:gLVlbM8h/nHIs09ns1qx3q3eaXcGSELgNu1DWXYz1HI= +cloud.google.com/go/gkeconnect v0.8.4 h1:1JLpZl31YhQDQeJ98tK6QiwTpgHFYRJwpntggpQQWis= +cloud.google.com/go/gkeconnect v0.8.4/go.mod h1:84hZz4UMlDCKl8ifVW8layK4WHlMAFeq8vbzjU0yJkw= +cloud.google.com/go/gkehub v0.14.4 h1:J5tYUtb3r0cl2mM7+YHvV32eL+uZQ7lONyUZnPikCEo= +cloud.google.com/go/gkehub v0.14.4/go.mod h1:Xispfu2MqnnFt8rV/2/3o73SK1snL8s9dYJ9G2oQMfc= +cloud.google.com/go/gkemulticloud v1.0.3 h1:NmJsNX9uQ2CT78957xnjXZb26TDIMvv+d5W2vVUt0Pg= +cloud.google.com/go/gkemulticloud v1.0.3/go.mod h1:7NpJBN94U6DY1xHIbsDqB2+TFZUfjLUKLjUX8NGLor0= +cloud.google.com/go/grafeas v0.3.0 h1:oyTL/KjiUeBs9eYLw/40cpSZglUC+0F7X4iu/8t7NWs= +cloud.google.com/go/grafeas v0.3.0/go.mod h1:P7hgN24EyONOTMyeJH6DxG4zD7fwiYa5Q6GUgyFSOU8= +cloud.google.com/go/gsuiteaddons v1.6.4 h1:uuw2Xd37yHftViSI8J2hUcCS8S7SH3ZWH09sUDLW30Q= +cloud.google.com/go/gsuiteaddons v1.6.4/go.mod h1:rxtstw7Fx22uLOXBpsvb9DUbC+fiXs7rF4U29KHM/pE= +cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= +cloud.google.com/go/iam v1.1.3/go.mod h1:3khUlaBXfPKKe7huYgEpDn6FtgRyMEqbkvBxrQyY5SE= +cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI= +cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8= +cloud.google.com/go/iap v1.9.3 h1:M4vDbQ4TLXdaljXVZSwW7XtxpwXUUarY2lIs66m0aCM= +cloud.google.com/go/iap v1.9.3/go.mod h1:DTdutSZBqkkOm2HEOTBzhZxh2mwwxshfD/h3yofAiCw= +cloud.google.com/go/ids v1.4.4 h1:VuFqv2ctf/A7AyKlNxVvlHTzjrEvumWaZflUzBPz/M4= +cloud.google.com/go/ids v1.4.4/go.mod h1:z+WUc2eEl6S/1aZWzwtVNWoSZslgzPxAboS0lZX0HjI= +cloud.google.com/go/iot v1.7.4 h1:m1WljtkZnvLTIRYW1YTOv5A6H1yKgLHR6nU7O8yf27w= +cloud.google.com/go/iot v1.7.4/go.mod h1:3TWqDVvsddYBG++nHSZmluoCAVGr1hAcabbWZNKEZLk= +cloud.google.com/go/kms v1.15.5 h1:pj1sRfut2eRbD9pFRjNnPNg/CzJPuQAzUujMIM1vVeM= +cloud.google.com/go/kms v1.15.5/go.mod h1:cU2H5jnp6G2TDpUGZyqTCoy1n16fbubHZjmVXSMtwDI= +cloud.google.com/go/language v1.12.2 h1:zg9uq2yS9PGIOdc0Kz/l+zMtOlxKWonZjjo5w5YPG2A= +cloud.google.com/go/language v1.12.2/go.mod h1:9idWapzr/JKXBBQ4lWqVX/hcadxB194ry20m/bTrhWc= +cloud.google.com/go/lifesciences v0.9.4 h1:rZEI/UxcxVKEzyoRS/kdJ1VoolNItRWjNN0Uk9tfexg= +cloud.google.com/go/lifesciences v0.9.4/go.mod h1:bhm64duKhMi7s9jR9WYJYvjAFJwRqNj+Nia7hF0Z7JA= +cloud.google.com/go/logging v1.8.1 h1:26skQWPeYhvIasWKm48+Eq7oUqdcdbwsCVwz5Ys0FvU= +cloud.google.com/go/logging v1.8.1/go.mod h1:TJjR+SimHwuC8MZ9cjByQulAMgni+RkXeI3wwctHJEI= cloud.google.com/go/longrunning v0.5.1 h1:Fr7TXftcqTudoyRJa113hyaqlGdiBQkp0Gq7tErFDWI= cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHSQl/fRUUQJYJc= +cloud.google.com/go/longrunning v0.5.2/go.mod h1:nqo6DQbNV2pXhGDbDMoN2bWz68MjZUzqv2YttZiveCs= +cloud.google.com/go/longrunning v0.5.4 h1:w8xEcbZodnA2BbW6sVirkkoC+1gP8wS57EUUgGS0GVg= +cloud.google.com/go/longrunning v0.5.4/go.mod h1:zqNVncI0BOP8ST6XQD1+VcvuShMmq7+xFSzOL++V0dI= +cloud.google.com/go/managedidentities v1.6.4 h1:SF/u1IJduMqQQdJA4MDyivlIQ4SrV5qAawkr/ZEREkY= +cloud.google.com/go/managedidentities v1.6.4/go.mod h1:WgyaECfHmF00t/1Uk8Oun3CQ2PGUtjc3e9Alh79wyiM= +cloud.google.com/go/maps v1.6.1 h1:2+eMp/1MvMPp5qrSOd3vtnLKa/pylt+krVRqET3jWsM= +cloud.google.com/go/maps v1.6.1/go.mod h1:4+buOHhYXFBp58Zj/K+Lc1rCmJssxxF4pJ5CJnhdz18= +cloud.google.com/go/mediatranslation v0.8.4 h1:VRCQfZB4s6jN0CSy7+cO3m4ewNwgVnaePanVCQh/9Z4= +cloud.google.com/go/mediatranslation v0.8.4/go.mod h1:9WstgtNVAdN53m6TQa5GjIjLqKQPXe74hwSCxUP6nj4= +cloud.google.com/go/memcache v1.10.4 h1:cdex/ayDd294XBj2cGeMe6Y+H1JvhN8y78B9UW7pxuQ= +cloud.google.com/go/memcache v1.10.4/go.mod h1:v/d8PuC8d1gD6Yn5+I3INzLR01IDn0N4Ym56RgikSI0= +cloud.google.com/go/metastore v1.13.3 h1:94l/Yxg9oBZjin2bzI79oK05feYefieDq0o5fjLSkC8= +cloud.google.com/go/metastore v1.13.3/go.mod h1:K+wdjXdtkdk7AQg4+sXS8bRrQa9gcOr+foOMF2tqINE= +cloud.google.com/go/monitoring v1.16.3 h1:mf2SN9qSoBtIgiMA4R/y4VADPWZA7VCNJA079qLaZQ8= +cloud.google.com/go/monitoring v1.16.3/go.mod h1:KwSsX5+8PnXv5NJnICZzW2R8pWTis8ypC4zmdRD63Tw= +cloud.google.com/go/networkconnectivity v1.14.3 h1:e9lUkCe2BexsqsUc2bjV8+gFBpQa54J+/F3qKVtW+wA= +cloud.google.com/go/networkconnectivity v1.14.3/go.mod h1:4aoeFdrJpYEXNvrnfyD5kIzs8YtHg945Og4koAjHQek= +cloud.google.com/go/networkmanagement v1.9.3 h1:HsQk4FNKJUX04k3OI6gUsoveiHMGvDRqlaFM2xGyvqU= +cloud.google.com/go/networkmanagement v1.9.3/go.mod h1:y7WMO1bRLaP5h3Obm4tey+NquUvB93Co1oh4wpL+XcU= +cloud.google.com/go/networksecurity v0.9.4 h1:947tNIPnj1bMGTIEBo3fc4QrrFKS5hh0bFVsHmFm4Vo= +cloud.google.com/go/networksecurity v0.9.4/go.mod h1:E9CeMZ2zDsNBkr8axKSYm8XyTqNhiCHf1JO/Vb8mD1w= +cloud.google.com/go/notebooks v1.11.2 h1:eTOTfNL1yM6L/PCtquJwjWg7ZZGR0URFaFgbs8kllbM= +cloud.google.com/go/notebooks v1.11.2/go.mod h1:z0tlHI/lREXC8BS2mIsUeR3agM1AkgLiS+Isov3SS70= +cloud.google.com/go/optimization v1.6.2 h1:iFsoexcp13cGT3k/Hv8PA5aK+FP7FnbhwDO9llnruas= +cloud.google.com/go/optimization v1.6.2/go.mod h1:mWNZ7B9/EyMCcwNl1frUGEuY6CPijSkz88Fz2vwKPOY= +cloud.google.com/go/orchestration v1.8.4 h1:kgwZ2f6qMMYIVBtUGGoU8yjYWwMTHDanLwM/CQCFaoQ= +cloud.google.com/go/orchestration v1.8.4/go.mod h1:d0lywZSVYtIoSZXb0iFjv9SaL13PGyVOKDxqGxEf/qI= +cloud.google.com/go/orgpolicy v1.11.4 h1:RWuXQDr9GDYhjmrredQJC7aY7cbyqP9ZuLbq5GJGves= +cloud.google.com/go/orgpolicy v1.11.4/go.mod h1:0+aNV/nrfoTQ4Mytv+Aw+stBDBjNf4d8fYRA9herfJI= +cloud.google.com/go/osconfig v1.12.4 h1:OrRCIYEAbrbXdhm13/JINn9pQchvTTIzgmOCA7uJw8I= +cloud.google.com/go/osconfig v1.12.4/go.mod h1:B1qEwJ/jzqSRslvdOCI8Kdnp0gSng0xW4LOnIebQomA= +cloud.google.com/go/oslogin v1.12.2 h1:NP/KgsD9+0r9hmHC5wKye0vJXVwdciv219DtYKYjgqE= +cloud.google.com/go/oslogin v1.12.2/go.mod h1:CQ3V8Jvw4Qo4WRhNPF0o+HAM4DiLuE27Ul9CX9g2QdY= +cloud.google.com/go/phishingprotection v0.8.4 h1:sPLUQkHq6b4AL0czSJZ0jd6vL55GSTHz2B3Md+TCZI0= +cloud.google.com/go/phishingprotection v0.8.4/go.mod h1:6b3kNPAc2AQ6jZfFHioZKg9MQNybDg4ixFd4RPZZ2nE= +cloud.google.com/go/policytroubleshooter v1.10.2 h1:sq+ScLP83d7GJy9+wpwYJVnY+q6xNTXwOdRIuYjvHT4= +cloud.google.com/go/policytroubleshooter v1.10.2/go.mod h1:m4uF3f6LseVEnMV6nknlN2vYGRb+75ylQwJdnOXfnv0= +cloud.google.com/go/privatecatalog v0.9.4 h1:Vo10IpWKbNvc/z/QZPVXgCiwfjpWoZ/wbgful4Uh/4E= +cloud.google.com/go/privatecatalog v0.9.4/go.mod h1:SOjm93f+5hp/U3PqMZAHTtBtluqLygrDrVO8X8tYtG0= cloud.google.com/go/pubsub v1.3.1 h1:ukjixP1wl0LpnZ6LWtZJ0mX5tBmjp1f8Sqer8Z2OMUU= +cloud.google.com/go/pubsub v1.33.0 h1:6SPCPvWav64tj0sVX/+npCBKhUi/UjJehy9op/V3p2g= +cloud.google.com/go/pubsub v1.33.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc= +cloud.google.com/go/pubsublite v1.8.1 h1:pX+idpWMIH30/K7c0epN6V703xpIcMXWRjKJsz0tYGY= +cloud.google.com/go/pubsublite v1.8.1/go.mod h1:fOLdU4f5xldK4RGJrBMm+J7zMWNj/k4PxwEZXy39QS0= +cloud.google.com/go/recaptchaenterprise/v2 v2.8.3 h1:UaV9C58snc5IsRQ6NN65jmRGnTdPT7mYZzK4Vbun+ik= +cloud.google.com/go/recaptchaenterprise/v2 v2.8.3/go.mod h1:Dak54rw6lC2gBY8FBznpOCAR58wKf+R+ZSJRoeJok4w= +cloud.google.com/go/recaptchaenterprise/v2 v2.8.4 h1:KOlLHLv3h3HwcZAkx91ubM3Oztz3JtT3ZacAJhWDorQ= +cloud.google.com/go/recaptchaenterprise/v2 v2.8.4/go.mod h1:Dak54rw6lC2gBY8FBznpOCAR58wKf+R+ZSJRoeJok4w= +cloud.google.com/go/recommendationengine v0.8.4 h1:JRiwe4hvu3auuh2hujiTc2qNgPPfVp+Q8KOpsXlEzKQ= +cloud.google.com/go/recommendationengine v0.8.4/go.mod h1:GEteCf1PATl5v5ZsQ60sTClUE0phbWmo3rQ1Js8louU= +cloud.google.com/go/recommender v1.11.3 h1:VndmgyS/J3+izR8V8BHa7HV/uun8//ivQ3k5eVKKyyM= +cloud.google.com/go/recommender v1.11.3/go.mod h1:+FJosKKJSId1MBFeJ/TTyoGQZiEelQQIZMKYYD8ruK4= +cloud.google.com/go/redis v1.14.1 h1:J9cEHxG9YLmA9o4jTSvWt/RuVEn6MTrPlYSCRHujxDQ= +cloud.google.com/go/redis v1.14.1/go.mod h1:MbmBxN8bEnQI4doZPC1BzADU4HGocHBk2de3SbgOkqs= +cloud.google.com/go/resourcemanager v1.9.4 h1:JwZ7Ggle54XQ/FVYSBrMLOQIKoIT/uer8mmNvNLK51k= +cloud.google.com/go/resourcemanager v1.9.4/go.mod h1:N1dhP9RFvo3lUfwtfLWVxfUWq8+KUQ+XLlHLH3BoFJ0= +cloud.google.com/go/resourcesettings v1.6.4 h1:yTIL2CsZswmMfFyx2Ic77oLVzfBFoWBYgpkgiSPnC4Y= +cloud.google.com/go/resourcesettings v1.6.4/go.mod h1:pYTTkWdv2lmQcjsthbZLNBP4QW140cs7wqA3DuqErVI= +cloud.google.com/go/retail v1.14.4 h1:geqdX1FNqqL2p0ADXjPpw8lq986iv5GrVcieTYafuJQ= +cloud.google.com/go/retail v1.14.4/go.mod h1:l/N7cMtY78yRnJqp5JW8emy7MB1nz8E4t2yfOmklYfg= +cloud.google.com/go/run v1.3.3 h1:qdfZteAm+vgzN1iXzILo3nJFQbzziudkJrvd9wCf3FQ= +cloud.google.com/go/run v1.3.3/go.mod h1:WSM5pGyJ7cfYyYbONVQBN4buz42zFqwG67Q3ch07iK4= +cloud.google.com/go/scheduler v1.10.4 h1:LXm6L6IYW3Fy8lxU7kvT7r6JiW/noxn2gItJmsvwzV4= +cloud.google.com/go/scheduler v1.10.4/go.mod h1:MTuXcrJC9tqOHhixdbHDFSIuh7xZF2IysiINDuiq6NI= +cloud.google.com/go/scheduler v1.10.5 h1:eMEettHlFhG5pXsoHouIM5nRT+k+zU4+GUvRtnxhuVI= +cloud.google.com/go/scheduler v1.10.5/go.mod h1:MTuXcrJC9tqOHhixdbHDFSIuh7xZF2IysiINDuiq6NI= +cloud.google.com/go/secretmanager v1.11.4 h1:krnX9qpG2kR2fJ+u+uNyNo+ACVhplIAS4Pu7u+4gd+k= +cloud.google.com/go/secretmanager v1.11.4/go.mod h1:wreJlbS9Zdq21lMzWmJ0XhWW2ZxgPeahsqeV/vZoJ3w= +cloud.google.com/go/security v1.15.4 h1:sdnh4Islb1ljaNhpIXlIPgb3eYj70QWgPVDKOUYvzJc= +cloud.google.com/go/security v1.15.4/go.mod h1:oN7C2uIZKhxCLiAAijKUCuHLZbIt/ghYEo8MqwD/Ty4= +cloud.google.com/go/securitycenter v1.24.2 h1:qCEyXoJoxNKKA1bDywBjjqCB7ODXazzHnVWnG5Uqd1M= +cloud.google.com/go/securitycenter v1.24.2/go.mod h1:l1XejOngggzqwr4Fa2Cn+iWZGf+aBLTXtB/vXjy5vXM= +cloud.google.com/go/servicedirectory v1.11.3 h1:5niCMfkw+jifmFtbBrtRedbXkJm3fubSR/KHbxSJZVM= +cloud.google.com/go/servicedirectory v1.11.3/go.mod h1:LV+cHkomRLr67YoQy3Xq2tUXBGOs5z5bPofdq7qtiAw= +cloud.google.com/go/shell v1.7.4 h1:nurhlJcSVFZneoRZgkBEHumTYf/kFJptCK2eBUq/88M= +cloud.google.com/go/shell v1.7.4/go.mod h1:yLeXB8eKLxw0dpEmXQ/FjriYrBijNsONpwnWsdPqlKM= +cloud.google.com/go/spanner v1.51.0 h1:l3exhhsVMKsx1E7Xd1QajYSvHmI1KZoWPW5tRxIIdvQ= +cloud.google.com/go/spanner v1.51.0/go.mod h1:c5KNo5LQ1X5tJwma9rSQZsXNBDNvj4/n8BVc3LNahq0= +cloud.google.com/go/spanner v1.53.0 h1:/NzWQJ1MEhdRcffiutRKbW/AIGVKhcTeivWTDjEyCCo= +cloud.google.com/go/spanner v1.53.0/go.mod h1:liG4iCeLqm5L3fFLU5whFITqP0e0orsAW1uUSrd4rws= +cloud.google.com/go/speech v1.20.1 h1:OpJ666ao7XxXewGSAkDUJnW188tJ5hNPoM7pZB+Q730= +cloud.google.com/go/speech v1.20.1/go.mod h1:wwolycgONvfz2EDU8rKuHRW3+wc9ILPsAWoikBEWavY= +cloud.google.com/go/speech v1.21.0 h1:qkxNao58oF8ghAHE1Eghen7XepawYEN5zuZXYWaUTA4= +cloud.google.com/go/speech v1.21.0/go.mod h1:wwolycgONvfz2EDU8rKuHRW3+wc9ILPsAWoikBEWavY= cloud.google.com/go/storage v1.14.0 h1:6RRlFMv1omScs6iq2hfE3IvgE+l6RfJPampq8UZc5TU= +cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E= +cloud.google.com/go/storage v1.35.1 h1:B59ahL//eDfx2IIKFBeT5Atm9wnNmj3+8xG/W4WB//w= +cloud.google.com/go/storage v1.35.1/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= +cloud.google.com/go/storagetransfer v1.10.3 h1:YM1dnj5gLjfL6aDldO2s4GeU8JoAvH1xyIwXre63KmI= +cloud.google.com/go/storagetransfer v1.10.3/go.mod h1:Up8LY2p6X68SZ+WToswpQbQHnJpOty/ACcMafuey8gc= +cloud.google.com/go/talent v1.6.5 h1:LnRJhhYkODDBoTwf6BeYkiJHFw9k+1mAFNyArwZUZAs= +cloud.google.com/go/talent v1.6.5/go.mod h1:Mf5cma696HmE+P2BWJ/ZwYqeJXEeU0UqjHFXVLadEDI= +cloud.google.com/go/texttospeech v1.7.4 h1:ahrzTgr7uAbvebuhkBAAVU6kRwVD0HWsmDsvMhtad5Q= +cloud.google.com/go/texttospeech v1.7.4/go.mod h1:vgv0002WvR4liGuSd5BJbWy4nDn5Ozco0uJymY5+U74= +cloud.google.com/go/tpu v1.6.4 h1:XIEH5c0WeYGaVy9H+UueiTaf3NI6XNdB4/v6TFQJxtE= +cloud.google.com/go/tpu v1.6.4/go.mod h1:NAm9q3Rq2wIlGnOhpYICNI7+bpBebMJbh0yyp3aNw1Y= +cloud.google.com/go/trace v1.10.4 h1:2qOAuAzNezwW3QN+t41BtkDJOG42HywL73q8x/f6fnM= +cloud.google.com/go/trace v1.10.4/go.mod h1:Nso99EDIK8Mj5/zmB+iGr9dosS/bzWCJ8wGmE6TXNWY= +cloud.google.com/go/translate v1.9.3 h1:t5WXTqlrk8VVJu/i3WrYQACjzYJiff5szARHiyqqPzI= +cloud.google.com/go/translate v1.9.3/go.mod h1:Kbq9RggWsbqZ9W5YpM94Q1Xv4dshw/gr/SHfsl5yCZ0= +cloud.google.com/go/video v1.20.3 h1:Xrpbm2S9UFQ1pZEeJt9Vqm5t2T/z9y/M3rNXhFoo8Is= +cloud.google.com/go/video v1.20.3/go.mod h1:TnH/mNZKVHeNtpamsSPygSR0iHtvrR/cW1/GDjN5+GU= +cloud.google.com/go/videointelligence v1.11.4 h1:YS4j7lY0zxYyneTFXjBJUj2r4CFe/UoIi/PJG0Zt/Rg= +cloud.google.com/go/videointelligence v1.11.4/go.mod h1:kPBMAYsTPFiQxMLmmjpcZUMklJp3nC9+ipJJtprccD8= +cloud.google.com/go/vision/v2 v2.7.5 h1:T/ujUghvEaTb+YnFY/jiYwVAkMbIC8EieK0CJo6B4vg= +cloud.google.com/go/vision/v2 v2.7.5/go.mod h1:GcviprJLFfK9OLf0z8Gm6lQb6ZFUulvpZws+mm6yPLM= +cloud.google.com/go/vmmigration v1.7.4 h1:qPNdab4aGgtaRX+51jCOtJxlJp6P26qua4o1xxUDjpc= +cloud.google.com/go/vmmigration v1.7.4/go.mod h1:yBXCmiLaB99hEl/G9ZooNx2GyzgsjKnw5fWcINRgD70= +cloud.google.com/go/vmwareengine v1.0.3 h1:WY526PqM6QNmFHSqe2sRfK6gRpzWjmL98UFkql2+JDM= +cloud.google.com/go/vmwareengine v1.0.3/go.mod h1:QSpdZ1stlbfKtyt6Iu19M6XRxjmXO+vb5a/R6Fvy2y4= +cloud.google.com/go/vpcaccess v1.7.4 h1:zbs3V+9ux45KYq8lxxn/wgXole6SlBHHKKyZhNJoS+8= +cloud.google.com/go/vpcaccess v1.7.4/go.mod h1:lA0KTvhtEOb/VOdnH/gwPuOzGgM+CWsmGu6bb4IoMKk= +cloud.google.com/go/webrisk v1.9.4 h1:iceR3k0BCRZgf2D/NiKviVMFfuNC9LmeNLtxUFRB/wI= +cloud.google.com/go/webrisk v1.9.4/go.mod h1:w7m4Ib4C+OseSr2GL66m0zMBywdrVNTDKsdEsfMl7X0= +cloud.google.com/go/websecurityscanner v1.6.4 h1:5Gp7h5j7jywxLUp6NTpjNPkgZb3ngl0tUSw6ICWvtJQ= +cloud.google.com/go/websecurityscanner v1.6.4/go.mod h1:mUiyMQ+dGpPPRkHgknIZeCzSHJ45+fY4F52nZFDHm2o= +cloud.google.com/go/workflows v1.12.3 h1:qocsqETmLAl34mSa01hKZjcqAvt699gaoFbooGGMvaM= +cloud.google.com/go/workflows v1.12.3/go.mod h1:fmOUeeqEwPzIU81foMjTRQIdwQHADi/vEr1cx9R1m5g= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= +github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/arrow/go/v12 v12.0.0 h1:xtZE63VWl7qLdB0JObIXvvhGjoVNrQ9ciIHG2OK5cmc= +github.com/apache/arrow/go/v12 v12.0.0/go.mod h1:d+tV/eHZZ7Dz7RPrFKtPK02tpr+c9/PEd/zm8mDS9Vg= +github.com/apache/thrift v0.16.0 h1:qEy6UW60iVOlUy+b9ZR0d5WzUWYGOo4HfopoyBaNmoY= +github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/atomicgo/cursor v0.0.1 h1:xdogsqa6YYlLfM+GyClC/Lchf7aiMerFiZQn7soTOoU= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= +github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= +github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible h1:C29Ae4G5GtYyYMm1aztcyj/J5ckgJm2zwdDajFbx1NY= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3 h1:TJH+oke8D16535+jHExHj4nQvzlZrj7ug5D7I/orNUA= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403 h1:cqQfy1jclcSy/FwLjemeg3SR1yaINm74aQyupQ0Bl8M= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe h1:QQ3GSy+MqSHxm/d8nCtnAiZdYFd45cYZPs8vOOIYKfk= +github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +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/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= +github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad h1:EmNYJhPYy0pOFjCx2PrgtaBXmee0iUX9hLlxE1xHOJE= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.11.1 h1:wSUXTlLfiAQRWs2F+p+EKOY9rUyis1MyGqJ2DIk5HpM= +github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g= github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= +github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= +github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= +github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= +github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= +github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/flatbuffers v2.0.8+incompatible h1:ivUb1cGomAB101ZM1T0nOiWz9pSrTMoa9+EiY7igmkM= +github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-pkcs11 v0.2.1-0.20230907215043-c6f79328ddf9 h1:OF1IPgv+F4NmqmJ98KTjdN97Vs1JxDPB3vbmYzV2dpk= +github.com/google/go-pkcs11 v0.2.1-0.20230907215043-c6f79328ddf9/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= +github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian/v3 v3.1.0 h1:wCKgOCHuUEVfsaQLpPSJb7VdYCdTVZQAuOdYm1yc/60= +github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2 h1:LR89qFljJ48s990kEKGsk213yIJDPI4205OKOzbURK8= github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= +github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.2.4/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/enterprise-certificate-proxy v0.3.1 h1:SBWmZhjUDRorQxrN0nwzf+AHBxnbFjViHQS4P0yVpmQ= github.com/googleapis/enterprise-certificate-proxy v0.3.1/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= +github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= +github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8 h1:tlyzajkF3030q6M8SvmJSemC9DTHL/xaMa18b65+JM4= +github.com/googleapis/google-cloud-go-testing v0.0.0-20210719221736-1c9a4c676720 h1:zC34cGQu69FG7qzJ3WiKW244WfhDC3xxYMeNOX2gtUQ= +github.com/googleapis/google-cloud-go-testing v0.0.0-20210719221736-1c9a4c676720/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjdKDqyr/2L+f6U12Fk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= github.com/hashicorp/consul/api v1.25.1 h1:CqrdhYzc8XZuPnhIYZWH45toM0LB9ZeYr/gvpLVI3PE= github.com/hashicorp/consul/api v1.25.1/go.mod h1:iiLVwR/htV7mas/sy0O+XSuEnrdBUUydemjxcUrAt4g= +github.com/hashicorp/consul/sdk v0.14.1 h1:ZiwE2bKb+zro68sWzZ1SgHF3kRMBZ94TwOCFRF4ylPs= +github.com/hashicorp/consul/sdk v0.14.1/go.mod h1:vFt03juSzocLRFo59NkeQHHmQa6+g7oU0pfzdI1mUhg= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +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/hashicorp/go-retryablehttp v0.5.3 h1:QlWt0KvWT0lq8MFppF9tsJGF+ynG7ztc2KIPhzRGk7s= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= +github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= +github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= +github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= 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/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.4 h1:sY0CMhFmjIPDMlTB+HfymFHCaYLhgifZ0QhjaYKD/UQ= +github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= +github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= +github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= +github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 h1:mV02weKRL81bEnm8A0HT1/CAelMQDBuQIfLw8n+d6xI= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 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/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= +github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= +github.com/klauspost/asmfmt v1.3.2 h1:4Ri7ox3EwapiOjCki+hw14RyKk201CN4rzyCJRFLpK4= +github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= +github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lyft/protoc-gen-star/v2 v2.0.3 h1:/3+/2sWyXeMLzKd1bX+ixWKgEMsULrIivpDsuaF441o= +github.com/lyft/protoc-gen-star/v2 v2.0.3/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= +github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= +github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 h1:AMFGa4R4MiIpspGNG7Z948v4n35fFGB3RR3G/ry4FWs= +github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= +github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 h1:+n/aFZefKZp7spd8DFdX7uMikMLXX4oubIzJF4kv/wI= +github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= +github.com/mitchellh/cli v1.1.0 h1:tEElEatulEHDeedTxwckzyYMA5c86fbmNIUL1hBIiTg= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +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= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nats-io/jwt/v2 v2.4.1 h1:Y35W1dgbbz2SQUYDPCaclXcuqleVmpbRa7646Jf2EX4= github.com/nats-io/jwt/v2 v2.4.1/go.mod h1:24BeQtRwxRV8ruvC4CojXlx/WQ/VjuwlYiH+vu/+ibI= github.com/nats-io/nats.go v1.30.2 h1:aloM0TGpPorZKQhbAkdCzYDj+ZmsJDyeo3Gkbr72NuY= github.com/nats-io/nats.go v1.30.2/go.mod h1:dcfhUgmQNN4GJEfIb2f9R7Fow+gzBF4emzDHrVBd5qM= +github.com/nats-io/nats.go v1.31.0 h1:/WFBHEc/dOKBF6qf1TZhrdEfTmOZ5JzdJ+Y3m6Y/p7E= +github.com/nats-io/nats.go v1.31.0/go.mod h1:di3Bm5MLsoB4Bx61CBTsxuarI36WbhAwOm8QrW39+i8= github.com/nats-io/nkeys v0.4.5 h1:Zdz2BUlFm4fJlierwvGK+yl20IAKUm7eV6AAZXEhkPk= github.com/nats-io/nkeys v0.4.5/go.mod h1:XUkxdLPTufzlihbamfzQ7mw/VGx6ObUs+0bN5sNvt64= +github.com/nats-io/nkeys v0.4.6 h1:IzVe95ru2CT6ta874rt9saQRkWfe2nFj1NtvYSLqMzY= +github.com/nats-io/nkeys v0.4.6/go.mod h1:4DxZNzenSVd1cYQoAa8948QY3QDjrHfcfVADymtkpts= github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0= +github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.1 h1:I2qBYMChEhIjOgazfJmV3/mZM256btk6wkCDRmW7JYs= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= +github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.11.1 h1:+4eQaD7vAZ6DsfsxB15hbE0odUjGI5ARs9yskGu1v4s= +github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f h1:UFr9zpz4xgTnIE5yIMtWAMngCdZ9p/+q6lTbgelo80M= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sagikazarmark/crypt v0.15.0 h1:TQJg76CemcIdJyC9/dmNjU9OUyIFHyvE50Tpq1t1nqY= github.com/sagikazarmark/crypt v0.15.0/go.mod h1:5rwNNax6Mlk9sZ40AcyVtiEw24Z4J04cfSioF2COKmc= +github.com/sagikazarmark/crypt v0.17.0 h1:ZA/7pXyjkHoK4bW4mIdnCLvL8hd+Nrbiw7Dqk7D4qUk= +github.com/sagikazarmark/crypt v0.17.0/go.mod h1:SMtHTvdmsZMuY/bpZoqokSoChIrcJ/epOxZN58PbZDg= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= github.com/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= go.etcd.io/etcd/api/v3 v3.5.9 h1:4wSsluwyTbGGmyjJktOf3wFQoTBIURXHnq9n/G/JQHs= go.etcd.io/etcd/api/v3 v3.5.9/go.mod h1:uyAal843mC8uUVSLWz6eHa/d971iDGnCRpmKd2Z+X8k= +go.etcd.io/etcd/api/v3 v3.5.10 h1:szRajuUUbLyppkhs9K6BRtjY37l66XQQmw7oZRANE4k= +go.etcd.io/etcd/api/v3 v3.5.10/go.mod h1:TidfmT4Uycad3NM/o25fG3J07odo4GBB9hoxaodFCtI= go.etcd.io/etcd/client/pkg/v3 v3.5.9 h1:oidDC4+YEuSIQbsR94rY9gur91UPL6DnxDCIYd2IGsE= go.etcd.io/etcd/client/pkg/v3 v3.5.9/go.mod h1:y+CzeSmkMpWN2Jyu1npecjB9BBnABxGM4pN8cGuJeL4= +go.etcd.io/etcd/client/pkg/v3 v3.5.10 h1:kfYIdQftBnbAq8pUWFXfpuuxFSKzlmM5cSn76JByiT0= +go.etcd.io/etcd/client/pkg/v3 v3.5.10/go.mod h1:DYivfIviIuQ8+/lCq4vcxuseg2P2XbHygkKwFo9fc8U= go.etcd.io/etcd/client/v2 v2.305.9 h1:YZ2OLi0OvR0H75AcgSUajjd5uqKDKocQUqROTG11jIo= go.etcd.io/etcd/client/v2 v2.305.9/go.mod h1:0NBdNx9wbxtEQLwAQtrDHwx58m02vXpDcgSYI2seohQ= +go.etcd.io/etcd/client/v2 v2.305.10 h1:MrmRktzv/XF8CvtQt+P6wLUlURaNpSDJHFZhe//2QE4= +go.etcd.io/etcd/client/v2 v2.305.10/go.mod h1:m3CKZi69HzilhVqtPDcjhSGp+kA1OmbNn0qamH80xjA= go.etcd.io/etcd/client/v3 v3.5.9 h1:r5xghnU7CwbUxD/fbUtRyJGaYNfDun8sp/gTr1hew6E= go.etcd.io/etcd/client/v3 v3.5.9/go.mod h1:i/Eo5LrZ5IKqpbtpPDuaUnDOUv471oDg8cjQaUr2MbA= +go.etcd.io/etcd/client/v3 v3.5.10 h1:W9TXNZ+oB3MCd/8UjxHTWK5J9Nquw9fQBLJd5ne5/Ao= +go.etcd.io/etcd/client/v3 v3.5.10/go.mod h1:RVeBnDz2PUEZqTpgqwAtUd8nAPf5kjyFyND7P1VkOKc= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= +go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= +golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= +golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.16.0 h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos= golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= +golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= +golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= +golang.org/x/oauth2 v0.14.0/go.mod h1:lAtNWgaWfL4cm7j2OV8TxGi9Qb7ECORx8DktCY74OwM= +golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= +golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/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-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +google.golang.org/api v0.128.0/go.mod h1:Y611qgqaE92On/7g65MQgxYul3c0rEB894kniWLY750= google.golang.org/api v0.143.0 h1:o8cekTkqhywkbZT6p1UHJPZ9+9uuCAJs/KYomxZB8fA= google.golang.org/api v0.143.0/go.mod h1:FoX9DO9hT7DLNn97OuoZAGSDuNAXdJRuGK98rSUgurk= +google.golang.org/api v0.149.0/go.mod h1:Mwn1B7JTXrzXtnvmzQE2BD6bYZQ8DShKZDZbeN9I7qI= +google.golang.org/api v0.150.0/go.mod h1:ccy+MJ6nrYFgE3WgRx/AMXOxOmU8Q4hSa+jjibzhxcg= +google.golang.org/api v0.152.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY= +google.golang.org/api v0.153.0 h1:N1AwGhielyKFaUqH07/ZSIQR3uNPcV7NVw0vj+j4iR4= +google.golang.org/api v0.153.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb h1:XFBgcDwm7irdHTbz4Zk2h7Mh+eis4nfJEFQFYzJzuIA= google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= +google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97/go.mod h1:t1VqOqqvce95G3hIDCT5FeO3YUc6Q4Oe24L/+rNMxRk= +google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:CgAqfJo+Xmu0GwA0411Ht3OU3OntXwsGmrmjI8ioGXI= +google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405/go.mod h1:3WDQMjmJk36UQhjQ89emUzb1mdaHcPeeAh4SCBKznB4= +google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ= +google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY= +google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3 h1:1hfbdAfFbkmpg41000wDVqr7jUpK/Yo+LPnIxxGzmkg= +google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3/go.mod h1:5RBcpGRxr25RbDzY5w+dmaqpSEvl8Gwl1x2CICf60ic= +google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb h1:lK0oleSc7IQsUxO3U5TjL9DWlsxpEBemh+zpB7IqhWI= google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= +google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97/go.mod h1:iargEX0SFPm3xcfMI0d1domjg0ZF4Aa0p2awqyxhvF0= +google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:IBQ646DjkDkvUIsVq/cc03FUFQ9wbZu7yE396YcL870= +google.golang.org/genproto/googleapis/api v0.0.0-20231030173426-d783a09b4405/go.mod h1:oT32Z4o8Zv2xPQTg0pbVaPr0MPOH6f14RgXt7zfIpwg= +google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:JpwMPBpFN3uKhdaekDpiNlImDdkUAyiJ6ez/uxGaUSo= +google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4= +google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f h1:2yNACc1O40tTnrsbk9Cv6oxiW8pxI/pXj0wRtdlYmgY= +google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f/go.mod h1:Uy9bTZJqmfrw2rIBxgGLnamc78euZULUBrLZ9XTITKI= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20231120223509-83a465c0220f h1:hL+1ptbhFoeL1HcROQ8OGXaqH0jYRRibgWQWco0/Ugc= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20231120223509-83a465c0220f/go.mod h1:iIgEblxoG4klcXsG0d9cpoxJ4xndv6+1FkDROCHhPRI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 h1:N3bU/SQDCDyD6R528GJ/PwW9KjYcJA3dgyH+MovAkIM= google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97/go.mod h1:v7nGkzlmW8P3n/bKmWBn2WpBjpOEx8Q6gMueudAmKfY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:swOH3j0KzcDDgGUWr+SNpyTen5YrXjS3eyPzFYKc6lc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405/go.mod h1:67X1fPuzjcrkymZzZV1vvkFeTn2Rvc6lYF9MYFGCcwE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:oQ5rr10WTTMvP4A36n8JpR1OrO1BEiV4f78CneXZxkA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= +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.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I= google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8= rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY= rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= +sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/lib/router/middleware/auth.go b/lib/router/middleware/auth.go new file mode 100644 index 00000000..26dc78d2 --- /dev/null +++ b/lib/router/middleware/auth.go @@ -0,0 +1,12 @@ +package middleware + +import ( + router "hsfl.de/group6/hsfl-master-ai-cloud-engineering/lib" + "net/http" +) + +func CreateAuthMiddleware() router.Middleware { + return func(w http.ResponseWriter, r *http.Request) *http.Request { + return r + } +} diff --git a/lib/router/router.go b/lib/router/router.go index ed82ff79..abb57350 100644 --- a/lib/router/router.go +++ b/lib/router/router.go @@ -7,6 +7,8 @@ import ( "regexp" ) +type Middleware = func(w http.ResponseWriter, r *http.Request) *http.Request + type route struct { method string pattern *regexp.Regexp @@ -15,7 +17,8 @@ type route struct { } type Router struct { - routes []route + routes []route + middlewares []Middleware } func New() *Router { @@ -32,6 +35,9 @@ func (router *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) { if len(matches) > 0 { r = createRequestContext(r, route.params, matches[1:]) + for _, middleware := range router.middlewares { + r = middleware(w, r) + } route.handler(w, r) return } @@ -53,7 +59,7 @@ func createRequestContext(r *http.Request, paramKeys []string, paramValues []str return r.WithContext(ctx) } -func (router *Router) addRoute(method string, pattern string, handler http.HandlerFunc) { +func (router *Router) addRoute(method string, pattern string, handler http.HandlerFunc, middlewares ...Middleware) { paramMatcher := regexp.MustCompile(":([a-zA-Z]+)|\\*") paramMatches := paramMatcher.FindAllStringSubmatch(pattern, -1) @@ -83,55 +89,64 @@ func (router *Router) addRoute(method string, pattern string, handler http.Handl router.routes = append(router.routes, route{ method: method, pattern: regexp.MustCompile("^" + pattern + "$"), - handler: handler, - params: params, + handler: func(w http.ResponseWriter, r *http.Request) { + for _, middleware := range middlewares { + r = middleware(w, r) + } + handler(w, r) + }, + params: params, }) } -func (router *Router) GET(pattern string, handler http.HandlerFunc) { - router.addRoute(http.MethodGet, pattern, handler) +func (router *Router) GET(pattern string, handler http.HandlerFunc, middlewares ...Middleware) { + router.addRoute(http.MethodGet, pattern, handler, middlewares...) +} + +func (router *Router) POST(pattern string, handler http.HandlerFunc, middlewares ...Middleware) { + router.addRoute(http.MethodPost, pattern, handler, middlewares...) } -func (router *Router) POST(pattern string, handler http.HandlerFunc) { - router.addRoute(http.MethodPost, pattern, handler) +func (router *Router) PUT(pattern string, handler http.HandlerFunc, middlewares ...Middleware) { + router.addRoute(http.MethodPut, pattern, handler, middlewares...) } -func (router *Router) PUT(pattern string, handler http.HandlerFunc) { - router.addRoute(http.MethodPut, pattern, handler) +func (router *Router) DELETE(pattern string, handler http.HandlerFunc, middlewares ...Middleware) { + router.addRoute(http.MethodDelete, pattern, handler, middlewares...) } -func (router *Router) DELETE(pattern string, handler http.HandlerFunc) { - router.addRoute(http.MethodDelete, pattern, handler) +func (router *Router) PATCH(pattern string, handler http.HandlerFunc, middlewares ...Middleware) { + router.addRoute(http.MethodPatch, pattern, handler, middlewares...) } -func (router *Router) PATCH(pattern string, handler http.HandlerFunc) { - router.addRoute(http.MethodPatch, pattern, handler) +func (router *Router) CONNECT(pattern string, handler http.HandlerFunc, middlewares ...Middleware) { + router.addRoute(http.MethodConnect, pattern, handler, middlewares...) } -func (router *Router) CONNECT(pattern string, handler http.HandlerFunc) { - router.addRoute(http.MethodConnect, pattern, handler) +func (router *Router) HEAD(pattern string, handler http.HandlerFunc, middlewares ...Middleware) { + router.addRoute(http.MethodHead, pattern, handler, middlewares...) } -func (router *Router) HEAD(pattern string, handler http.HandlerFunc) { - router.addRoute(http.MethodHead, pattern, handler) +func (router *Router) OPTIONS(pattern string, handler http.HandlerFunc, middlewares ...Middleware) { + router.addRoute(http.MethodOptions, pattern, handler, middlewares...) } -func (router *Router) OPTIONS(pattern string, handler http.HandlerFunc) { - router.addRoute(http.MethodOptions, pattern, handler) +func (router *Router) TRACE(pattern string, handler http.HandlerFunc, middlewares ...Middleware) { + router.addRoute(http.MethodTrace, pattern, handler, middlewares...) } -func (router *Router) TRACE(pattern string, handler http.HandlerFunc) { - router.addRoute(http.MethodTrace, pattern, handler) +func (router *Router) ALL(pattern string, handler http.HandlerFunc, middlewares ...Middleware) { + router.GET(pattern, handler, middlewares...) + router.POST(pattern, handler, middlewares...) + router.PUT(pattern, handler, middlewares...) + router.DELETE(pattern, handler, middlewares...) + router.PATCH(pattern, handler, middlewares...) + router.CONNECT(pattern, handler, middlewares...) + router.HEAD(pattern, handler, middlewares...) + router.OPTIONS(pattern, handler, middlewares...) + router.TRACE(pattern, handler, middlewares...) } -func (router *Router) ALL(pattern string, handler http.HandlerFunc) { - router.GET(pattern, handler) - router.POST(pattern, handler) - router.PUT(pattern, handler) - router.DELETE(pattern, handler) - router.PATCH(pattern, handler) - router.CONNECT(pattern, handler) - router.HEAD(pattern, handler) - router.OPTIONS(pattern, handler) - router.TRACE(pattern, handler) +func (router *Router) RegisterMiddleware(middleware Middleware) { + router.middlewares = append(router.middlewares, middleware) } diff --git a/lib/router/router_test.go b/lib/router/router_test.go index 8ff76ca3..4257cddc 100644 --- a/lib/router/router_test.go +++ b/lib/router/router_test.go @@ -59,4 +59,52 @@ func TestRouter(t *testing.T) { assert.Equal(t, "route", ctx.Value("route")) assert.Equal(t, "params", ctx.Value("params")) }) + + t.Run("should handle simple handler response", func(t *testing.T) { + // given + router := New() + handlerResponse := "Test response" + router.GET("/test/handler", func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(handlerResponse)) + }) + + w := httptest.NewRecorder() + r := httptest.NewRequest("GET", "/test/handler", nil) + + // when + router.ServeHTTP(w, r) + + // then + assert.Equal(t, http.StatusOK, w.Code) + assert.Equal(t, handlerResponse, w.Body.String()) + }) + + t.Run("should handle handler response with middleware", func(t *testing.T) { + // given + router := New() + handlerResponse := "Test response" + contextKey := "testKey" + expectedValue := "testValue" + var ctx context.Context + router.GET("/test/context", + func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(handlerResponse)) + w.WriteHeader(http.StatusOK) + ctx = r.Context() + }, + func(w http.ResponseWriter, r *http.Request) *http.Request { + return r.WithContext(context.WithValue(r.Context(), contextKey, expectedValue)) + }) + + w := httptest.NewRecorder() + r := httptest.NewRequest("GET", "/test/context", nil) + + // when + router.ServeHTTP(w, r) + + // then + assert.Equal(t, http.StatusOK, w.Code) + assert.Equal(t, expectedValue, ctx.Value(contextKey).(string)) + assert.Equal(t, handlerResponse, w.Body.String()) + }) } diff --git a/lib/rpc/product/product.proto b/lib/rpc/product/product.proto new file mode 100644 index 00000000..8bb05ece --- /dev/null +++ b/lib/rpc/product/product.proto @@ -0,0 +1,151 @@ +syntax = "proto3"; + +package product; + +option go_package = "./internal/proto"; + +message Product { + uint64 id = 1; + string description = 2; + uint64 ean = 3; +} + +message Price { + uint64 userId = 1; + uint64 productId = 2; + float price = 3; +} + +service ProductService { + // create method for adding a new product + rpc CreateProduct(CreateProductRequest) returns (CreateProductResponse); + + // read method for getting a product by id + rpc GetProduct(GetProductRequest) returns (GetProductResponse); + + // read method for getting all products + rpc GetAllProducts(GetAllProductsRequest) returns (GetAllProductsResponse); + + // update method for updating a product + rpc UpdateProduct(UpdateProductRequest) returns (UpdateProductResponse); + + // delete method to get rid of a product + rpc DeleteProduct(DeleteProductRequest) returns (DeleteProductResponse); +} + +service PriceService { + // create method for adding a new price + rpc CreatePrice(CreatePriceRequest) returns (CreatePriceResponse); + + // read method for finding a price by ids + rpc FindPrice(FindPriceRequest) returns (FindPriceResponse); + + // read method for finding all products + rpc FindAllPrices(FindAllPricesRequest) returns (FindAllPricesResponse); + + // read method for finding all products from a specific user/vendor + rpc FindAllPricesFromUser(FindAllPricesFromUserRequest) returns (FindAllPricesFromUserResponse); + + // update method for updating a price + rpc UpdatePrice(UpdatePriceRequest) returns (UpdatePriceResponse); + + // delete method to get rid of a price + rpc DeletePrice(DeletePriceRequest) returns (DeletePriceResponse); +} + +// Request- and Response-Messages for CreateProduct +message CreateProductRequest { + Product product = 1; +} + +message CreateProductResponse { + Product product = 1; +} + +// Request- and Response-Messages for GetProduct +message GetProductRequest { + uint64 id = 1; +} + +message GetProductResponse { + Product product = 1; +} + +// Request- and Response-Messages for ListProducts +message GetAllProductsRequest { +} + +message GetAllProductsResponse { + repeated Product products = 1; +} + +// Request- and Response-Messages for UpdateProduct +message UpdateProductRequest { + Product product = 1; +} + +message UpdateProductResponse { + Product product = 1; +} + +// Request- and Response-Messages for DeleteProduct +message DeleteProductRequest { + uint64 id = 1; +} + +message DeleteProductResponse { +} + +// Request- and Response-Messages for CreatePrice +message CreatePriceRequest { + Price price = 1; +} + +message CreatePriceResponse { + Price price = 1; +} + +// Request- and Response-Messages for FindPrice +message FindPriceRequest { + uint64 userId = 1; + uint64 productId = 2; +} + +message FindPriceResponse { + Price price = 1; +} + +// Request- and Response-Messages for FindAllPrices +message FindAllPricesRequest { +} + +message FindAllPricesResponse { + repeated Price price = 1; +} + +// Request- and Response-Messages for FindAllPricesFromUser +message FindAllPricesFromUserRequest { + uint64 userId = 1; +} + +message FindAllPricesFromUserResponse { + repeated Price price = 1; +} + +// Request- and Response-Messages for UpdateProduct +message UpdatePriceRequest { + Price price = 1; +} + +message UpdatePriceResponse { + Price price = 1; +} + +// Request- and Response-Messages for DeleteProduct +message DeletePriceRequest { + uint64 userId = 1; + uint64 productId = 2; +} + +message DeletePriceResponse { +} \ No newline at end of file diff --git a/lib/rpc/shoppinglist/shoppinglist.proto b/lib/rpc/shoppinglist/shoppinglist.proto new file mode 100644 index 00000000..1546c2ed --- /dev/null +++ b/lib/rpc/shoppinglist/shoppinglist.proto @@ -0,0 +1,144 @@ +syntax = "proto3"; + +package shoppinglist; + +option go_package = "./internal/proto"; + +message UserShoppingList { + uint64 id = 1; + uint64 userId = 2; + string description = 3; + bool completed = 4; +} + +message UserShoppingListEntry { + uint64 shoppingListId = 1; + uint64 productId = 2; + uint64 count = 3; + string note = 4; + bool checked = 5; +} + +service UserShoppingListService { + // create method for adding a new shopping list + rpc CreateUserShoppingList(CreateUserShoppingListRequest) returns (CreateUserShoppingListResponse); + + // read method for getting a specific shopping list + rpc GetUserShoppingList(GetUserShoppingListRequest) returns (GetUserShoppingListResponse); + + // read method for getting all shopping lists for an user + rpc GetAllUserShoppingLists(GetAllUserShoppingListsRequest) returns (GetAllUserShoppingListsResponse); + + // update method for updating a shopping list + rpc UpdateUserShoppingList(UpdateUserShoppingListRequest) returns (UpdateUserShoppingListResponse); + + // delete method to get rid of a shopping list + rpc DeleteUserShoppingList(DeleteUserShoppingListRequest) returns (DeleteUserShoppingListResponse); +} + +service UserShoppingListEntryService { + // create method for adding a new shopping list entry + rpc CreateUserShoppingListEntry(CreateUserShoppingListEntryRequest) returns (CreateUserShoppingListEntryResponse); + + // read method for getting a specific shopping list entry + rpc GetUserShoppingListEntry(GetUserShoppingListEntryRequest) returns (GetUserShoppingListEntryResponse); + + // read method for getting all shopping list entry for a specific shopping list + rpc GetAllUserShoppingListEntries(GetAllUserShoppingListEntriesRequest) returns (GetAllUserShoppingListEntriesResponse); + + // update method for updating a shopping list + rpc UpdateUserShoppingListEntry(UpdateUserShoppingListEntryRequest) returns (UpdateUserShoppingListEntryResponse); + + // delete method to get rid of a shopping list + rpc DeleteUserShoppingListEntry(DeleteUserShoppingListEntryRequest) returns (DeleteUserShoppingListEntryResponse); +} + +// Request- and Response-Messages for CreateUserShoppingList +message CreateUserShoppingListRequest { + UserShoppingList userShoppingList = 1; +} + +message CreateUserShoppingListResponse { + UserShoppingList userShoppingList = 1; +} + +// Request- and Response-Messages for GetUserShoppingList +message GetUserShoppingListRequest { + uint64 Id = 1; +} + +message GetUserShoppingListResponse { + UserShoppingList userShoppingList = 1; +} + +// Request- and Response-Messages for ListProducts +message GetAllUserShoppingListsRequest { + uint64 userId = 1; +} + +message GetAllUserShoppingListsResponse { + repeated UserShoppingList userShoppingList = 1; +} + +// Request- and Response-Messages for UpdateUserShoppingList +message UpdateUserShoppingListRequest { + UserShoppingList userShoppingList = 1; +} + +message UpdateUserShoppingListResponse { + UserShoppingList userShoppingList = 1; +} + +// Request- and Response-Messages for DeleteUserShoppingList +message DeleteUserShoppingListRequest { + uint64 id = 1; +} + +message DeleteUserShoppingListResponse { +} + +// Request- and Response-Messages for CreateUserShoppingListEntry +message CreateUserShoppingListEntryRequest { + UserShoppingListEntry userShoppingListEntry = 1; +} + +message CreateUserShoppingListEntryResponse { + UserShoppingListEntry userShoppingListEntry = 1; +} + +// Request- and Response-Messages for GetUserShoppingListEntry +message GetUserShoppingListEntryRequest { + uint64 shoppingListId = 1; + uint64 productId = 2; +} + +message GetUserShoppingListEntryResponse { + UserShoppingListEntry userShoppingListEntry = 1; +} + +// Request- and Response-Messages for GetAllUserShoppingListEntries +message GetAllUserShoppingListEntriesRequest { + uint64 id = 1; +} + +message GetAllUserShoppingListEntriesResponse { + repeated UserShoppingListEntry userShoppingListEntries = 1; +} + +// Request- and Response-Messages for UpdateUserShoppingList +message UpdateUserShoppingListEntryRequest { + UserShoppingListEntry userShoppingListEntry = 1; +} + +message UpdateUserShoppingListEntryResponse { + UserShoppingListEntry userShoppingListEntry = 1; +} + +// Request- and Response-Messages for DeleteUserShoppingList +message DeleteUserShoppingListEntryRequest { + uint64 shoppingListId = 1; + uint64 productId = 2; +} + +message DeleteUserShoppingListEntryResponse { +} \ No newline at end of file diff --git a/lib/rpc/user/user.proto b/lib/rpc/user/user.proto new file mode 100644 index 00000000..9aa5cd6f --- /dev/null +++ b/lib/rpc/user/user.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; + +package product; + +option go_package = "./internal/proto"; + +message User { + uint64 id = 1; + string email = 2; + string name = 3; + int64 role = 4; +} + +service UserService { + // validate a token and return a user + rpc ValidateUserToken(ValidateUserTokenRequest) returns (ValidateUserTokenResponse); +} + +message ValidateUserTokenRequest { + string token = 1; +} + +message ValidateUserTokenResponse { + User user = 1; +} + diff --git a/scripts/kubernetes-cluster/manifests/price-whisper/proxy.deployment.yaml b/scripts/kubernetes-cluster/manifests/price-whisper/proxy.deployment.yaml index d287f031..a821faa6 100644 --- a/scripts/kubernetes-cluster/manifests/price-whisper/proxy.deployment.yaml +++ b/scripts/kubernetes-cluster/manifests/price-whisper/proxy.deployment.yaml @@ -19,7 +19,5 @@ spec: ports: - containerPort: 8080 env: - - name: PROXY_DOCKER_CONFIG_PATH - value: "./config" - - name: PROXY_DOCKER_CONFIG_FILENAME - value: "proxyConfig.docker.native.yaml" \ No newline at end of file + - name: PROXY_CONFIG_PATH + value: "./config/proxyConfig.docker.native.yaml" \ No newline at end of file diff --git a/src/http-proxy-service/Dockerfile b/src/http-proxy-service/Dockerfile index 6f9e5444..ab2bc468 100644 --- a/src/http-proxy-service/Dockerfile +++ b/src/http-proxy-service/Dockerfile @@ -1,8 +1,5 @@ FROM golang:1.21-alpine -ARG PROXY_DOCKER_MODE -ENV PROXY_DOCKER_MODE $PROXY_DOCKER_MODE - WORKDIR /app COPY ./lib ./lib COPY ./src/http-proxy-service ./src/http-proxy-service diff --git a/src/http-proxy-service/main.go b/src/http-proxy-service/main.go index 8b204919..78dd6c4f 100644 --- a/src/http-proxy-service/main.go +++ b/src/http-proxy-service/main.go @@ -8,26 +8,20 @@ import ( "os" ) -var proxyConfigPath = "./config" -var proxyConfigFilename = "proxyConfig.yaml" +var proxyConfigPath = "./config/proxyConfig.yaml" func main() { log.Printf("Prepare service: http-proxy-service") var proxyConfig *proxy.Config - envPath, isEnvPathSet := os.LookupEnv("PROXY_DOCKER_CONFIG_PATH") - envFilename, isEnvFilenameSet := os.LookupEnv("PROXY_DOCKER_CONFIG_FILENAME") + envPath, isEnvPathSet := os.LookupEnv("PROXY_CONFIG_PATH") if isEnvPathSet { proxyConfigPath = envPath } - if isEnvFilenameSet { - proxyConfigFilename = envFilename - } - - proxyConfig = proxyutils.DefaultProxyManagerConfigurationReader(proxyConfigPath, proxyConfigFilename) + proxyConfig = proxyutils.DefaultProxyManagerConfigurationReader(proxyConfigPath) log.Printf("Configuration loaded successfully with %d mappings", len(proxyConfig.ProxyRoutes)) proxyManager := proxy.NewDefaultManager(proxyConfig) diff --git a/src/http-proxy-service/proxy/proxyutils/default_proxy_manager_configuration_reader.go b/src/http-proxy-service/proxy/proxyutils/default_proxy_manager_configuration_reader.go index 8cb7bf1f..9929c2ba 100644 --- a/src/http-proxy-service/proxy/proxyutils/default_proxy_manager_configuration_reader.go +++ b/src/http-proxy-service/proxy/proxyutils/default_proxy_manager_configuration_reader.go @@ -6,10 +6,8 @@ import ( "log" ) -func DefaultProxyManagerConfigurationReader(path string, filename string) *proxy.Config { - viper.AddConfigPath(path) - viper.SetConfigType("yaml") - viper.SetConfigName(filename) +func DefaultProxyManagerConfigurationReader(path string) *proxy.Config { + viper.SetConfigFile(path) err := viper.ReadInConfig() if err != nil { diff --git a/src/load-balancer-service/Dockerfile b/src/load-balancer-service/Dockerfile index 90291cf4..e2ef4eae 100644 --- a/src/load-balancer-service/Dockerfile +++ b/src/load-balancer-service/Dockerfile @@ -1,10 +1,6 @@ FROM golang:1.21-alpine -ARG IMAGE -ARG REPLICAS -ARG NETWORK_NAME -ENV IMAGE $IMAGE -ENV REPLICAS $REPLICAS -ENV NETWORK_NAME $NETWORK_NAME +ARG LOAD_BALANCER_CONFIG_PATH +ENV LOAD_BALANCER_CONFIG_PATH $LOAD_BALANCER_CONFIG_PATH WORKDIR /app COPY ./src/load-balancer-service ./src/load-balancer-service @@ -14,4 +10,4 @@ RUN go mod tidy RUN go build -o ./main EXPOSE 3000 -CMD ["sh","-c","/app/src/load-balancer-service/main -image ${IMAGE} -replicas ${REPLICAS} -network ${NETWORK_NAME}"] \ No newline at end of file +CMD ["sh","-c","/app/src/load-balancer-service/main -config ${LOAD_BALANCER_CONFIG_PATH}"] \ No newline at end of file diff --git a/src/load-balancer-service/balancer/endpoint/health/health_check.go b/src/load-balancer-service/balancer/endpoint/health/health_check.go index 5d309393..74d5cbb2 100644 --- a/src/load-balancer-service/balancer/endpoint/health/health_check.go +++ b/src/load-balancer-service/balancer/endpoint/health/health_check.go @@ -83,7 +83,7 @@ func (hc *HealthCheck) stopHealthCheck() { var DefaultHealthCheck = func(addr *url.URL) bool { conn, err := net.DialTimeout("tcp", addr.Host, 2*time.Second) if err != nil { - log.Printf("Failed healtcheck: " + addr.Host) + log.Printf("Health check is missing heartbeat: " + addr.Host) return false } _ = conn.Close() diff --git a/src/load-balancer-service/config/config.web-service.dev.yaml b/src/load-balancer-service/config/config.web-service.dev.yaml new file mode 100644 index 00000000..e40e80fe --- /dev/null +++ b/src/load-balancer-service/config/config.web-service.dev.yaml @@ -0,0 +1,3 @@ +image: onyxmoon/pw-web-service:latest +network: dev-network +replicas: 5 diff --git a/src/load-balancer-service/config/config.web-service.yaml b/src/load-balancer-service/config/config.web-service.yaml new file mode 100644 index 00000000..3ad4a9d7 --- /dev/null +++ b/src/load-balancer-service/config/config.web-service.yaml @@ -0,0 +1,3 @@ +image: onyxmoon/pw-web-service:latest +network: internal +replicas: 5 diff --git a/src/load-balancer-service/config/config.yaml b/src/load-balancer-service/config/config.yaml new file mode 100644 index 00000000..255ce04a --- /dev/null +++ b/src/load-balancer-service/config/config.yaml @@ -0,0 +1,3 @@ +image: nginxdemos/hello +network: bridge +replicas: 5 diff --git a/src/load-balancer-service/go.mod b/src/load-balancer-service/go.mod index 49a58bcd..653e11de 100644 --- a/src/load-balancer-service/go.mod +++ b/src/load-balancer-service/go.mod @@ -2,25 +2,44 @@ module hsfl.de/group6/hsfl-master-ai-cloud-engineering/load-balancer-service go 1.21 -require github.com/docker/docker v24.0.7+incompatible +require ( + github.com/docker/docker v24.0.7+incompatible + github.com/docker/go-connections v0.4.0 + github.com/spf13/viper v1.18.2 +) require ( github.com/Microsoft/go-winio v0.6.1 // indirect github.com/distribution/reference v0.5.0 // indirect github.com/docker/distribution v2.8.3+incompatible // indirect - github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/term v0.5.0 // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/stretchr/testify v1.8.4 // indirect - golang.org/x/mod v0.8.0 // indirect - golang.org/x/net v0.6.0 // indirect - golang.org/x/sys v0.5.0 // indirect - golang.org/x/time v0.4.0 // indirect - golang.org/x/tools v0.6.0 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cast v1.6.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/subosito/gotenv v1.6.0 // indirect + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/multierr v1.9.0 // indirect + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect + golang.org/x/mod v0.12.0 // indirect + golang.org/x/net v0.19.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/tools v0.13.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect ) diff --git a/src/load-balancer-service/go.sum b/src/load-balancer-service/go.sum index bdd5e1a9..b652468a 100644 --- a/src/load-balancer-service/go.sum +++ b/src/load-balancer-service/go.sum @@ -2,8 +2,10 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOEl github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= @@ -14,12 +16,26 @@ github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKoh github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= @@ -28,51 +44,92 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= +github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= 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/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= +github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= 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-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/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/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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/time v0.4.0 h1:Z81tqI5ddIoXDPvVQ7/7CC9TnLM7ubaFG2qXYd5BbYY= -golang.org/x/time v0.4.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= 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/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= diff --git a/src/load-balancer-service/main.go b/src/load-balancer-service/main.go index 4fe4935b..6b28f115 100644 --- a/src/load-balancer-service/main.go +++ b/src/load-balancer-service/main.go @@ -14,24 +14,23 @@ import ( ) func main() { - // Parse command line arguments - image := flag.String("image", "nginxdemos/hello", "") - replicas := flag.Int("replicas", 5, "") - networkName := flag.String("network", "bridge", "") + // Configuration + configPath := flag.String("config", "", "Path to config file") flag.Parse() + configuration := utils.GetConfig(*configPath) // Log configuration - log.Printf("Image is: %s", *image) - log.Printf("No. of Replicas is: %d", *replicas) - log.Printf("Network is: %s", *networkName) + log.Printf("Image is: %s", configuration.Image) + log.Printf("No. of Replicas is: %d", configuration.Replicas) + log.Printf("Network is: %s", configuration.Network) // Initialize orchestrator and start containers var defaultOrchestrator orchestrator.Orchestrator = orchestrator.NewDefaultOrchestrator() - containers := defaultOrchestrator.StartContainers(*image, *replicas, *networkName) + containers := defaultOrchestrator.StartContainers(configuration.Image, configuration.Replicas, configuration.Network) // Initialize load balancer loadBalancer := balancer.NewBalancer( - defaultOrchestrator.GetContainerEndpoints(containers, *networkName), + defaultOrchestrator.GetContainerEndpoints(containers, configuration.Network), scheduler.NewRoundRobin) loadBalancer.SetHealthCheckFunction(health.DefaultHealthCheck, 5*time.Second) diff --git a/src/load-balancer-service/utils/configurator.go b/src/load-balancer-service/utils/configurator.go new file mode 100644 index 00000000..2c8f4446 --- /dev/null +++ b/src/load-balancer-service/utils/configurator.go @@ -0,0 +1,46 @@ +package utils + +import ( + "errors" + "fmt" + "github.com/spf13/viper" + "os" +) + +type Configuration struct { + Image string `yaml:"image"` // Image which should be run. + Replicas int `yaml:"replicas"` // Replicas number to run and load balance. + Network string `yaml:"network"` // Network where replicas belong to. +} + +const ( + DefaultConfigPath string = "./config/config.yaml" +) + +func GetConfig(path string) *Configuration { + viper.SetDefault("image", "nginxdemos/hello") + viper.SetDefault("replicas", 5) + viper.SetDefault("network", "bridge") + + if len(path) != 0 { + viper.SetConfigFile(path) + } else { + if _, err := os.Stat(DefaultConfigPath); errors.Is(err, os.ErrNotExist) { + viper.SetConfigType("yaml") + viper.WriteConfigAs(DefaultConfigPath) + } + viper.SetConfigFile(DefaultConfigPath) + } + + err := viper.ReadInConfig() + if err != nil { + panic(fmt.Errorf("fatal error config file: %w", err)) + } + + configuration := &Configuration{} + if err := viper.Unmarshal(configuration); err != nil { + fmt.Printf("unable to decode configuration, %v", err) + } + + return configuration +} diff --git a/src/load-balancer-service/utils/graceful_shutdown.go b/src/load-balancer-service/utils/graceful_shutdown.go index a0443346..c828d876 100644 --- a/src/load-balancer-service/utils/graceful_shutdown.go +++ b/src/load-balancer-service/utils/graceful_shutdown.go @@ -17,13 +17,11 @@ func GracefulShutdown(ctx context.Context, timeout time.Duration, ops map[string go func() { s := make(chan os.Signal, 1) - // add any other syscalls that you want to be notified with signal.Notify(s, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP) <-s log.Println("shutting down") - // set timeout for the ops to be done to prevent system hang timeoutFunc := time.AfterFunc(timeout, func() { log.Printf("timeout %d ms has been elapsed, force exit", timeout.Milliseconds()) os.Exit(0) @@ -33,7 +31,6 @@ func GracefulShutdown(ctx context.Context, timeout time.Duration, ops map[string var wg sync.WaitGroup - // Do the operations asynchronously to save time for key, op := range ops { wg.Add(1) innerOp := op diff --git a/src/product-service/Dockerfile b/src/product-service/Dockerfile index 3180b229..92ea196b 100644 --- a/src/product-service/Dockerfile +++ b/src/product-service/Dockerfile @@ -1,4 +1,7 @@ FROM golang:1.21-alpine +RUN apk update && apk add --no-cache make protobuf-dev +RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@latest +RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest WORKDIR /app COPY ./lib ./lib @@ -6,6 +9,7 @@ COPY ./src/product-service ./src/product-service WORKDIR /app/src/product-service RUN go mod tidy +RUN go generate RUN go build -o ./main EXPOSE 3003 diff --git a/src/product-service/api/http/router/router.go b/src/product-service/api/http/router/router.go new file mode 100644 index 00000000..24034576 --- /dev/null +++ b/src/product-service/api/http/router/router.go @@ -0,0 +1,36 @@ +package router + +import ( + router "hsfl.de/group6/hsfl-master-ai-cloud-engineering/lib" + "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/prices" + "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/products" + "net/http" +) + +type Router struct { + router http.Handler +} + +func New(productController *products.Controller, pricesController *prices.Controller) *Router { + r := router.New() + + r.GET("/api/v1/product/", (*productController).GetProducts) + r.GET("/api/v1/product/ean/:productEan", (*productController).GetProductByEan) + r.GET("/api/v1/product/:productId", (*productController).GetProductById) + r.PUT("/api/v1/product/:productId", (*productController).PutProduct) + r.POST("/api/v1/product/", (*productController).PostProduct) + r.DELETE("/api/v1/product/:productId", (*productController).DeleteProduct) + + r.GET("/api/v1/price/", (*pricesController).GetPrices) + r.GET("/api/v1/price/user/:userId", (*pricesController).GetPricesByUser) + r.GET("/api/v1/price/:productId/:userId", (*pricesController).GetPrice) + r.PUT("/api/v1/price/:productId/:userId", (*pricesController).PutPrice) + r.POST("/api/v1/price/:productId/:userId", (*pricesController).PostPrice) + r.DELETE("/api/v1/price/:productId/:userId", (*pricesController).DeletePrice) + + return &Router{r} +} + +func (router *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) { + router.router.ServeHTTP(w, r) +} diff --git a/src/product-service/api/router/router_test.go b/src/product-service/api/http/router/router_test.go similarity index 95% rename from src/product-service/api/router/router_test.go rename to src/product-service/api/http/router/router_test.go index 26c62a23..2ada1cba 100644 --- a/src/product-service/api/router/router_test.go +++ b/src/product-service/api/http/router/router_test.go @@ -14,11 +14,11 @@ import ( ) func TestRouter(t *testing.T) { - pricesRepo := setupMockPriceRepository() - productsRepo := setupMockProductRepository() - pricesController := prices.NewDefaultController(pricesRepo) - productsController := products.NewDefaultController(productsRepo) - router := New(productsController, pricesController) + var pricesRepo = setupMockPriceRepository() + var productsRepo = setupMockProductRepository() + var productsController products.Controller = products.NewDefaultController(productsRepo) + var pricesController prices.Controller = prices.NewDefaultController(pricesRepo) + router := New(&productsController, &pricesController) t.Run("should return 404 NOT FOUND if path is unknown", func(t *testing.T) { // given diff --git a/src/product-service/api/router/router.go b/src/product-service/api/router/router.go deleted file mode 100644 index e410ae18..00000000 --- a/src/product-service/api/router/router.go +++ /dev/null @@ -1,36 +0,0 @@ -package router - -import ( - router "hsfl.de/group6/hsfl-master-ai-cloud-engineering/lib" - "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/prices" - "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/products" - "net/http" -) - -type Router struct { - router http.Handler -} - -func New(productController products.Controller, pricesController prices.Controller) *Router { - r := router.New() - - r.GET("/api/v1/product/", productController.GetProducts) - r.GET("/api/v1/product/ean/:productEan", productController.GetProductByEan) - r.GET("/api/v1/product/:productId", productController.GetProductById) - r.PUT("/api/v1/product/:productId", productController.PutProduct) - r.POST("/api/v1/product/", productController.PostProduct) - r.DELETE("/api/v1/product/:productId", productController.DeleteProduct) - - r.GET("/api/v1/price/", pricesController.GetPrices) - r.GET("/api/v1/price/user/:userId", pricesController.GetPricesByUser) - r.GET("/api/v1/price/:productId/:userId", pricesController.GetPrice) - r.PUT("/api/v1/price/:productId/:userId", pricesController.PutPrice) - r.POST("/api/v1/price/:productId/:userId", pricesController.PostPrice) - r.DELETE("/api/v1/price/:productId/:userId", pricesController.DeletePrice) - - return &Router{r} -} - -func (router *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) { - router.router.ServeHTTP(w, r) -} diff --git a/src/product-service/api/rpc/server.go b/src/product-service/api/rpc/server.go new file mode 100644 index 00000000..f1e61b03 --- /dev/null +++ b/src/product-service/api/rpc/server.go @@ -0,0 +1,249 @@ +package rpc + +import ( + "context" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + proto "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/internal/proto/product" + "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/prices" + priceModel "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/prices/model" + "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/products" + productsModel "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/products/model" +) + +type ProductServiceServer struct { + proto.UnimplementedProductServiceServer + proto.UnimplementedPriceServiceServer + productRepository *products.Repository + priceRepository *prices.Repository +} + +func NewProductServiceServer(productRepository *products.Repository, priceRepository *prices.Repository) *ProductServiceServer { + return &ProductServiceServer{ + productRepository: productRepository, + priceRepository: priceRepository, + } +} + +func (p *ProductServiceServer) CreateProduct(ctx context.Context, request *proto.CreateProductRequest) (*proto.CreateProductResponse, error) { + requestProduct := request.GetProduct() + + var createdProduct, err = (*p.productRepository).Create(&productsModel.Product{ + Id: requestProduct.GetId(), + Description: requestProduct.GetDescription(), + Ean: requestProduct.GetEan(), + }) + + if err == nil { + response := &proto.CreateProductResponse{ + Product: &proto.Product{ + Id: createdProduct.Id, + Description: createdProduct.Description, + Ean: createdProduct.Ean, + }, + } + return response, nil + } else { + return nil, status.Error(codes.Internal, err.Error()) + } +} + +func (p *ProductServiceServer) GetProduct(ctx context.Context, request *proto.GetProductRequest) (*proto.GetProductResponse, error) { + var foundProduct, err = (*p.productRepository).FindById(request.GetId()) + + if err == nil { + response := &proto.GetProductResponse{ + Product: &proto.Product{ + Id: foundProduct.Id, + Description: foundProduct.Description, + Ean: foundProduct.Ean, + }, + } + return response, nil + } else { + return nil, status.Error(codes.NotFound, err.Error()) + } +} + +func (p *ProductServiceServer) GetAllProducts(ctx context.Context, request *proto.GetAllProductsRequest) (*proto.GetAllProductsResponse, error) { + var foundProducts, err = (*p.productRepository).FindAll() + + productList := make([]*proto.Product, len(foundProducts)) + + for i, product := range foundProducts { + productList[i] = &proto.Product{ + Id: product.Id, + Description: product.Description, + Ean: product.Ean, + } + } + + if err == nil { + response := &proto.GetAllProductsResponse{ + Products: productList, + } + return response, nil + } else { + return nil, status.Error(codes.Internal, err.Error()) + } +} + +func (p *ProductServiceServer) UpdateProduct(ctx context.Context, request *proto.UpdateProductRequest) (*proto.UpdateProductResponse, error) { + requestProduct := request.GetProduct() + + var updateProduct, err = (*p.productRepository).Update(&productsModel.Product{ + Id: requestProduct.GetId(), + Description: requestProduct.GetDescription(), + Ean: requestProduct.GetEan(), + }) + + if err == nil { + response := &proto.UpdateProductResponse{ + Product: &proto.Product{ + Id: updateProduct.Id, + Description: updateProduct.Description, + Ean: updateProduct.Ean, + }, + } + return response, nil + } else { + return nil, status.Error(codes.Internal, err.Error()) + } +} + +func (p *ProductServiceServer) DeleteProduct(ctx context.Context, request *proto.DeleteProductRequest) (*proto.DeleteProductResponse, error) { + requestProductId := request.Id + + var err = (*p.productRepository).Delete(&productsModel.Product{ + Id: requestProductId, + }) + + if err == nil { + return &proto.DeleteProductResponse{}, nil + } else { + return nil, status.Error(codes.Internal, err.Error()) + } +} + +func (p *ProductServiceServer) CreatePrice(ctx context.Context, request *proto.CreatePriceRequest) (*proto.CreatePriceResponse, error) { + requestPrice := request.GetPrice() + + var createdPrice, err = (*p.priceRepository).Create(&priceModel.Price{ + UserId: requestPrice.UserId, + ProductId: requestPrice.ProductId, + Price: requestPrice.Price, + }) + + if err == nil { + response := &proto.CreatePriceResponse{ + Price: &proto.Price{ + UserId: createdPrice.UserId, + ProductId: createdPrice.ProductId, + Price: createdPrice.Price, + }, + } + return response, nil + } else { + return nil, status.Error(codes.Internal, err.Error()) + } +} + +func (p *ProductServiceServer) FindPrice(ctx context.Context, request *proto.FindPriceRequest) (*proto.FindPriceResponse, error) { + var foundPrice, err = (*p.priceRepository).FindByIds(request.ProductId, request.UserId) + + if err == nil { + response := &proto.FindPriceResponse{Price: &proto.Price{ + UserId: foundPrice.UserId, + ProductId: foundPrice.ProductId, + Price: foundPrice.Price, + }} + return response, nil + } else { + return nil, status.Error(codes.NotFound, err.Error()) + } +} + +func (p *ProductServiceServer) FindAllPrices(ctx context.Context, request *proto.FindAllPricesRequest) (*proto.FindAllPricesResponse, error) { + var foundPrices, err = (*p.priceRepository).FindAll() + + priceList := make([]*proto.Price, len(foundPrices)) + + for i, price := range foundPrices { + priceList[i] = &proto.Price{ + UserId: price.UserId, + ProductId: price.ProductId, + Price: price.Price, + } + } + + if err == nil { + response := &proto.FindAllPricesResponse{ + Price: priceList, + } + return response, nil + } else { + return nil, status.Error(codes.Internal, err.Error()) + } +} + +func (p *ProductServiceServer) FindAllPricesFromUser(ctx context.Context, request *proto.FindAllPricesFromUserRequest) (*proto.FindAllPricesFromUserResponse, error) { + var foundPrices, err = (*p.priceRepository).FindAllByUser(request.UserId) + + priceList := make([]*proto.Price, len(foundPrices)) + + for i, price := range foundPrices { + priceList[i] = &proto.Price{ + UserId: price.UserId, + ProductId: price.ProductId, + Price: price.Price, + } + } + + if err == nil { + response := &proto.FindAllPricesFromUserResponse{ + Price: priceList, + } + return response, nil + } else { + return nil, status.Error(codes.Internal, err.Error()) + } +} + +func (p *ProductServiceServer) UpdatePrice(ctx context.Context, request *proto.UpdatePriceRequest) (*proto.UpdatePriceResponse, error) { + requestPrice := request.GetPrice() + + var updatePrice, err = (*p.priceRepository).Update(&priceModel.Price{ + UserId: requestPrice.UserId, + ProductId: requestPrice.ProductId, + Price: requestPrice.Price, + }) + + if err == nil { + response := &proto.UpdatePriceResponse{ + Price: &proto.Price{ + UserId: updatePrice.UserId, + ProductId: updatePrice.ProductId, + Price: updatePrice.Price, + }, + } + return response, nil + } else { + return nil, status.Error(codes.Internal, err.Error()) + } +} + +func (p *ProductServiceServer) DeletePrice(ctx context.Context, request *proto.DeletePriceRequest) (*proto.DeletePriceResponse, error) { + requestUserId := request.UserId + requestProductId := request.ProductId + + var err = (*p.priceRepository).Delete(&priceModel.Price{ + UserId: requestUserId, + ProductId: requestProductId, + }) + + if err == nil { + return &proto.DeletePriceResponse{}, nil + } else { + return nil, status.Error(codes.Internal, err.Error()) + } +} diff --git a/src/product-service/api/rpc/server_test.go b/src/product-service/api/rpc/server_test.go new file mode 100644 index 00000000..f10fd80c --- /dev/null +++ b/src/product-service/api/rpc/server_test.go @@ -0,0 +1,98 @@ +package rpc + +import ( + "context" + "github.com/stretchr/testify/assert" + proto "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/internal/proto/product" + "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/prices" + "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/products" + "testing" +) + +func TestNewProductServiceServer(t *testing.T) { + var productRepo products.Repository = products.NewDemoRepository() + var priceRepo prices.Repository = prices.NewDemoRepository() + + server := NewProductServiceServer(&productRepo, &priceRepo) + + assert.NotNil(t, server) + assert.NotNil(t, server.productRepository) + assert.NotNil(t, server.priceRepository, priceRepo) +} + +func TestProductServiceServer_CreateProduct(t *testing.T) { + productRepo := products.GenerateExampleDemoRepository() + priceRepo := prices.GenerateExampleDemoRepository() + server := NewProductServiceServer(&productRepo, &priceRepo) + + ctx := context.Background() + req := &proto.CreateProductRequest{ + Product: &proto.Product{ + Id: 123, + Description: "Test", + Ean: 123456789, + }, + } + + resp, err := server.CreateProduct(ctx, req) + if err != nil { + t.Errorf("Error creating product: %v", err) + } + + if resp.Product.Id != 123 { + t.Errorf("Expected product ID '123', got '%d'", resp.Product.Id) + } +} + +func TestProductServiceServer_GetProduct(t *testing.T) { + productRepo := products.GenerateExampleDemoRepository() + priceRepo := prices.GenerateExampleDemoRepository() + server := NewProductServiceServer(&productRepo, &priceRepo) + + ctx := context.Background() + getReq := &proto.GetProductRequest{Id: 2} + resp, err := server.GetProduct(ctx, getReq) + if err != nil { + t.Errorf("Error getting product: %v", err) + } + + if resp.Product.Id != 2 { + t.Errorf("Expected product ID '123', got '%d'", resp.Product.Id) + } +} + +func TestProductServiceServer_CreatePrice(t *testing.T) { + +} + +func TestProductServiceServer_DeletePrice(t *testing.T) { + +} + +func TestProductServiceServer_DeleteProduct(t *testing.T) { + +} + +func TestProductServiceServer_FindAllPrices(t *testing.T) { + +} + +func TestProductServiceServer_FindAllPricesFromUser(t *testing.T) { + +} + +func TestProductServiceServer_FindPrice(t *testing.T) { + +} + +func TestProductServiceServer_GetAllProducts(t *testing.T) { + +} + +func TestProductServiceServer_UpdatePrice(t *testing.T) { + +} + +func TestProductServiceServer_UpdateProduct(t *testing.T) { + +} diff --git a/src/product-service/go.mod b/src/product-service/go.mod index 84b85be2..b5c99805 100644 --- a/src/product-service/go.mod +++ b/src/product-service/go.mod @@ -2,6 +2,23 @@ module hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service go 1.21 -replace ( -"hsfl.de/group6/hsfl-master-ai-cloud-engineering/lib" => ./../../lib/router -) \ No newline at end of file +replace hsfl.de/group6/hsfl-master-ai-cloud-engineering/lib => ./../../lib/router + +require ( + github.com/stretchr/testify v1.8.4 + golang.org/x/sync v0.4.0 + google.golang.org/grpc v1.60.0 + google.golang.org/protobuf v1.31.0 + hsfl.de/group6/hsfl-master-ai-cloud-engineering/lib v0.0.0-00010101000000-000000000000 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + golang.org/x/net v0.19.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/src/product-service/go.sum b/src/product-service/go.sum new file mode 100644 index 00000000..4dd7be67 --- /dev/null +++ b/src/product-service/go.sum @@ -0,0 +1,33 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +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/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +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/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 h1:/jFB8jK5R3Sq3i/lmeZO0cATSzFfZaJq1J2Euan3XKU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0/go.mod h1:FUoWkonphQm3RhTS+kOEhF8h0iDpm4tdXolVCeZ9KKA= +google.golang.org/grpc v1.60.0 h1:6FQAR0kM31P6MRdeluor2w2gPaS4SVNrD/DNTxrQ15k= +google.golang.org/grpc v1.60.0/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= +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.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.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.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/src/product-service/internal/proto/product/product.pb.go b/src/product-service/internal/proto/product/product.pb.go new file mode 100644 index 00000000..b8a2d326 --- /dev/null +++ b/src/product-service/internal/proto/product/product.pb.go @@ -0,0 +1,1722 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v4.25.1 +// source: product/product.proto + +package proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Product struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Ean uint64 `protobuf:"varint,3,opt,name=ean,proto3" json:"ean,omitempty"` +} + +func (x *Product) Reset() { + *x = Product{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Product) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Product) ProtoMessage() {} + +func (x *Product) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Product.ProtoReflect.Descriptor instead. +func (*Product) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{0} +} + +func (x *Product) GetId() uint64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *Product) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Product) GetEan() uint64 { + if x != nil { + return x.Ean + } + return 0 +} + +type Price struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserId uint64 `protobuf:"varint,1,opt,name=userId,proto3" json:"userId,omitempty"` + ProductId uint64 `protobuf:"varint,2,opt,name=productId,proto3" json:"productId,omitempty"` + Price float32 `protobuf:"fixed32,3,opt,name=price,proto3" json:"price,omitempty"` +} + +func (x *Price) Reset() { + *x = Price{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Price) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Price) ProtoMessage() {} + +func (x *Price) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Price.ProtoReflect.Descriptor instead. +func (*Price) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{1} +} + +func (x *Price) GetUserId() uint64 { + if x != nil { + return x.UserId + } + return 0 +} + +func (x *Price) GetProductId() uint64 { + if x != nil { + return x.ProductId + } + return 0 +} + +func (x *Price) GetPrice() float32 { + if x != nil { + return x.Price + } + return 0 +} + +// Request- and Response-Messages for CreateProduct +type CreateProductRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Product *Product `protobuf:"bytes,1,opt,name=product,proto3" json:"product,omitempty"` +} + +func (x *CreateProductRequest) Reset() { + *x = CreateProductRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateProductRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateProductRequest) ProtoMessage() {} + +func (x *CreateProductRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateProductRequest.ProtoReflect.Descriptor instead. +func (*CreateProductRequest) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{2} +} + +func (x *CreateProductRequest) GetProduct() *Product { + if x != nil { + return x.Product + } + return nil +} + +type CreateProductResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Product *Product `protobuf:"bytes,1,opt,name=product,proto3" json:"product,omitempty"` +} + +func (x *CreateProductResponse) Reset() { + *x = CreateProductResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateProductResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateProductResponse) ProtoMessage() {} + +func (x *CreateProductResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateProductResponse.ProtoReflect.Descriptor instead. +func (*CreateProductResponse) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{3} +} + +func (x *CreateProductResponse) GetProduct() *Product { + if x != nil { + return x.Product + } + return nil +} + +// Request- and Response-Messages for GetProduct +type GetProductRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *GetProductRequest) Reset() { + *x = GetProductRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetProductRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetProductRequest) ProtoMessage() {} + +func (x *GetProductRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetProductRequest.ProtoReflect.Descriptor instead. +func (*GetProductRequest) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{4} +} + +func (x *GetProductRequest) GetId() uint64 { + if x != nil { + return x.Id + } + return 0 +} + +type GetProductResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Product *Product `protobuf:"bytes,1,opt,name=product,proto3" json:"product,omitempty"` +} + +func (x *GetProductResponse) Reset() { + *x = GetProductResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetProductResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetProductResponse) ProtoMessage() {} + +func (x *GetProductResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetProductResponse.ProtoReflect.Descriptor instead. +func (*GetProductResponse) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{5} +} + +func (x *GetProductResponse) GetProduct() *Product { + if x != nil { + return x.Product + } + return nil +} + +// Request- and Response-Messages for ListProducts +type GetAllProductsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetAllProductsRequest) Reset() { + *x = GetAllProductsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllProductsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllProductsRequest) ProtoMessage() {} + +func (x *GetAllProductsRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllProductsRequest.ProtoReflect.Descriptor instead. +func (*GetAllProductsRequest) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{6} +} + +type GetAllProductsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Products []*Product `protobuf:"bytes,1,rep,name=products,proto3" json:"products,omitempty"` +} + +func (x *GetAllProductsResponse) Reset() { + *x = GetAllProductsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllProductsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllProductsResponse) ProtoMessage() {} + +func (x *GetAllProductsResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllProductsResponse.ProtoReflect.Descriptor instead. +func (*GetAllProductsResponse) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{7} +} + +func (x *GetAllProductsResponse) GetProducts() []*Product { + if x != nil { + return x.Products + } + return nil +} + +// Request- and Response-Messages for UpdateProduct +type UpdateProductRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Product *Product `protobuf:"bytes,1,opt,name=product,proto3" json:"product,omitempty"` +} + +func (x *UpdateProductRequest) Reset() { + *x = UpdateProductRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateProductRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateProductRequest) ProtoMessage() {} + +func (x *UpdateProductRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateProductRequest.ProtoReflect.Descriptor instead. +func (*UpdateProductRequest) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{8} +} + +func (x *UpdateProductRequest) GetProduct() *Product { + if x != nil { + return x.Product + } + return nil +} + +type UpdateProductResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Product *Product `protobuf:"bytes,1,opt,name=product,proto3" json:"product,omitempty"` +} + +func (x *UpdateProductResponse) Reset() { + *x = UpdateProductResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateProductResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateProductResponse) ProtoMessage() {} + +func (x *UpdateProductResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateProductResponse.ProtoReflect.Descriptor instead. +func (*UpdateProductResponse) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{9} +} + +func (x *UpdateProductResponse) GetProduct() *Product { + if x != nil { + return x.Product + } + return nil +} + +// Request- and Response-Messages for DeleteProduct +type DeleteProductRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *DeleteProductRequest) Reset() { + *x = DeleteProductRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteProductRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteProductRequest) ProtoMessage() {} + +func (x *DeleteProductRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteProductRequest.ProtoReflect.Descriptor instead. +func (*DeleteProductRequest) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{10} +} + +func (x *DeleteProductRequest) GetId() uint64 { + if x != nil { + return x.Id + } + return 0 +} + +type DeleteProductResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeleteProductResponse) Reset() { + *x = DeleteProductResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteProductResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteProductResponse) ProtoMessage() {} + +func (x *DeleteProductResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteProductResponse.ProtoReflect.Descriptor instead. +func (*DeleteProductResponse) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{11} +} + +// Request- and Response-Messages for CreatePrice +type CreatePriceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Price *Price `protobuf:"bytes,1,opt,name=price,proto3" json:"price,omitempty"` +} + +func (x *CreatePriceRequest) Reset() { + *x = CreatePriceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreatePriceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreatePriceRequest) ProtoMessage() {} + +func (x *CreatePriceRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreatePriceRequest.ProtoReflect.Descriptor instead. +func (*CreatePriceRequest) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{12} +} + +func (x *CreatePriceRequest) GetPrice() *Price { + if x != nil { + return x.Price + } + return nil +} + +type CreatePriceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Price *Price `protobuf:"bytes,1,opt,name=price,proto3" json:"price,omitempty"` +} + +func (x *CreatePriceResponse) Reset() { + *x = CreatePriceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreatePriceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreatePriceResponse) ProtoMessage() {} + +func (x *CreatePriceResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreatePriceResponse.ProtoReflect.Descriptor instead. +func (*CreatePriceResponse) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{13} +} + +func (x *CreatePriceResponse) GetPrice() *Price { + if x != nil { + return x.Price + } + return nil +} + +// Request- and Response-Messages for FindPrice +type FindPriceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserId uint64 `protobuf:"varint,1,opt,name=userId,proto3" json:"userId,omitempty"` + ProductId uint64 `protobuf:"varint,2,opt,name=productId,proto3" json:"productId,omitempty"` +} + +func (x *FindPriceRequest) Reset() { + *x = FindPriceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FindPriceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindPriceRequest) ProtoMessage() {} + +func (x *FindPriceRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FindPriceRequest.ProtoReflect.Descriptor instead. +func (*FindPriceRequest) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{14} +} + +func (x *FindPriceRequest) GetUserId() uint64 { + if x != nil { + return x.UserId + } + return 0 +} + +func (x *FindPriceRequest) GetProductId() uint64 { + if x != nil { + return x.ProductId + } + return 0 +} + +type FindPriceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Price *Price `protobuf:"bytes,1,opt,name=price,proto3" json:"price,omitempty"` +} + +func (x *FindPriceResponse) Reset() { + *x = FindPriceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FindPriceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindPriceResponse) ProtoMessage() {} + +func (x *FindPriceResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FindPriceResponse.ProtoReflect.Descriptor instead. +func (*FindPriceResponse) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{15} +} + +func (x *FindPriceResponse) GetPrice() *Price { + if x != nil { + return x.Price + } + return nil +} + +// Request- and Response-Messages for FindAllPrices +type FindAllPricesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *FindAllPricesRequest) Reset() { + *x = FindAllPricesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FindAllPricesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindAllPricesRequest) ProtoMessage() {} + +func (x *FindAllPricesRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FindAllPricesRequest.ProtoReflect.Descriptor instead. +func (*FindAllPricesRequest) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{16} +} + +type FindAllPricesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Price []*Price `protobuf:"bytes,1,rep,name=price,proto3" json:"price,omitempty"` +} + +func (x *FindAllPricesResponse) Reset() { + *x = FindAllPricesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FindAllPricesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindAllPricesResponse) ProtoMessage() {} + +func (x *FindAllPricesResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FindAllPricesResponse.ProtoReflect.Descriptor instead. +func (*FindAllPricesResponse) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{17} +} + +func (x *FindAllPricesResponse) GetPrice() []*Price { + if x != nil { + return x.Price + } + return nil +} + +// Request- and Response-Messages for FindAllPricesFromUser +type FindAllPricesFromUserRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserId uint64 `protobuf:"varint,1,opt,name=userId,proto3" json:"userId,omitempty"` +} + +func (x *FindAllPricesFromUserRequest) Reset() { + *x = FindAllPricesFromUserRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FindAllPricesFromUserRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindAllPricesFromUserRequest) ProtoMessage() {} + +func (x *FindAllPricesFromUserRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FindAllPricesFromUserRequest.ProtoReflect.Descriptor instead. +func (*FindAllPricesFromUserRequest) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{18} +} + +func (x *FindAllPricesFromUserRequest) GetUserId() uint64 { + if x != nil { + return x.UserId + } + return 0 +} + +type FindAllPricesFromUserResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Price []*Price `protobuf:"bytes,1,rep,name=price,proto3" json:"price,omitempty"` +} + +func (x *FindAllPricesFromUserResponse) Reset() { + *x = FindAllPricesFromUserResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FindAllPricesFromUserResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindAllPricesFromUserResponse) ProtoMessage() {} + +func (x *FindAllPricesFromUserResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FindAllPricesFromUserResponse.ProtoReflect.Descriptor instead. +func (*FindAllPricesFromUserResponse) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{19} +} + +func (x *FindAllPricesFromUserResponse) GetPrice() []*Price { + if x != nil { + return x.Price + } + return nil +} + +// Request- and Response-Messages for UpdateProduct +type UpdatePriceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Price *Price `protobuf:"bytes,1,opt,name=price,proto3" json:"price,omitempty"` +} + +func (x *UpdatePriceRequest) Reset() { + *x = UpdatePriceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdatePriceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdatePriceRequest) ProtoMessage() {} + +func (x *UpdatePriceRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdatePriceRequest.ProtoReflect.Descriptor instead. +func (*UpdatePriceRequest) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{20} +} + +func (x *UpdatePriceRequest) GetPrice() *Price { + if x != nil { + return x.Price + } + return nil +} + +type UpdatePriceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Price *Price `protobuf:"bytes,1,opt,name=price,proto3" json:"price,omitempty"` +} + +func (x *UpdatePriceResponse) Reset() { + *x = UpdatePriceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdatePriceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdatePriceResponse) ProtoMessage() {} + +func (x *UpdatePriceResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdatePriceResponse.ProtoReflect.Descriptor instead. +func (*UpdatePriceResponse) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{21} +} + +func (x *UpdatePriceResponse) GetPrice() *Price { + if x != nil { + return x.Price + } + return nil +} + +// Request- and Response-Messages for DeleteProduct +type DeletePriceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserId uint64 `protobuf:"varint,1,opt,name=userId,proto3" json:"userId,omitempty"` + ProductId uint64 `protobuf:"varint,2,opt,name=productId,proto3" json:"productId,omitempty"` +} + +func (x *DeletePriceRequest) Reset() { + *x = DeletePriceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeletePriceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeletePriceRequest) ProtoMessage() {} + +func (x *DeletePriceRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeletePriceRequest.ProtoReflect.Descriptor instead. +func (*DeletePriceRequest) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{22} +} + +func (x *DeletePriceRequest) GetUserId() uint64 { + if x != nil { + return x.UserId + } + return 0 +} + +func (x *DeletePriceRequest) GetProductId() uint64 { + if x != nil { + return x.ProductId + } + return 0 +} + +type DeletePriceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeletePriceResponse) Reset() { + *x = DeletePriceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_product_product_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeletePriceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeletePriceResponse) ProtoMessage() {} + +func (x *DeletePriceResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_product_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeletePriceResponse.ProtoReflect.Descriptor instead. +func (*DeletePriceResponse) Descriptor() ([]byte, []int) { + return file_product_product_proto_rawDescGZIP(), []int{23} +} + +var File_product_product_proto protoreflect.FileDescriptor + +var file_product_product_proto_rawDesc = []byte{ + 0x0a, 0x15, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, + 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, + 0x22, 0x4d, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, + 0x03, 0x65, 0x61, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x65, 0x61, 0x6e, 0x22, + 0x53, 0x0a, 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, + 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x12, 0x14, + 0x0a, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x70, + 0x72, 0x69, 0x63, 0x65, 0x22, 0x42, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x07, + 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, + 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, + 0x07, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x22, 0x43, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x2a, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x50, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x74, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x22, 0x23, 0x0a, + 0x11, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, + 0x69, 0x64, 0x22, 0x40, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x07, 0x70, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x74, 0x22, 0x17, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x50, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x46, 0x0a, + 0x16, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x64, 0x75, + 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x08, 0x70, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x74, 0x73, 0x22, 0x42, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, + 0x07, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, + 0x52, 0x07, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x22, 0x43, 0x0a, 0x15, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x50, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x22, 0x26, + 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x22, 0x17, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x3a, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x50, + 0x72, 0x69, 0x63, 0x65, 0x52, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x22, 0x3b, 0x0a, 0x13, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x24, 0x0a, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x50, 0x72, 0x69, 0x63, + 0x65, 0x52, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x22, 0x48, 0x0a, 0x10, 0x46, 0x69, 0x6e, 0x64, + 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, + 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x73, + 0x65, 0x72, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, + 0x49, 0x64, 0x22, 0x39, 0x0a, 0x11, 0x46, 0x69, 0x6e, 0x64, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, + 0x2e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x22, 0x16, 0x0a, + 0x14, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x50, 0x72, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3d, 0x0a, 0x15, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, + 0x50, 0x72, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, + 0x0a, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, + 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x05, 0x70, + 0x72, 0x69, 0x63, 0x65, 0x22, 0x36, 0x0a, 0x1c, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x50, + 0x72, 0x69, 0x63, 0x65, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x45, 0x0a, 0x1d, + 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x50, 0x72, 0x69, 0x63, 0x65, 0x73, 0x46, 0x72, 0x6f, + 0x6d, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, + 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x05, 0x70, 0x72, + 0x69, 0x63, 0x65, 0x22, 0x3a, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x69, + 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x05, 0x70, 0x72, 0x69, + 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, + 0x63, 0x74, 0x2e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x22, + 0x3b, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, + 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x22, 0x4a, 0x0a, 0x12, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x70, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x22, 0x15, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, + 0x9a, 0x03, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x4e, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x74, 0x12, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, + 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0e, 0x47, 0x65, 0x74, + 0x41, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x12, 0x1e, 0x2e, 0x70, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x0d, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x1d, 0x2e, + 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x0d, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x1d, 0x2e, + 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xe8, 0x03, 0x0a, + 0x0c, 0x50, 0x72, 0x69, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x48, 0x0a, + 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x1b, 0x2e, 0x70, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x69, + 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x09, 0x46, 0x69, 0x6e, 0x64, 0x50, + 0x72, 0x69, 0x63, 0x65, 0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x46, + 0x69, 0x6e, 0x64, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x50, 0x72, + 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x0d, 0x46, + 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x50, 0x72, 0x69, 0x63, 0x65, 0x73, 0x12, 0x1d, 0x2e, 0x70, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x50, 0x72, + 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x50, 0x72, 0x69, + 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, 0x0a, 0x15, 0x46, + 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x50, 0x72, 0x69, 0x63, 0x65, 0x73, 0x46, 0x72, 0x6f, 0x6d, + 0x55, 0x73, 0x65, 0x72, 0x12, 0x25, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x46, + 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x50, 0x72, 0x69, 0x63, 0x65, 0x73, 0x46, 0x72, 0x6f, 0x6d, + 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x70, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x50, 0x72, 0x69, + 0x63, 0x65, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x69, + 0x63, 0x65, 0x12, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, + 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x1b, 0x2e, 0x70, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x69, + 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x12, 0x5a, 0x10, 0x2e, 0x2f, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_product_product_proto_rawDescOnce sync.Once + file_product_product_proto_rawDescData = file_product_product_proto_rawDesc +) + +func file_product_product_proto_rawDescGZIP() []byte { + file_product_product_proto_rawDescOnce.Do(func() { + file_product_product_proto_rawDescData = protoimpl.X.CompressGZIP(file_product_product_proto_rawDescData) + }) + return file_product_product_proto_rawDescData +} + +var file_product_product_proto_msgTypes = make([]protoimpl.MessageInfo, 24) +var file_product_product_proto_goTypes = []interface{}{ + (*Product)(nil), // 0: product.Product + (*Price)(nil), // 1: product.Price + (*CreateProductRequest)(nil), // 2: product.CreateProductRequest + (*CreateProductResponse)(nil), // 3: product.CreateProductResponse + (*GetProductRequest)(nil), // 4: product.GetProductRequest + (*GetProductResponse)(nil), // 5: product.GetProductResponse + (*GetAllProductsRequest)(nil), // 6: product.GetAllProductsRequest + (*GetAllProductsResponse)(nil), // 7: product.GetAllProductsResponse + (*UpdateProductRequest)(nil), // 8: product.UpdateProductRequest + (*UpdateProductResponse)(nil), // 9: product.UpdateProductResponse + (*DeleteProductRequest)(nil), // 10: product.DeleteProductRequest + (*DeleteProductResponse)(nil), // 11: product.DeleteProductResponse + (*CreatePriceRequest)(nil), // 12: product.CreatePriceRequest + (*CreatePriceResponse)(nil), // 13: product.CreatePriceResponse + (*FindPriceRequest)(nil), // 14: product.FindPriceRequest + (*FindPriceResponse)(nil), // 15: product.FindPriceResponse + (*FindAllPricesRequest)(nil), // 16: product.FindAllPricesRequest + (*FindAllPricesResponse)(nil), // 17: product.FindAllPricesResponse + (*FindAllPricesFromUserRequest)(nil), // 18: product.FindAllPricesFromUserRequest + (*FindAllPricesFromUserResponse)(nil), // 19: product.FindAllPricesFromUserResponse + (*UpdatePriceRequest)(nil), // 20: product.UpdatePriceRequest + (*UpdatePriceResponse)(nil), // 21: product.UpdatePriceResponse + (*DeletePriceRequest)(nil), // 22: product.DeletePriceRequest + (*DeletePriceResponse)(nil), // 23: product.DeletePriceResponse +} +var file_product_product_proto_depIdxs = []int32{ + 0, // 0: product.CreateProductRequest.product:type_name -> product.Product + 0, // 1: product.CreateProductResponse.product:type_name -> product.Product + 0, // 2: product.GetProductResponse.product:type_name -> product.Product + 0, // 3: product.GetAllProductsResponse.products:type_name -> product.Product + 0, // 4: product.UpdateProductRequest.product:type_name -> product.Product + 0, // 5: product.UpdateProductResponse.product:type_name -> product.Product + 1, // 6: product.CreatePriceRequest.price:type_name -> product.Price + 1, // 7: product.CreatePriceResponse.price:type_name -> product.Price + 1, // 8: product.FindPriceResponse.price:type_name -> product.Price + 1, // 9: product.FindAllPricesResponse.price:type_name -> product.Price + 1, // 10: product.FindAllPricesFromUserResponse.price:type_name -> product.Price + 1, // 11: product.UpdatePriceRequest.price:type_name -> product.Price + 1, // 12: product.UpdatePriceResponse.price:type_name -> product.Price + 2, // 13: product.ProductService.CreateProduct:input_type -> product.CreateProductRequest + 4, // 14: product.ProductService.GetProduct:input_type -> product.GetProductRequest + 6, // 15: product.ProductService.GetAllProducts:input_type -> product.GetAllProductsRequest + 8, // 16: product.ProductService.UpdateProduct:input_type -> product.UpdateProductRequest + 10, // 17: product.ProductService.DeleteProduct:input_type -> product.DeleteProductRequest + 12, // 18: product.PriceService.CreatePrice:input_type -> product.CreatePriceRequest + 14, // 19: product.PriceService.FindPrice:input_type -> product.FindPriceRequest + 16, // 20: product.PriceService.FindAllPrices:input_type -> product.FindAllPricesRequest + 18, // 21: product.PriceService.FindAllPricesFromUser:input_type -> product.FindAllPricesFromUserRequest + 20, // 22: product.PriceService.UpdatePrice:input_type -> product.UpdatePriceRequest + 22, // 23: product.PriceService.DeletePrice:input_type -> product.DeletePriceRequest + 3, // 24: product.ProductService.CreateProduct:output_type -> product.CreateProductResponse + 5, // 25: product.ProductService.GetProduct:output_type -> product.GetProductResponse + 7, // 26: product.ProductService.GetAllProducts:output_type -> product.GetAllProductsResponse + 9, // 27: product.ProductService.UpdateProduct:output_type -> product.UpdateProductResponse + 11, // 28: product.ProductService.DeleteProduct:output_type -> product.DeleteProductResponse + 13, // 29: product.PriceService.CreatePrice:output_type -> product.CreatePriceResponse + 15, // 30: product.PriceService.FindPrice:output_type -> product.FindPriceResponse + 17, // 31: product.PriceService.FindAllPrices:output_type -> product.FindAllPricesResponse + 19, // 32: product.PriceService.FindAllPricesFromUser:output_type -> product.FindAllPricesFromUserResponse + 21, // 33: product.PriceService.UpdatePrice:output_type -> product.UpdatePriceResponse + 23, // 34: product.PriceService.DeletePrice:output_type -> product.DeletePriceResponse + 24, // [24:35] is the sub-list for method output_type + 13, // [13:24] is the sub-list for method input_type + 13, // [13:13] is the sub-list for extension type_name + 13, // [13:13] is the sub-list for extension extendee + 0, // [0:13] is the sub-list for field type_name +} + +func init() { file_product_product_proto_init() } +func file_product_product_proto_init() { + if File_product_product_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_product_product_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Product); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Price); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateProductRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateProductResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetProductRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetProductResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllProductsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllProductsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateProductRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateProductResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteProductRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteProductResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreatePriceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreatePriceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FindPriceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FindPriceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FindAllPricesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FindAllPricesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FindAllPricesFromUserRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FindAllPricesFromUserResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdatePriceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdatePriceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeletePriceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_product_product_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeletePriceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_product_product_proto_rawDesc, + NumEnums: 0, + NumMessages: 24, + NumExtensions: 0, + NumServices: 2, + }, + GoTypes: file_product_product_proto_goTypes, + DependencyIndexes: file_product_product_proto_depIdxs, + MessageInfos: file_product_product_proto_msgTypes, + }.Build() + File_product_product_proto = out.File + file_product_product_proto_rawDesc = nil + file_product_product_proto_goTypes = nil + file_product_product_proto_depIdxs = nil +} diff --git a/src/product-service/internal/proto/product/product_grpc.pb.go b/src/product-service/internal/proto/product/product_grpc.pb.go new file mode 100644 index 00000000..8511f4de --- /dev/null +++ b/src/product-service/internal/proto/product/product_grpc.pb.go @@ -0,0 +1,554 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v4.25.1 +// source: product/product.proto + +package proto + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + ProductService_CreateProduct_FullMethodName = "/product.ProductService/CreateProduct" + ProductService_GetProduct_FullMethodName = "/product.ProductService/GetProduct" + ProductService_GetAllProducts_FullMethodName = "/product.ProductService/GetAllProducts" + ProductService_UpdateProduct_FullMethodName = "/product.ProductService/UpdateProduct" + ProductService_DeleteProduct_FullMethodName = "/product.ProductService/DeleteProduct" +) + +// ProductServiceClient is the client API for ProductService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ProductServiceClient interface { + // create method for adding a new product + CreateProduct(ctx context.Context, in *CreateProductRequest, opts ...grpc.CallOption) (*CreateProductResponse, error) + // read method for getting a product by id + GetProduct(ctx context.Context, in *GetProductRequest, opts ...grpc.CallOption) (*GetProductResponse, error) + // read method for getting all products + GetAllProducts(ctx context.Context, in *GetAllProductsRequest, opts ...grpc.CallOption) (*GetAllProductsResponse, error) + // update method for updating a product + UpdateProduct(ctx context.Context, in *UpdateProductRequest, opts ...grpc.CallOption) (*UpdateProductResponse, error) + // delete method to get rid of a product + DeleteProduct(ctx context.Context, in *DeleteProductRequest, opts ...grpc.CallOption) (*DeleteProductResponse, error) +} + +type productServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewProductServiceClient(cc grpc.ClientConnInterface) ProductServiceClient { + return &productServiceClient{cc} +} + +func (c *productServiceClient) CreateProduct(ctx context.Context, in *CreateProductRequest, opts ...grpc.CallOption) (*CreateProductResponse, error) { + out := new(CreateProductResponse) + err := c.cc.Invoke(ctx, ProductService_CreateProduct_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productServiceClient) GetProduct(ctx context.Context, in *GetProductRequest, opts ...grpc.CallOption) (*GetProductResponse, error) { + out := new(GetProductResponse) + err := c.cc.Invoke(ctx, ProductService_GetProduct_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productServiceClient) GetAllProducts(ctx context.Context, in *GetAllProductsRequest, opts ...grpc.CallOption) (*GetAllProductsResponse, error) { + out := new(GetAllProductsResponse) + err := c.cc.Invoke(ctx, ProductService_GetAllProducts_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productServiceClient) UpdateProduct(ctx context.Context, in *UpdateProductRequest, opts ...grpc.CallOption) (*UpdateProductResponse, error) { + out := new(UpdateProductResponse) + err := c.cc.Invoke(ctx, ProductService_UpdateProduct_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productServiceClient) DeleteProduct(ctx context.Context, in *DeleteProductRequest, opts ...grpc.CallOption) (*DeleteProductResponse, error) { + out := new(DeleteProductResponse) + err := c.cc.Invoke(ctx, ProductService_DeleteProduct_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ProductServiceServer is the server API for ProductService service. +// All implementations must embed UnimplementedProductServiceServer +// for forward compatibility +type ProductServiceServer interface { + // create method for adding a new product + CreateProduct(context.Context, *CreateProductRequest) (*CreateProductResponse, error) + // read method for getting a product by id + GetProduct(context.Context, *GetProductRequest) (*GetProductResponse, error) + // read method for getting all products + GetAllProducts(context.Context, *GetAllProductsRequest) (*GetAllProductsResponse, error) + // update method for updating a product + UpdateProduct(context.Context, *UpdateProductRequest) (*UpdateProductResponse, error) + // delete method to get rid of a product + DeleteProduct(context.Context, *DeleteProductRequest) (*DeleteProductResponse, error) + mustEmbedUnimplementedProductServiceServer() +} + +// UnimplementedProductServiceServer must be embedded to have forward compatible implementations. +type UnimplementedProductServiceServer struct { +} + +func (UnimplementedProductServiceServer) CreateProduct(context.Context, *CreateProductRequest) (*CreateProductResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateProduct not implemented") +} +func (UnimplementedProductServiceServer) GetProduct(context.Context, *GetProductRequest) (*GetProductResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetProduct not implemented") +} +func (UnimplementedProductServiceServer) GetAllProducts(context.Context, *GetAllProductsRequest) (*GetAllProductsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAllProducts not implemented") +} +func (UnimplementedProductServiceServer) UpdateProduct(context.Context, *UpdateProductRequest) (*UpdateProductResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateProduct not implemented") +} +func (UnimplementedProductServiceServer) DeleteProduct(context.Context, *DeleteProductRequest) (*DeleteProductResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteProduct not implemented") +} +func (UnimplementedProductServiceServer) mustEmbedUnimplementedProductServiceServer() {} + +// UnsafeProductServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ProductServiceServer will +// result in compilation errors. +type UnsafeProductServiceServer interface { + mustEmbedUnimplementedProductServiceServer() +} + +func RegisterProductServiceServer(s grpc.ServiceRegistrar, srv ProductServiceServer) { + s.RegisterService(&ProductService_ServiceDesc, srv) +} + +func _ProductService_CreateProduct_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateProductRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).CreateProduct(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_CreateProduct_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).CreateProduct(ctx, req.(*CreateProductRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_GetProduct_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetProductRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).GetProduct(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_GetProduct_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).GetProduct(ctx, req.(*GetProductRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_GetAllProducts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetAllProductsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).GetAllProducts(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_GetAllProducts_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).GetAllProducts(ctx, req.(*GetAllProductsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_UpdateProduct_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateProductRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).UpdateProduct(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_UpdateProduct_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).UpdateProduct(ctx, req.(*UpdateProductRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_DeleteProduct_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteProductRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).DeleteProduct(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_DeleteProduct_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).DeleteProduct(ctx, req.(*DeleteProductRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// ProductService_ServiceDesc is the grpc.ServiceDesc for ProductService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ProductService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "product.ProductService", + HandlerType: (*ProductServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateProduct", + Handler: _ProductService_CreateProduct_Handler, + }, + { + MethodName: "GetProduct", + Handler: _ProductService_GetProduct_Handler, + }, + { + MethodName: "GetAllProducts", + Handler: _ProductService_GetAllProducts_Handler, + }, + { + MethodName: "UpdateProduct", + Handler: _ProductService_UpdateProduct_Handler, + }, + { + MethodName: "DeleteProduct", + Handler: _ProductService_DeleteProduct_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "product/product.proto", +} + +const ( + PriceService_CreatePrice_FullMethodName = "/product.PriceService/CreatePrice" + PriceService_FindPrice_FullMethodName = "/product.PriceService/FindPrice" + PriceService_FindAllPrices_FullMethodName = "/product.PriceService/FindAllPrices" + PriceService_FindAllPricesFromUser_FullMethodName = "/product.PriceService/FindAllPricesFromUser" + PriceService_UpdatePrice_FullMethodName = "/product.PriceService/UpdatePrice" + PriceService_DeletePrice_FullMethodName = "/product.PriceService/DeletePrice" +) + +// PriceServiceClient is the client API for PriceService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type PriceServiceClient interface { + // create method for adding a new price + CreatePrice(ctx context.Context, in *CreatePriceRequest, opts ...grpc.CallOption) (*CreatePriceResponse, error) + // read method for finding a price by ids + FindPrice(ctx context.Context, in *FindPriceRequest, opts ...grpc.CallOption) (*FindPriceResponse, error) + // read method for finding all products + FindAllPrices(ctx context.Context, in *FindAllPricesRequest, opts ...grpc.CallOption) (*FindAllPricesResponse, error) + // read method for finding all products from a specific user/vendor + FindAllPricesFromUser(ctx context.Context, in *FindAllPricesFromUserRequest, opts ...grpc.CallOption) (*FindAllPricesFromUserResponse, error) + // update method for updating a price + UpdatePrice(ctx context.Context, in *UpdatePriceRequest, opts ...grpc.CallOption) (*UpdatePriceResponse, error) + // delete method to get rid of a price + DeletePrice(ctx context.Context, in *DeletePriceRequest, opts ...grpc.CallOption) (*DeletePriceResponse, error) +} + +type priceServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewPriceServiceClient(cc grpc.ClientConnInterface) PriceServiceClient { + return &priceServiceClient{cc} +} + +func (c *priceServiceClient) CreatePrice(ctx context.Context, in *CreatePriceRequest, opts ...grpc.CallOption) (*CreatePriceResponse, error) { + out := new(CreatePriceResponse) + err := c.cc.Invoke(ctx, PriceService_CreatePrice_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *priceServiceClient) FindPrice(ctx context.Context, in *FindPriceRequest, opts ...grpc.CallOption) (*FindPriceResponse, error) { + out := new(FindPriceResponse) + err := c.cc.Invoke(ctx, PriceService_FindPrice_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *priceServiceClient) FindAllPrices(ctx context.Context, in *FindAllPricesRequest, opts ...grpc.CallOption) (*FindAllPricesResponse, error) { + out := new(FindAllPricesResponse) + err := c.cc.Invoke(ctx, PriceService_FindAllPrices_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *priceServiceClient) FindAllPricesFromUser(ctx context.Context, in *FindAllPricesFromUserRequest, opts ...grpc.CallOption) (*FindAllPricesFromUserResponse, error) { + out := new(FindAllPricesFromUserResponse) + err := c.cc.Invoke(ctx, PriceService_FindAllPricesFromUser_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *priceServiceClient) UpdatePrice(ctx context.Context, in *UpdatePriceRequest, opts ...grpc.CallOption) (*UpdatePriceResponse, error) { + out := new(UpdatePriceResponse) + err := c.cc.Invoke(ctx, PriceService_UpdatePrice_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *priceServiceClient) DeletePrice(ctx context.Context, in *DeletePriceRequest, opts ...grpc.CallOption) (*DeletePriceResponse, error) { + out := new(DeletePriceResponse) + err := c.cc.Invoke(ctx, PriceService_DeletePrice_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// PriceServiceServer is the server API for PriceService service. +// All implementations must embed UnimplementedPriceServiceServer +// for forward compatibility +type PriceServiceServer interface { + // create method for adding a new price + CreatePrice(context.Context, *CreatePriceRequest) (*CreatePriceResponse, error) + // read method for finding a price by ids + FindPrice(context.Context, *FindPriceRequest) (*FindPriceResponse, error) + // read method for finding all products + FindAllPrices(context.Context, *FindAllPricesRequest) (*FindAllPricesResponse, error) + // read method for finding all products from a specific user/vendor + FindAllPricesFromUser(context.Context, *FindAllPricesFromUserRequest) (*FindAllPricesFromUserResponse, error) + // update method for updating a price + UpdatePrice(context.Context, *UpdatePriceRequest) (*UpdatePriceResponse, error) + // delete method to get rid of a price + DeletePrice(context.Context, *DeletePriceRequest) (*DeletePriceResponse, error) + mustEmbedUnimplementedPriceServiceServer() +} + +// UnimplementedPriceServiceServer must be embedded to have forward compatible implementations. +type UnimplementedPriceServiceServer struct { +} + +func (UnimplementedPriceServiceServer) CreatePrice(context.Context, *CreatePriceRequest) (*CreatePriceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreatePrice not implemented") +} +func (UnimplementedPriceServiceServer) FindPrice(context.Context, *FindPriceRequest) (*FindPriceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method FindPrice not implemented") +} +func (UnimplementedPriceServiceServer) FindAllPrices(context.Context, *FindAllPricesRequest) (*FindAllPricesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method FindAllPrices not implemented") +} +func (UnimplementedPriceServiceServer) FindAllPricesFromUser(context.Context, *FindAllPricesFromUserRequest) (*FindAllPricesFromUserResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method FindAllPricesFromUser not implemented") +} +func (UnimplementedPriceServiceServer) UpdatePrice(context.Context, *UpdatePriceRequest) (*UpdatePriceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdatePrice not implemented") +} +func (UnimplementedPriceServiceServer) DeletePrice(context.Context, *DeletePriceRequest) (*DeletePriceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeletePrice not implemented") +} +func (UnimplementedPriceServiceServer) mustEmbedUnimplementedPriceServiceServer() {} + +// UnsafePriceServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to PriceServiceServer will +// result in compilation errors. +type UnsafePriceServiceServer interface { + mustEmbedUnimplementedPriceServiceServer() +} + +func RegisterPriceServiceServer(s grpc.ServiceRegistrar, srv PriceServiceServer) { + s.RegisterService(&PriceService_ServiceDesc, srv) +} + +func _PriceService_CreatePrice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreatePriceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PriceServiceServer).CreatePrice(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: PriceService_CreatePrice_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PriceServiceServer).CreatePrice(ctx, req.(*CreatePriceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _PriceService_FindPrice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(FindPriceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PriceServiceServer).FindPrice(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: PriceService_FindPrice_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PriceServiceServer).FindPrice(ctx, req.(*FindPriceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _PriceService_FindAllPrices_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(FindAllPricesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PriceServiceServer).FindAllPrices(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: PriceService_FindAllPrices_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PriceServiceServer).FindAllPrices(ctx, req.(*FindAllPricesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _PriceService_FindAllPricesFromUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(FindAllPricesFromUserRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PriceServiceServer).FindAllPricesFromUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: PriceService_FindAllPricesFromUser_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PriceServiceServer).FindAllPricesFromUser(ctx, req.(*FindAllPricesFromUserRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _PriceService_UpdatePrice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdatePriceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PriceServiceServer).UpdatePrice(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: PriceService_UpdatePrice_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PriceServiceServer).UpdatePrice(ctx, req.(*UpdatePriceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _PriceService_DeletePrice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeletePriceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PriceServiceServer).DeletePrice(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: PriceService_DeletePrice_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PriceServiceServer).DeletePrice(ctx, req.(*DeletePriceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// PriceService_ServiceDesc is the grpc.ServiceDesc for PriceService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var PriceService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "product.PriceService", + HandlerType: (*PriceServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreatePrice", + Handler: _PriceService_CreatePrice_Handler, + }, + { + MethodName: "FindPrice", + Handler: _PriceService_FindPrice_Handler, + }, + { + MethodName: "FindAllPrices", + Handler: _PriceService_FindAllPrices_Handler, + }, + { + MethodName: "FindAllPricesFromUser", + Handler: _PriceService_FindAllPricesFromUser_Handler, + }, + { + MethodName: "UpdatePrice", + Handler: _PriceService_UpdatePrice_Handler, + }, + { + MethodName: "DeletePrice", + Handler: _PriceService_DeletePrice_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "product/product.proto", +} diff --git a/src/product-service/main.go b/src/product-service/main.go index efa629ce..b9aebbf8 100644 --- a/src/product-service/main.go +++ b/src/product-service/main.go @@ -1,29 +1,94 @@ +//go:generate protoc --proto_path=../../lib/rpc --go_out=internal/proto --go_opt=paths=source_relative --go-grpc_out=internal/proto --go-grpc_opt=paths=source_relative ../../lib/rpc/product/product.proto package main import ( - "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/api/router" + "context" + "errors" + "google.golang.org/grpc" + "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/api/http/router" + "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/api/rpc" + proto "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/internal/proto/product" "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/prices" priceModel "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/prices/model" "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/products" productModel "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/products/model" "log" + "net" "net/http" + "os" + "os/signal" + "sync" + "syscall" ) func main() { - productRepository := products.NewDemoRepository() - productsController := products.NewDefaultController(productRepository) + var productRepository products.Repository = products.NewDemoRepository() + var productsController products.Controller = products.NewCoalescingController(productRepository) createContentForProducts(productRepository) - priceRepository := prices.NewDemoRepository() - pricesController := prices.NewDefaultController(priceRepository) + var priceRepository prices.Repository = prices.NewDemoRepository() + var pricesController prices.Controller = prices.NewCoalescingController(priceRepository) createContentForPrices(priceRepository) + var wg sync.WaitGroup + + ctx, cancel := context.WithCancel(context.Background()) + + wg.Add(1) + go startHTTPServer(ctx, &wg, &productsController, &pricesController) + + wg.Add(1) + go startGRPCServer(ctx, &wg, &productRepository, &priceRepository) + + stopChan := make(chan os.Signal, 1) + signal.Notify(stopChan, syscall.SIGINT, syscall.SIGTERM) + + <-stopChan + cancel() + + wg.Wait() +} + +func startHTTPServer(ctx context.Context, wg *sync.WaitGroup, productsController *products.Controller, pricesController *prices.Controller) { + defer wg.Done() + handler := router.New(productsController, pricesController) + server := &http.Server{Addr: ":3003", Handler: handler} + + go func() { + if err := server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { + log.Fatalf("Failed to start HTTP server: %v", err) + } + }() + + <-ctx.Done() + + if err := server.Shutdown(context.Background()); err != nil { + log.Fatalf("HTTP Server Shutdown Failed:%v", err) + } +} - if err := http.ListenAndServe(":3003", handler); err != nil { - log.Fatalf("error while listen and serve: %s", err.Error()) +func startGRPCServer(ctx context.Context, wg *sync.WaitGroup, productRepository *products.Repository, priceRepository *prices.Repository) { + defer wg.Done() + + lis, err := net.Listen("tcp", ":50051") + if err != nil { + log.Fatalf("Failed to listen: %v", err) } + + grpcServer := grpc.NewServer() + productServiceServer := rpc.NewProductServiceServer(productRepository, priceRepository) + proto.RegisterProductServiceServer(grpcServer, productServiceServer) + proto.RegisterPriceServiceServer(grpcServer, productServiceServer) + + go func() { + if err := grpcServer.Serve(lis); err != nil { + log.Fatalf("Failed to start gRPC server: %v", err) + } + }() + + <-ctx.Done() + grpcServer.GracefulStop() } func createContentForPrices(priceRepository prices.Repository) { diff --git a/src/product-service/prices/coalescing_controller.go b/src/product-service/prices/coalescing_controller.go new file mode 100644 index 00000000..cb63aeee --- /dev/null +++ b/src/product-service/prices/coalescing_controller.go @@ -0,0 +1,163 @@ +package prices + +import ( + "encoding/json" + "fmt" + "golang.org/x/sync/singleflight" + "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/prices/model" + "net/http" + "strconv" +) + +type coalescingController struct { + priceRepository Repository + group *singleflight.Group +} + +func NewCoalescingController(priceRepository Repository) *coalescingController { + return &coalescingController{ + priceRepository, + &singleflight.Group{}} +} + +func (controller *coalescingController) GetPrices(writer http.ResponseWriter, request *http.Request) { + msg, err, _ := controller.group.Do("get-all", func() (interface{}, error) { + return controller.priceRepository.FindAll() + }) + + if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + } + + writer.Header().Set("Content-Type", "application/json") + err = json.NewEncoder(writer).Encode(msg) + if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + return + } +} + +func (controller *coalescingController) GetPricesByUser(writer http.ResponseWriter, request *http.Request) { + userIdAttribute := request.Context().Value("userId").(string) + + msg, err, _ := controller.group.Do("get_id_"+userIdAttribute, func() (interface{}, error) { + userId, err := strconv.ParseUint(userIdAttribute, 10, 64) + if err != nil { + http.Error(writer, err.Error(), http.StatusBadRequest) + return nil, err + } + + value, err := controller.priceRepository.FindAllByUser(userId) + if err != nil { + if err.Error() == ErrorPriceNotFound { + http.Error(writer, err.Error(), http.StatusNotFound) + return nil, err + } + http.Error(writer, err.Error(), http.StatusInternalServerError) + } + + return value, nil + }) + + writer.Header().Set("Content-Type", "application/json") + err = json.NewEncoder(writer).Encode(msg) + if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + return + } +} + +func (controller *coalescingController) PostPrice(writer http.ResponseWriter, request *http.Request) { + productId, productIdErr := strconv.ParseUint(request.Context().Value("productId").(string), 10, 64) + userId, userIdErr := strconv.ParseUint(request.Context().Value("userId").(string), 10, 64) + + if productIdErr != nil || userIdErr != nil { + http.Error(writer, "Invalid listId or productId", http.StatusBadRequest) + return + } + + var requestData JsonFormatCreatePriceRequest + if err := json.NewDecoder(request.Body).Decode(&requestData); err != nil { + writer.WriteHeader(http.StatusBadRequest) + return + } + + if _, err := controller.priceRepository.Create(&model.Price{ + ProductId: productId, + UserId: userId, + Price: requestData.Price, + }); err != nil { + writer.WriteHeader(http.StatusInternalServerError) + } +} + +func (controller *coalescingController) GetPrice(writer http.ResponseWriter, request *http.Request) { + userIdAttribute := request.Context().Value("userId").(string) + productIdAttribute := request.Context().Value("productId").(string) + + msg, err, _ := controller.group.Do(fmt.Sprintf("get_id_%s_%s", userIdAttribute, productIdAttribute), func() (interface{}, error) { + userId, err := strconv.ParseUint(userIdAttribute, 10, 64) + productId, err := strconv.ParseUint(productIdAttribute, 10, 64) + if err != nil { + http.Error(writer, err.Error(), http.StatusBadRequest) + return nil, err + } + + value, err := controller.priceRepository.FindByIds(productId, userId) + if err != nil { + if err.Error() == ErrorPriceNotFound { + http.Error(writer, err.Error(), http.StatusNotFound) + return nil, err + } + http.Error(writer, err.Error(), http.StatusInternalServerError) + } + + return value, nil + }) + + writer.Header().Set("Content-Type", "application/json") + err = json.NewEncoder(writer).Encode(msg) + if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + } +} + +func (controller *coalescingController) PutPrice(writer http.ResponseWriter, request *http.Request) { + userId, err := strconv.ParseUint(request.Context().Value("userId").(string), 10, 64) + productId, err := strconv.ParseUint(request.Context().Value("productId").(string), 10, 64) + + if err != nil { + http.Error(writer, err.Error(), http.StatusBadRequest) + return + } + + var requestData JsonFormatUpdatePriceRequest + if err := json.NewDecoder(request.Body).Decode(&requestData); err != nil { + writer.WriteHeader(http.StatusBadRequest) + return + } + + if _, err := controller.priceRepository.Update(&model.Price{ + UserId: userId, + ProductId: productId, + Price: requestData.Price, + }); err != nil { + writer.WriteHeader(http.StatusInternalServerError) + return + } +} + +func (controller *coalescingController) DeletePrice(writer http.ResponseWriter, request *http.Request) { + userId, err := strconv.ParseUint(request.Context().Value("userId").(string), 10, 64) + productId, err := strconv.ParseUint(request.Context().Value("productId").(string), 10, 64) + + if err != nil { + http.Error(writer, err.Error(), http.StatusBadRequest) + return + } + + if err := controller.priceRepository.Delete(&model.Price{ProductId: productId, UserId: userId}); err != nil { + writer.WriteHeader(http.StatusInternalServerError) + return + } +} diff --git a/src/product-service/prices/coalescing_controller_test.go b/src/product-service/prices/coalescing_controller_test.go new file mode 100644 index 00000000..eb3cfb1f --- /dev/null +++ b/src/product-service/prices/coalescing_controller_test.go @@ -0,0 +1,509 @@ +package prices + +import ( + "context" + "encoding/json" + "github.com/stretchr/testify/assert" + "golang.org/x/sync/singleflight" + "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/prices/model" + "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/prices/utils" + "net/http" + "net/http/httptest" + "strings" + "testing" +) + +func TestNewCoalescingController(t *testing.T) { + demoRepo := NewDemoRepository() + controller := NewCoalescingController(demoRepo) + + assert.NotNil(t, controller) + assert.Equal(t, demoRepo, controller.priceRepository) + assert.IsType(t, &singleflight.Group{}, controller.group) +} + +func TestCoalescingController_DeletePrice(t *testing.T) { + type fields struct { + priceRepository Repository + } + type args struct { + writer *httptest.ResponseRecorder + request *http.Request + } + tests := []struct { + name string + fields fields + args args + wantStatus int + }{ + { + name: "Successfully delete existing price (expect 200)", + fields: fields{ + priceRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: func() *http.Request { + var request = httptest.NewRequest("DELETE", "/api/v1/price/1/1", nil) + request = request.WithContext(context.WithValue(request.Context(), "productId", "1")) + request = request.WithContext(context.WithValue(request.Context(), "userId", "1")) + return request + }(), + }, + + wantStatus: http.StatusOK, + }, + { + name: "Bad non-numeric request (expect 400)", + fields: fields{ + priceRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: utils.CreatePriceRequestWithValues("DELETE", "/api/v1/price/abc/abc", "abc", "abc"), + }, + wantStatus: http.StatusBadRequest, + }, + { + name: "Unknown product to delete (expect 500)", + fields: fields{ + priceRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: utils.CreatePriceRequestWithValues("DELETE", "/api/v1/price/42/42", "42", "42"), + }, + wantStatus: http.StatusInternalServerError, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + controller := NewCoalescingController(tt.fields.priceRepository) + controller.DeletePrice(tt.args.writer, tt.args.request) + if tt.args.writer.Code != tt.wantStatus { + t.Errorf("Expected status code %d, got %d", tt.wantStatus, tt.args.writer.Code) + } + }) + } +} + +func TestCoalescingController_GetPrices(t *testing.T) { + t.Run("should return all prices", func(t *testing.T) { + controller := NewCoalescingController(GenerateExampleDemoRepository()) + + writer := httptest.NewRecorder() + request := httptest.NewRequest("GET", "/api/v1/price", nil) + + // Test request + controller.GetPrices(writer, request) + + res := writer.Result() + var response []model.Price + err := json.NewDecoder(res.Body).Decode(&response) + + if err != nil { + t.Error(err) + } + + if writer.Code != http.StatusOK { + t.Errorf("Expected status code %d, got %d", http.StatusOK, writer.Code) + } + + if writer.Header().Get("Content-Type") != "application/json" { + t.Errorf("Expected content type %s, got %s", + "application/json", writer.Header().Get("Content-Type")) + } + + prices := GenerateExamplePriceSlice() + + if len(response) != len(prices) { + t.Errorf("Expected count of prices is %d, got %d", + 2, len(response)) + } + }) +} + +func TestCoalescingController_GetPricesByUser(t *testing.T) { + type fields struct { + priceRepository Repository + } + type args struct { + writer *httptest.ResponseRecorder + request *http.Request + } + tests := []struct { + name string + fields fields + args args + wantStatus int + }{ + { + name: "Bad non-numeric request (expect 400)", + fields: fields{ + priceRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: func() *http.Request { + var request = httptest.NewRequest("GET", "/api/v1/price/user/abc", nil) + request = request.WithContext(context.WithValue(request.Context(), "userId", "abc")) + return request + }(), + }, + wantStatus: http.StatusBadRequest, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + controller := NewCoalescingController(tt.fields.priceRepository) + controller.GetPricesByUser(tt.args.writer, tt.args.request) + if tt.args.writer.Code != tt.wantStatus { + t.Errorf("Expected status code %d, got %d", tt.wantStatus, tt.args.writer.Code) + } + }) + } + + t.Run("Successfully get existing prices by user (expect 200 and prices)", func(t *testing.T) { + writer := httptest.NewRecorder() + request := httptest.NewRequest("GET", "/api/v1/price/user/1", nil) + request = request.WithContext(context.WithValue(request.Context(), "userId", "1")) + + controller := NewCoalescingController(GenerateExampleDemoRepository()) + + // when + controller.GetPricesByUser(writer, request) + + // then + if writer.Code != http.StatusOK { + t.Errorf("Expected status code %d, got %d", http.StatusOK, writer.Code) + } + + if writer.Header().Get("Content-Type") != "application/json" { + t.Errorf("Expected content type %s, got %s", + "application/json", writer.Header().Get("Content-Type")) + } + + result := writer.Result() + var response []model.Price + err := json.NewDecoder(result.Body).Decode(&response) + if err != nil { + t.Fatal(err.Error()) + } + + if len(response) != 1 { + t.Errorf("Expected count of prices is %d, got %d", + 1, len(response)) + } + + for i, price := range response { + if price.UserId != 1 { + t.Errorf("Expected role of user %d, got %d", 1, response[i].UserId) + } + } + }) +} + +func TestCoalescingController_GetPrice(t *testing.T) { + type fields struct { + priceRepository Repository + } + type args struct { + writer *httptest.ResponseRecorder + request *http.Request + } + tests := []struct { + name string + fields fields + args args + wantStatus int + }{ + { + name: "Bad non-numeric request (expect 400)", + fields: fields{ + priceRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: utils.CreatePriceRequestWithValues("GET", "/api/v1/price/abc/abc", "abc", "abc"), + }, + wantStatus: http.StatusBadRequest, + }, + { + name: "Unknown price (expect 404)", + fields: fields{ + priceRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: utils.CreatePriceRequestWithValues("GET", "/api/v1/price/42/42", "42", "42"), + }, + wantStatus: http.StatusNotFound, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + controller := NewCoalescingController(tt.fields.priceRepository) + controller.GetPrice(tt.args.writer, tt.args.request) + if tt.args.writer.Code != tt.wantStatus { + t.Errorf("Expected status code %d, got %d", tt.wantStatus, tt.args.writer.Code) + } + }) + } + + t.Run("Successfully get existing price (expect 200 and price)", func(t *testing.T) { + writer := httptest.NewRecorder() + request := httptest.NewRequest("GET", "/api/v1/price/1/1", nil) + request = request.WithContext(context.WithValue(request.Context(), "productId", "1")) + request = request.WithContext(context.WithValue(request.Context(), "userId", "1")) + + controller := NewCoalescingController(GenerateExampleDemoRepository()) + + // when + controller.GetPrice(writer, request) + + // then + if writer.Code != http.StatusOK { + t.Errorf("Expected status code %d, got %d", http.StatusOK, writer.Code) + } + + if writer.Header().Get("Content-Type") != "application/json" { + t.Errorf("Expected content type %s, got %s", + "application/json", writer.Header().Get("Content-Type")) + } + + result := writer.Result() + var response model.Price + err := json.NewDecoder(result.Body).Decode(&response) + if err != nil { + t.Fatal(err.Error()) + } + + if response.ProductId != 1 { + t.Errorf("Expected product id of price %d, got %d", 1, response.ProductId) + } + + if response.UserId != 1 { + t.Errorf("Expected user id of product %d, got %d", 1, response.UserId) + } + + if response.Price != 2.99 { + t.Errorf("Expected ean of product %f, got %f", 2.99, response.Price) + } + + }) +} + +func TestCoalescingController_PostPrice(t *testing.T) { + type fields struct { + priceRepository Repository + } + type args struct { + writer *httptest.ResponseRecorder + request *http.Request + } + tests := []struct { + name string + fields fields + args args + expectedStatus int + expectedResponse string + }{ + { + name: "Valid Price", + fields: fields{ + priceRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: func() *http.Request { + var request = httptest.NewRequest( + "POST", + "/api/v1/price/4/4", + strings.NewReader(`{"price": 0.99}`)) + request = request.WithContext(context.WithValue(request.Context(), "productId", "4")) + request = request.WithContext(context.WithValue(request.Context(), "userId", "4")) + return request + }(), + }, + expectedStatus: http.StatusOK, + expectedResponse: "", + }, + { + name: "Malformed JSON", + fields: fields{ + priceRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: func() *http.Request { + var request = httptest.NewRequest( + "POST", + "/api/v1/price/5/5", + strings.NewReader(`{"price": 0.99`)) + request = request.WithContext(context.WithValue(request.Context(), "productId", "5")) + request = request.WithContext(context.WithValue(request.Context(), "userId", "5")) + return request + }(), + }, + expectedStatus: http.StatusBadRequest, + expectedResponse: "", + }, + { + name: "Invalid price, incorrect Type for price (Non-numeric)", + fields: fields{ + priceRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: func() *http.Request { + var request = httptest.NewRequest( + "POST", + "/api/v1/price/5/5", + strings.NewReader(`{"price": "0.99"}`)) + request = request.WithContext(context.WithValue(request.Context(), "productId", "5")) + request = request.WithContext(context.WithValue(request.Context(), "userId", "5")) + return request + }(), + }, + expectedStatus: http.StatusBadRequest, + expectedResponse: "", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + controller := NewCoalescingController(tt.fields.priceRepository) + controller.PostPrice(tt.args.writer, tt.args.request) + + // You can then assert the response status and content, and check against your expectations. + if tt.args.writer.Code != tt.expectedStatus { + t.Errorf("Expected status code %d, but got %d", tt.expectedStatus, tt.args.writer.Code) + } + + if tt.expectedResponse != "" { + actualResponse := tt.args.writer.Body.String() + if actualResponse != tt.expectedResponse { + t.Errorf("Expected response: %s, but got: %s", tt.expectedResponse, actualResponse) + } + } + }) + } +} + +func TestCoalescingController_PutPrice(t *testing.T) { + type fields struct { + priceRepository Repository + } + type args struct { + writer *httptest.ResponseRecorder + request *http.Request + } + + tests := []struct { + name string + fields fields + args args + expectedStatus int + expectedResponse string // If you want to check the response content + }{ + { + name: "Valid Update", + fields: fields{ + priceRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: func() *http.Request { + var request = httptest.NewRequest( + "PUT", + "/api/v1/price/1/1", + strings.NewReader(`{"userId": 1, "productId": 1, "price": 10.99}`)) + request = request.WithContext(context.WithValue(request.Context(), "productId", "1")) + request = request.WithContext(context.WithValue(request.Context(), "userId", "1")) + return request + }(), + }, + expectedStatus: http.StatusOK, + expectedResponse: "", + }, + { + name: "Valid Update (Partly Fields)", + fields: fields{ + priceRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: func() *http.Request { + var request = httptest.NewRequest( + "PUT", + "/api/v1/price/2/2", + strings.NewReader(`{"price": 6.50}`)) + request = request.WithContext(context.WithValue(request.Context(), "productId", "2")) + request = request.WithContext(context.WithValue(request.Context(), "userId", "2")) + return request + }(), + }, + expectedStatus: http.StatusOK, + expectedResponse: "", + }, + { + name: "Malformed JSON", + fields: fields{ + priceRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: func() *http.Request { + var request = httptest.NewRequest( + "PUT", + "/api/v1/price/2/2", + strings.NewReader(`{"price": 6.50`)) + request = request.WithContext(context.WithValue(request.Context(), "productId", "2")) + request = request.WithContext(context.WithValue(request.Context(), "userId", "2")) + return request + }(), + }, + expectedStatus: http.StatusBadRequest, + expectedResponse: "", + }, + { + name: "Incorrect Type for Price (Non-numeric)", + fields: fields{ + // Set up your repository mock or test double here if needed + }, + args: args{ + writer: httptest.NewRecorder(), + request: func() *http.Request { + var request = httptest.NewRequest( + "PUT", + "/api/v1/price/2/2", + strings.NewReader(`{"price": "Wrong Type"`)) + request = request.WithContext(context.WithValue(request.Context(), "productId", "2")) + request = request.WithContext(context.WithValue(request.Context(), "userId", "2")) + return request + }(), + }, + expectedStatus: http.StatusBadRequest, + expectedResponse: "", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + controller := NewCoalescingController(tt.fields.priceRepository) + controller.PutPrice(tt.args.writer, tt.args.request) + + // You can then assert the response status and content, and check against your expectations. + if tt.args.writer.Code != tt.expectedStatus { + t.Errorf("Expected status code %d, but got %d", tt.expectedStatus, tt.args.writer.Code) + } + + if tt.expectedResponse != "" { + actualResponse := tt.args.writer.Body.String() + if actualResponse != tt.expectedResponse { + t.Errorf("Expected response: %s, but got: %s", tt.expectedResponse, actualResponse) + } + } + }) + } +} diff --git a/src/product-service/prices/default_controller.go b/src/product-service/prices/default_controller.go index 2b1e0545..1eb59168 100644 --- a/src/product-service/prices/default_controller.go +++ b/src/product-service/prices/default_controller.go @@ -15,7 +15,7 @@ func NewDefaultController(priceRepository Repository) *defaultController { return &defaultController{priceRepository} } -func (controller defaultController) GetPrices(writer http.ResponseWriter, request *http.Request) { +func (controller *defaultController) GetPrices(writer http.ResponseWriter, request *http.Request) { values, err := controller.priceRepository.FindAll() if err != nil { http.Error(writer, err.Error(), http.StatusInternalServerError) @@ -29,7 +29,7 @@ func (controller defaultController) GetPrices(writer http.ResponseWriter, reques } } -func (controller defaultController) GetPricesByUser(writer http.ResponseWriter, request *http.Request) { +func (controller *defaultController) GetPricesByUser(writer http.ResponseWriter, request *http.Request) { userId, err := strconv.ParseUint(request.Context().Value("userId").(string), 10, 64) if err != nil { @@ -49,7 +49,7 @@ func (controller defaultController) GetPricesByUser(writer http.ResponseWriter, } } -func (controller defaultController) PostPrice(writer http.ResponseWriter, request *http.Request) { +func (controller *defaultController) PostPrice(writer http.ResponseWriter, request *http.Request) { productId, productIdErr := strconv.ParseUint(request.Context().Value("productId").(string), 10, 64) userId, userIdErr := strconv.ParseUint(request.Context().Value("userId").(string), 10, 64) @@ -73,7 +73,7 @@ func (controller defaultController) PostPrice(writer http.ResponseWriter, reques } } -func (controller defaultController) GetPrice(writer http.ResponseWriter, request *http.Request) { +func (controller *defaultController) GetPrice(writer http.ResponseWriter, request *http.Request) { userId, err := strconv.ParseUint(request.Context().Value("userId").(string), 10, 64) productId, err := strconv.ParseUint(request.Context().Value("productId").(string), 10, 64) @@ -98,7 +98,7 @@ func (controller defaultController) GetPrice(writer http.ResponseWriter, request } } -func (controller defaultController) PutPrice(writer http.ResponseWriter, request *http.Request) { +func (controller *defaultController) PutPrice(writer http.ResponseWriter, request *http.Request) { userId, err := strconv.ParseUint(request.Context().Value("userId").(string), 10, 64) productId, err := strconv.ParseUint(request.Context().Value("productId").(string), 10, 64) @@ -123,7 +123,7 @@ func (controller defaultController) PutPrice(writer http.ResponseWriter, request } } -func (controller defaultController) DeletePrice(writer http.ResponseWriter, request *http.Request) { +func (controller *defaultController) DeletePrice(writer http.ResponseWriter, request *http.Request) { userId, err := strconv.ParseUint(request.Context().Value("userId").(string), 10, 64) productId, err := strconv.ParseUint(request.Context().Value("productId").(string), 10, 64) diff --git a/src/product-service/prices/default_controller_test.go b/src/product-service/prices/default_controller_test.go index a0701014..18ee5f19 100644 --- a/src/product-service/prices/default_controller_test.go +++ b/src/product-service/prices/default_controller_test.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/prices/model" + "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/prices/utils" "net/http" "net/http/httptest" "reflect" @@ -52,7 +53,7 @@ func TestDefaultController_DeletePrice(t *testing.T) { { name: "Successfully delete existing price (expect 200)", fields: fields{ - priceRepository: setupMockRepository(), + priceRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), @@ -69,22 +70,22 @@ func TestDefaultController_DeletePrice(t *testing.T) { { name: "Bad non-numeric request (expect 400)", fields: fields{ - priceRepository: setupMockRepository(), + priceRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), - request: createRequestWithValues("DELETE", "/api/v1/price/abc/abc", "abc", "abc"), + request: utils.CreatePriceRequestWithValues("DELETE", "/api/v1/price/abc/abc", "abc", "abc"), }, wantStatus: http.StatusBadRequest, }, { name: "Unknown product to delete (expect 500)", fields: fields{ - priceRepository: setupMockRepository(), + priceRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), - request: createRequestWithValues("DELETE", "/api/v1/price/42/42", "42", "42"), + request: utils.CreatePriceRequestWithValues("DELETE", "/api/v1/price/42/42", "42", "42"), }, wantStatus: http.StatusInternalServerError, }, @@ -105,7 +106,7 @@ func TestDefaultController_DeletePrice(t *testing.T) { func TestDefaultController_GetPrices(t *testing.T) { t.Run("should return all prices", func(t *testing.T) { controller := defaultController{ - priceRepository: setupMockRepository(), + priceRepository: GenerateExampleDemoRepository(), } writer := httptest.NewRecorder() @@ -131,7 +132,7 @@ func TestDefaultController_GetPrices(t *testing.T) { "application/json", writer.Header().Get("Content-Type")) } - prices := setupDemoPricesSlice() + prices := GenerateExamplePriceSlice() if len(response) != len(prices) { t.Errorf("Expected count of prices is %d, got %d", @@ -157,7 +158,7 @@ func TestDefaultController_GetPricesByUser(t *testing.T) { { name: "Bad non-numeric request (expect 400)", fields: fields{ - priceRepository: setupMockRepository(), + priceRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), @@ -188,7 +189,7 @@ func TestDefaultController_GetPricesByUser(t *testing.T) { request = request.WithContext(context.WithValue(request.Context(), "userId", "1")) controller := defaultController{ - priceRepository: setupMockRepository(), + priceRepository: GenerateExampleDemoRepository(), } // when @@ -241,22 +242,22 @@ func TestDefaultController_GetPrice(t *testing.T) { { name: "Bad non-numeric request (expect 400)", fields: fields{ - priceRepository: setupMockRepository(), + priceRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), - request: createRequestWithValues("GET", "/api/v1/price/abc/abc", "abc", "abc"), + request: utils.CreatePriceRequestWithValues("GET", "/api/v1/price/abc/abc", "abc", "abc"), }, wantStatus: http.StatusBadRequest, }, { name: "Unknown price (expect 404)", fields: fields{ - priceRepository: setupMockRepository(), + priceRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), - request: createRequestWithValues("GET", "/api/v1/price/42/42", "42", "42"), + request: utils.CreatePriceRequestWithValues("GET", "/api/v1/price/42/42", "42", "42"), }, wantStatus: http.StatusNotFound, }, @@ -280,7 +281,7 @@ func TestDefaultController_GetPrice(t *testing.T) { request = request.WithContext(context.WithValue(request.Context(), "userId", "1")) controller := defaultController{ - priceRepository: setupMockRepository(), + priceRepository: GenerateExampleDemoRepository(), } // when @@ -336,7 +337,7 @@ func TestDefaultController_PostPrice(t *testing.T) { { name: "Valid Price", fields: fields{ - priceRepository: setupMockRepository(), + priceRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), @@ -356,7 +357,7 @@ func TestDefaultController_PostPrice(t *testing.T) { { name: "Malformed JSON", fields: fields{ - priceRepository: setupMockRepository(), + priceRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), @@ -376,7 +377,7 @@ func TestDefaultController_PostPrice(t *testing.T) { { name: "Invalid price, incorrect Type for price (Non-numeric)", fields: fields{ - priceRepository: setupMockRepository(), + priceRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), @@ -436,7 +437,7 @@ func TestDefaultController_PutPrice(t *testing.T) { { name: "Valid Update", fields: fields{ - priceRepository: setupMockRepository(), + priceRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), @@ -456,7 +457,7 @@ func TestDefaultController_PutPrice(t *testing.T) { { name: "Valid Update (Partly Fields)", fields: fields{ - priceRepository: setupMockRepository(), + priceRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), @@ -476,7 +477,7 @@ func TestDefaultController_PutPrice(t *testing.T) { { name: "Malformed JSON", fields: fields{ - priceRepository: setupMockRepository(), + priceRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), @@ -536,37 +537,3 @@ func TestDefaultController_PutPrice(t *testing.T) { }) } } - -func createRequestWithValues(method string, path string, productId string, userId string) *http.Request { - request := httptest.NewRequest(method, path, nil) - ctx := request.Context() - ctx = context.WithValue(ctx, "productId", productId) - ctx = context.WithValue(ctx, "userId", userId) - request = request.WithContext(ctx) - return request -} - -func setupMockRepository() Repository { - repository := NewDemoRepository() - pricesSlice := setupDemoPricesSlice() - for _, price := range pricesSlice { - repository.Create(price) - } - - return repository -} - -func setupDemoPricesSlice() []*model.Price { - return []*model.Price{ - { - UserId: 1, - ProductId: 1, - Price: 2.99, - }, - { - UserId: 2, - ProductId: 2, - Price: 5.99, - }, - } -} diff --git a/src/product-service/prices/demo_repository_example.go b/src/product-service/prices/demo_repository_example.go new file mode 100644 index 00000000..23514ea7 --- /dev/null +++ b/src/product-service/prices/demo_repository_example.go @@ -0,0 +1,28 @@ +package prices + +import "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/prices/model" + +func GenerateExampleDemoRepository() Repository { + repository := NewDemoRepository() + pricesSlice := GenerateExamplePriceSlice() + for _, price := range pricesSlice { + repository.Create(price) + } + + return repository +} + +func GenerateExamplePriceSlice() []*model.Price { + return []*model.Price{ + { + UserId: 1, + ProductId: 1, + Price: 2.99, + }, + { + UserId: 2, + ProductId: 2, + Price: 5.99, + }, + } +} diff --git a/src/product-service/prices/utils/controller_test_utils.go b/src/product-service/prices/utils/controller_test_utils.go new file mode 100644 index 00000000..07fa4fc3 --- /dev/null +++ b/src/product-service/prices/utils/controller_test_utils.go @@ -0,0 +1,16 @@ +package utils + +import ( + "context" + "net/http" + "net/http/httptest" +) + +func CreatePriceRequestWithValues(method string, path string, productId string, userId string) *http.Request { + request := httptest.NewRequest(method, path, nil) + ctx := request.Context() + ctx = context.WithValue(ctx, "productId", productId) + ctx = context.WithValue(ctx, "userId", userId) + request = request.WithContext(ctx) + return request +} diff --git a/src/product-service/products/coalescing_controller.go b/src/product-service/products/coalescing_controller.go new file mode 100644 index 00000000..de545cb7 --- /dev/null +++ b/src/product-service/products/coalescing_controller.go @@ -0,0 +1,157 @@ +package products + +import ( + "encoding/json" + "golang.org/x/sync/singleflight" + "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/products/model" + "net/http" + "strconv" +) + +type coalescingController struct { + productRepository Repository + group *singleflight.Group +} + +func NewCoalescingController(productRepository Repository) *coalescingController { + return &coalescingController{ + productRepository, + &singleflight.Group{}, + } +} + +func (controller *coalescingController) GetProducts(writer http.ResponseWriter, request *http.Request) { + msg, err, _ := controller.group.Do("get-all", func() (interface{}, error) { + return controller.productRepository.FindAll() + }) + + if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + } + + writer.Header().Set("Content-Type", "application/json") + err = json.NewEncoder(writer).Encode(msg) + if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + return + } +} + +func (controller *coalescingController) PostProduct(writer http.ResponseWriter, request *http.Request) { + var requestData JsonFormatCreateProductRequest + if err := json.NewDecoder(request.Body).Decode(&requestData); err != nil { + writer.WriteHeader(http.StatusBadRequest) + return + } + + product, err := controller.productRepository.Create(&model.Product{ + Description: requestData.Description, + Ean: requestData.Ean, + }) + + if err != nil { + writer.WriteHeader(http.StatusInternalServerError) + return + } + + writer.Header().Set("Content-Type", "application/json") + err = json.NewEncoder(writer).Encode(product) + if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + return + } +} + +func (controller *coalescingController) GetProductById(writer http.ResponseWriter, request *http.Request) { + productIdAttribute := request.Context().Value("productId").(string) + + msg, err, _ := controller.group.Do("get_id_"+productIdAttribute, func() (interface{}, error) { + productId, err := strconv.ParseUint(productIdAttribute, 10, 64) + if err != nil { + http.Error(writer, err.Error(), http.StatusBadRequest) + return nil, err + } + + value, err := controller.productRepository.FindById(productId) + if err != nil { + if err.Error() == ErrorProductNotFound { + http.Error(writer, err.Error(), http.StatusNotFound) + return nil, err + } + http.Error(writer, err.Error(), http.StatusInternalServerError) + } + + return value, nil + }) + + writer.Header().Set("Content-Type", "application/json") + err = json.NewEncoder(writer).Encode(msg) + if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + } +} + +func (controller *coalescingController) GetProductByEan(writer http.ResponseWriter, request *http.Request) { + productEanAttribute := request.Context().Value("productEan").(string) + + msg, err, _ := controller.group.Do("get_ean_"+productEanAttribute, func() (interface{}, error) { + productEan, err := strconv.ParseUint(productEanAttribute, 10, 64) + if err != nil { + http.Error(writer, err.Error(), http.StatusBadRequest) + return nil, err + } + + value, err := controller.productRepository.FindByEan(productEan) + if err != nil { + if err.Error() == ErrorProductNotFound { + http.Error(writer, err.Error(), http.StatusNotFound) + return nil, err + } + http.Error(writer, err.Error(), http.StatusInternalServerError) + } + + return value, nil + }) + + writer.Header().Set("Content-Type", "application/json") + err = json.NewEncoder(writer).Encode(msg) + if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + } +} + +func (controller *coalescingController) PutProduct(writer http.ResponseWriter, request *http.Request) { + productId, err := strconv.ParseUint(request.Context().Value("productId").(string), 10, 64) + if err != nil { + http.Error(writer, err.Error(), http.StatusBadRequest) + return + } + + var requestData JsonFormatUpdateProductRequest + if err := json.NewDecoder(request.Body).Decode(&requestData); err != nil { + writer.WriteHeader(http.StatusBadRequest) + return + } + + if _, err := controller.productRepository.Update(&model.Product{ + Id: productId, + Description: requestData.Description, + Ean: requestData.Ean, + }); err != nil { + writer.WriteHeader(http.StatusInternalServerError) + return + } +} + +func (controller *coalescingController) DeleteProduct(writer http.ResponseWriter, request *http.Request) { + productId, err := strconv.ParseUint(request.Context().Value("productId").(string), 10, 64) + if err != nil { + http.Error(writer, err.Error(), http.StatusBadRequest) + return + } + + if err := controller.productRepository.Delete(&model.Product{Id: productId}); err != nil { + writer.WriteHeader(http.StatusInternalServerError) + return + } +} diff --git a/src/product-service/products/coalescing_controller_test.go b/src/product-service/products/coalescing_controller_test.go new file mode 100644 index 00000000..1c207dd2 --- /dev/null +++ b/src/product-service/products/coalescing_controller_test.go @@ -0,0 +1,528 @@ +package products + +import ( + "context" + "encoding/json" + "github.com/stretchr/testify/assert" + "golang.org/x/sync/singleflight" + "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/products/model" + "net/http" + "net/http/httptest" + "sort" + "strings" + "testing" +) + +func TestNewCoalescingController(t *testing.T) { + demoRepo := NewDemoRepository() + + controller := NewCoalescingController(demoRepo) + + assert.NotNil(t, controller) + assert.Equal(t, demoRepo, controller.productRepository) + assert.IsType(t, &singleflight.Group{}, controller.group) +} + +func TestCoalescingController_DeleteProduct(t *testing.T) { + type fields struct { + productRepository Repository + } + type args struct { + writer *httptest.ResponseRecorder + request *http.Request + } + tests := []struct { + name string + fields fields + args args + wantStatus int + }{ + { + name: "Successfully delete existing product (expect 200)", + fields: fields{ + productRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: func() *http.Request { + var request = httptest.NewRequest("DELETE", "/api/v1/product/1", nil) + request = request.WithContext(context.WithValue(request.Context(), "productId", "1")) + return request + }(), + }, + wantStatus: http.StatusOK, + }, + { + name: "Bad non-numeric request (expect 400)", + fields: fields{ + productRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: func() *http.Request { + var request = httptest.NewRequest("DELETE", "/api/v1/product/abc", nil) + request = request.WithContext(context.WithValue(request.Context(), "productId", "abc")) + return request + }(), + }, + wantStatus: http.StatusBadRequest, + }, + { + name: "Unknown product to delete (expect 500)", + fields: fields{ + productRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: func() *http.Request { + var request = httptest.NewRequest("DELETE", "/api/v1/product/5", nil) + request = request.WithContext(context.WithValue(request.Context(), "productId", "5")) + return request + }(), + }, + wantStatus: http.StatusInternalServerError, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + controller := coalescingController{ + productRepository: tt.fields.productRepository, + } + controller.DeleteProduct(tt.args.writer, tt.args.request) + if tt.args.writer.Code != tt.wantStatus { + t.Errorf("Expected status code %d, got %d", tt.wantStatus, tt.args.writer.Code) + } + }) + } +} + +func TestCoalescingController_GetProductById(t *testing.T) { + type fields struct { + productRepository Repository + } + type args struct { + writer *httptest.ResponseRecorder + request *http.Request + } + tests := []struct { + name string + fields fields + args args + wantStatus int + }{ + { + name: "Bad non-numeric request (expect 400)", + fields: fields{ + productRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: func() *http.Request { + var request = httptest.NewRequest("GET", "/api/v1/product/abc", nil) + request = request.WithContext(context.WithValue(request.Context(), "productId", "abc")) + return request + }(), + }, + wantStatus: http.StatusBadRequest, + }, + { + name: "Unknown product (expect 404)", + fields: fields{ + productRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: func() *http.Request { + var request = httptest.NewRequest("GET", "/api/v1/product/4", nil) + request = request.WithContext(context.WithValue(request.Context(), "productId", "4")) + return request + }(), + }, + wantStatus: http.StatusNotFound, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + controller := NewCoalescingController(tt.fields.productRepository) + controller.GetProductById(tt.args.writer, tt.args.request) + if tt.args.writer.Code != tt.wantStatus { + t.Errorf("Expected status code %d, got %d", tt.wantStatus, tt.args.writer.Code) + } + }) + } + + t.Run("Successfully get existing product (expect 200 and product)", func(t *testing.T) { + writer := httptest.NewRecorder() + request := httptest.NewRequest("GET", "/api/v1/product/1", nil) + request = request.WithContext(context.WithValue(request.Context(), "productId", "1")) + + controller := NewCoalescingController(GenerateExampleDemoRepository()) + + // when + controller.GetProductById(writer, request) + + // then + if writer.Code != http.StatusOK { + t.Errorf("Expected status code %d, got %d", http.StatusOK, writer.Code) + } + + if writer.Header().Get("Content-Type") != "application/json" { + t.Errorf("Expected content type %s, got %s", + "application/json", writer.Header().Get("Content-Type")) + } + + result := writer.Result() + var response model.Product + err := json.NewDecoder(result.Body).Decode(&response) + if err != nil { + t.Fatal(err.Error()) + } + + if response.Id != 1 { + t.Errorf("Expected id of product %d, got %d", 1, response.Id) + } + + if response.Description != "Strauchtomaten" { + t.Errorf("Expected description of product %s, got %s", "Strauchtomaten", response.Description) + } + + if response.Ean != 4014819040771 { + t.Errorf("Expected ean of product %d, got %d", 4014819040771, response.Ean) + } + + }) +} + +func TestCoalescingController_GetProductByEan(t *testing.T) { + t.Run("Bad non-numeric request (expect 400)", func(t *testing.T) { + controller := NewCoalescingController(GenerateExampleDemoRepository()) + + writer := httptest.NewRecorder() + request := httptest.NewRequest("GET", "/api/v1/products/ean?ean=abc", nil) + request = request.WithContext(context.WithValue(request.Context(), "productEan", "abc")) + + // Test request + controller.GetProductByEan(writer, request) + + if writer.Code != http.StatusBadRequest { + t.Errorf("Expected status code %d, got %d", http.StatusBadRequest, writer.Code) + } + }) + + t.Run("Unknown product (expect 404)", func(t *testing.T) { + controller := NewCoalescingController(GenerateExampleDemoRepository()) + + writer := httptest.NewRecorder() + request := httptest.NewRequest("GET", "/api/v1/products/ean?ean=123", nil) + request = request.WithContext(context.WithValue(request.Context(), "productEan", "123")) + + // Test request + controller.GetProductByEan(writer, request) + + if writer.Code != http.StatusNotFound { + t.Errorf("Expected status code %d, got %d", http.StatusNotFound, writer.Code) + } + }) + + t.Run("Should return products by EAN", func(t *testing.T) { + controller := NewCoalescingController(GenerateExampleDemoRepository()) + + writer := httptest.NewRecorder() + request := httptest.NewRequest("GET", "/api/v1/products/ean?ean=4014819040771", nil) + request = request.WithContext(context.WithValue(request.Context(), "productEan", "4014819040771")) + + // Test request + controller.GetProductByEan(writer, request) + + if writer.Code != http.StatusOK { + t.Errorf("Expected status code %d, got %d", http.StatusOK, writer.Code) + } + + res := writer.Result() + var response model.Product + err := json.NewDecoder(res.Body).Decode(&response) + + if err != nil { + t.Error(err) + } + + // Add assertions based on your expected response. + // For example, check the length, content, etc. + // ... + + }) +} + +func TestCoalescingController_GetProducts(t *testing.T) { + t.Run("should return all products", func(t *testing.T) { + controller := NewCoalescingController(GenerateExampleDemoRepository()) + + writer := httptest.NewRecorder() + request := httptest.NewRequest("GET", "/api/v1/product", nil) + + // Test request + controller.GetProducts(writer, request) + + res := writer.Result() + var response []model.Product + err := json.NewDecoder(res.Body).Decode(&response) + + if err != nil { + t.Error(err) + } + + if writer.Code != http.StatusOK { + t.Errorf("Expected status code %d, got %d", http.StatusOK, writer.Code) + } + + if writer.Header().Get("Content-Type") != "application/json" { + t.Errorf("Expected content type %s, got %s", + "application/json", writer.Header().Get("Content-Type")) + } + + products := GenerateExampleProductSlice() + + sort.Slice(response, func(i, j int) bool { + return response[i].Id < response[j].Id + }) + + if len(response) != len(products) { + t.Errorf("Expected count of product is %d, got %d", + 2, len(response)) + } + + for i, product := range products { + if product.Id != response[i].Id { + t.Errorf("Expected id of product %d, got %d", product.Id, response[i].Id) + } + + if product.Description != response[i].Description { + t.Errorf("Expected description of product %s, got %s", product.Description, response[i].Description) + } + + if product.Ean != response[i].Ean { + t.Errorf("Expected ean of product %d, got %d", product.Ean, response[i].Ean) + } + } + + }) +} + +func TestCoalescingController_PostProduct(t *testing.T) { + type fields struct { + productRepository Repository + } + type args struct { + writer *httptest.ResponseRecorder + request *http.Request + } + tests := []struct { + name string + fields fields + args args + expectedStatus int + expectedResponse string + }{ + { + name: "Valid Product", + fields: fields{ + productRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: httptest.NewRequest( + "POST", + "/api/v1/product", + strings.NewReader(`{"id": 3, "description": "Test Product", "ean": 12345}`), + ), + }, + expectedStatus: http.StatusOK, + expectedResponse: "", + }, + { + name: "Valid Product (Partly Fields)", + fields: fields{ + productRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: httptest.NewRequest( + "POST", + "/api/v1/product", + strings.NewReader(`{"description": "Incomplete Product"}`), + ), + }, + expectedStatus: http.StatusOK, + expectedResponse: "", + }, + { + name: "Malformed JSON", + fields: fields{ + productRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: httptest.NewRequest( + "POST", + "/api/v1/product", + strings.NewReader(`{"description": "Incomplete Product"`), + ), + }, + expectedStatus: http.StatusBadRequest, + expectedResponse: "", + }, + { + name: "Invalid product, incorrect Type for EAN (Non-numeric)", + fields: fields{ + productRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: httptest.NewRequest( + "POST", + "/api/v1/product", + strings.NewReader(`{"id": 3, "description": "Invalid EAN", "ean": "abc"}`), + ), + }, + expectedStatus: http.StatusBadRequest, + expectedResponse: "", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + controller := coalescingController{ + productRepository: tt.fields.productRepository, + } + controller.PostProduct(tt.args.writer, tt.args.request) + + // You can then assert the response status and content, and check against your expectations. + if tt.args.writer.Code != tt.expectedStatus { + t.Errorf("Expected status code %d, but got %d", tt.expectedStatus, tt.args.writer.Code) + } + + if tt.expectedResponse != "" { + actualResponse := tt.args.writer.Body.String() + if actualResponse != tt.expectedResponse { + t.Errorf("Expected response: %s, but got: %s", tt.expectedResponse, actualResponse) + } + } + }) + } +} + +func TestCoalescingController_PutProduct(t *testing.T) { + type fields struct { + productRepository Repository + } + type args struct { + writer *httptest.ResponseRecorder + request *http.Request + } + + tests := []struct { + name string + fields fields + args args + expectedStatus int + expectedResponse string // If you want to check the response content + }{ + { + name: "Valid Update", + fields: fields{ + productRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: func() *http.Request { + var request = httptest.NewRequest( + "PUT", + "/api/v1/product/1", + strings.NewReader(`{"id": 1, "description": "Updated Product", "ean": 54321}`)) + request = request.WithContext(context.WithValue(request.Context(), "productId", "1")) + return request + }(), + }, + expectedStatus: http.StatusOK, + expectedResponse: "", + }, + { + name: "Valid Update (Partly Fields)", + fields: fields{ + productRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: func() *http.Request { + var request = httptest.NewRequest( + "PUT", + "/api/v1/product/2", + strings.NewReader(`{"description": "Incomplete Update"}`)) + request = request.WithContext(context.WithValue(request.Context(), "productId", "2")) + return request + }(), + }, + expectedStatus: http.StatusOK, + expectedResponse: "", + }, + { + name: "Malformed JSON", + fields: fields{ + productRepository: GenerateExampleDemoRepository(), + }, + args: args{ + writer: httptest.NewRecorder(), + request: func() *http.Request { + var request = httptest.NewRequest( + "PUT", + "/api/v1/product/2", + strings.NewReader(`{"description": "Incomplete Update"`)) + request = request.WithContext(context.WithValue(request.Context(), "productId", "2")) + return request + }(), + }, + expectedStatus: http.StatusBadRequest, + expectedResponse: "", + }, + { + name: "Incorrect Type for EAN (Non-numeric)", + fields: fields{ + // Set up your repository mock or test double here if needed + }, + args: args{ + writer: httptest.NewRecorder(), + request: func() *http.Request { + var request = httptest.NewRequest( + "PUT", + "/api/v1/product/2", + strings.NewReader(`{"ean": "Wrong Type"`)) + request = request.WithContext(context.WithValue(request.Context(), "productId", "2")) + return request + }(), + }, + expectedStatus: http.StatusBadRequest, + expectedResponse: "", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + controller := coalescingController{ + productRepository: tt.fields.productRepository, + } + controller.PutProduct(tt.args.writer, tt.args.request) + + // You can then assert the response status and content, and check against your expectations. + if tt.args.writer.Code != tt.expectedStatus { + t.Errorf("Expected status code %d, but got %d", tt.expectedStatus, tt.args.writer.Code) + } + + if tt.expectedResponse != "" { + actualResponse := tt.args.writer.Body.String() + if actualResponse != tt.expectedResponse { + t.Errorf("Expected response: %s, but got: %s", tt.expectedResponse, actualResponse) + } + } + }) + } +} diff --git a/src/product-service/products/default_controller.go b/src/product-service/products/default_controller.go index 1d133d25..f189cf00 100644 --- a/src/product-service/products/default_controller.go +++ b/src/product-service/products/default_controller.go @@ -15,7 +15,7 @@ func NewDefaultController(productRepository Repository) *defaultController { return &defaultController{productRepository} } -func (controller defaultController) GetProducts(writer http.ResponseWriter, request *http.Request) { +func (controller *defaultController) GetProducts(writer http.ResponseWriter, request *http.Request) { values, err := controller.productRepository.FindAll() if err != nil { http.Error(writer, err.Error(), http.StatusInternalServerError) @@ -29,7 +29,7 @@ func (controller defaultController) GetProducts(writer http.ResponseWriter, requ } } -func (controller defaultController) PostProduct(writer http.ResponseWriter, request *http.Request) { +func (controller *defaultController) PostProduct(writer http.ResponseWriter, request *http.Request) { var requestData JsonFormatCreateProductRequest if err := json.NewDecoder(request.Body).Decode(&requestData); err != nil { writer.WriteHeader(http.StatusBadRequest) @@ -54,7 +54,7 @@ func (controller defaultController) PostProduct(writer http.ResponseWriter, requ } } -func (controller defaultController) GetProductById(writer http.ResponseWriter, request *http.Request) { +func (controller *defaultController) GetProductById(writer http.ResponseWriter, request *http.Request) { productId, err := strconv.ParseUint(request.Context().Value("productId").(string), 10, 64) if err != nil { http.Error(writer, err.Error(), http.StatusBadRequest) @@ -77,7 +77,7 @@ func (controller defaultController) GetProductById(writer http.ResponseWriter, r } } -func (controller defaultController) GetProductByEan(writer http.ResponseWriter, request *http.Request) { +func (controller *defaultController) GetProductByEan(writer http.ResponseWriter, request *http.Request) { productEan, err := strconv.ParseUint(request.Context().Value("productEan").(string), 10, 64) if err != nil { http.Error(writer, err.Error(), http.StatusBadRequest) @@ -101,7 +101,7 @@ func (controller defaultController) GetProductByEan(writer http.ResponseWriter, } } -func (controller defaultController) PutProduct(writer http.ResponseWriter, request *http.Request) { +func (controller *defaultController) PutProduct(writer http.ResponseWriter, request *http.Request) { productId, err := strconv.ParseUint(request.Context().Value("productId").(string), 10, 64) if err != nil { http.Error(writer, err.Error(), http.StatusBadRequest) @@ -124,7 +124,7 @@ func (controller defaultController) PutProduct(writer http.ResponseWriter, reque } } -func (controller defaultController) DeleteProduct(writer http.ResponseWriter, request *http.Request) { +func (controller *defaultController) DeleteProduct(writer http.ResponseWriter, request *http.Request) { productId, err := strconv.ParseUint(request.Context().Value("productId").(string), 10, 64) if err != nil { http.Error(writer, err.Error(), http.StatusBadRequest) diff --git a/src/product-service/products/default_controller_test.go b/src/product-service/products/default_controller_test.go index cacf6e53..ce6355d5 100644 --- a/src/product-service/products/default_controller_test.go +++ b/src/product-service/products/default_controller_test.go @@ -53,7 +53,7 @@ func TestDefaultController_DeleteProduct(t *testing.T) { { name: "Successfully delete existing product (expect 200)", fields: fields{ - productRepository: setupMockRepository(), + productRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), @@ -68,7 +68,7 @@ func TestDefaultController_DeleteProduct(t *testing.T) { { name: "Bad non-numeric request (expect 400)", fields: fields{ - productRepository: setupMockRepository(), + productRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), @@ -83,7 +83,7 @@ func TestDefaultController_DeleteProduct(t *testing.T) { { name: "Unknown product to delete (expect 500)", fields: fields{ - productRepository: setupMockRepository(), + productRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), @@ -126,7 +126,7 @@ func TestDefaultController_GetProductById(t *testing.T) { { name: "Bad non-numeric request (expect 400)", fields: fields{ - productRepository: setupMockRepository(), + productRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), @@ -141,7 +141,7 @@ func TestDefaultController_GetProductById(t *testing.T) { { name: "Unknown product (expect 404)", fields: fields{ - productRepository: setupMockRepository(), + productRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), @@ -172,7 +172,7 @@ func TestDefaultController_GetProductById(t *testing.T) { request = request.WithContext(context.WithValue(request.Context(), "productId", "1")) controller := defaultController{ - productRepository: setupMockRepository(), + productRepository: GenerateExampleDemoRepository(), } // when @@ -213,7 +213,7 @@ func TestDefaultController_GetProductById(t *testing.T) { func TestDefaultController_GetProductByEan(t *testing.T) { t.Run("Bad non-numeric request (expect 400)", func(t *testing.T) { controller := defaultController{ - productRepository: setupMockRepository(), + productRepository: GenerateExampleDemoRepository(), } writer := httptest.NewRecorder() @@ -230,7 +230,7 @@ func TestDefaultController_GetProductByEan(t *testing.T) { t.Run("Unknown product (expect 404)", func(t *testing.T) { controller := defaultController{ - productRepository: setupMockRepository(), + productRepository: GenerateExampleDemoRepository(), } writer := httptest.NewRecorder() @@ -247,7 +247,7 @@ func TestDefaultController_GetProductByEan(t *testing.T) { t.Run("Should return products by EAN", func(t *testing.T) { controller := defaultController{ - productRepository: setupMockRepository(), + productRepository: GenerateExampleDemoRepository(), } writer := httptest.NewRecorder() @@ -279,7 +279,7 @@ func TestDefaultController_GetProductByEan(t *testing.T) { func TestDefaultController_GetProducts(t *testing.T) { t.Run("should return all products", func(t *testing.T) { controller := defaultController{ - productRepository: setupMockRepository(), + productRepository: GenerateExampleDemoRepository(), } writer := httptest.NewRecorder() @@ -305,7 +305,7 @@ func TestDefaultController_GetProducts(t *testing.T) { "application/json", writer.Header().Get("Content-Type")) } - products := setupDemoProductSlice() + products := GenerateExampleProductSlice() sort.Slice(response, func(i, j int) bool { return response[i].Id < response[j].Id @@ -351,7 +351,7 @@ func TestDefaultController_PostProduct(t *testing.T) { { name: "Valid Product", fields: fields{ - productRepository: setupMockRepository(), + productRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), @@ -367,7 +367,7 @@ func TestDefaultController_PostProduct(t *testing.T) { { name: "Valid Product (Partly Fields)", fields: fields{ - productRepository: setupMockRepository(), + productRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), @@ -383,7 +383,7 @@ func TestDefaultController_PostProduct(t *testing.T) { { name: "Malformed JSON", fields: fields{ - productRepository: setupMockRepository(), + productRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), @@ -399,7 +399,7 @@ func TestDefaultController_PostProduct(t *testing.T) { { name: "Invalid product, incorrect Type for EAN (Non-numeric)", fields: fields{ - productRepository: setupMockRepository(), + productRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), @@ -455,7 +455,7 @@ func TestDefaultController_PutProduct(t *testing.T) { { name: "Valid Update", fields: fields{ - productRepository: setupMockRepository(), + productRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), @@ -474,7 +474,7 @@ func TestDefaultController_PutProduct(t *testing.T) { { name: "Valid Update (Partly Fields)", fields: fields{ - productRepository: setupMockRepository(), + productRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), @@ -493,7 +493,7 @@ func TestDefaultController_PutProduct(t *testing.T) { { name: "Malformed JSON", fields: fields{ - productRepository: setupMockRepository(), + productRepository: GenerateExampleDemoRepository(), }, args: args{ writer: httptest.NewRecorder(), @@ -551,28 +551,3 @@ func TestDefaultController_PutProduct(t *testing.T) { }) } } - -func setupMockRepository() Repository { - repository := NewDemoRepository() - productSlice := setupDemoProductSlice() - for _, product := range productSlice { - repository.Create(product) - } - - return repository -} - -func setupDemoProductSlice() []*model.Product { - return []*model.Product{ - { - Id: 1, - Description: "Strauchtomaten", - Ean: 4014819040771, - }, - { - Id: 2, - Description: "Lauchzwiebeln", - Ean: 5001819040871, - }, - } -} diff --git a/src/product-service/products/demo_repository_example.go b/src/product-service/products/demo_repository_example.go new file mode 100644 index 00000000..7a9e88ca --- /dev/null +++ b/src/product-service/products/demo_repository_example.go @@ -0,0 +1,28 @@ +package products + +import "hsfl.de/group6/hsfl-master-ai-cloud-engineering/product-service/products/model" + +func GenerateExampleDemoRepository() Repository { + repository := NewDemoRepository() + productSlice := GenerateExampleProductSlice() + for _, product := range productSlice { + repository.Create(product) + } + + return repository +} + +func GenerateExampleProductSlice() []*model.Product { + return []*model.Product{ + { + Id: 1, + Description: "Strauchtomaten", + Ean: 4014819040771, + }, + { + Id: 2, + Description: "Lauchzwiebeln", + Ean: 5001819040871, + }, + } +} diff --git a/src/shoppinglist-service/Dockerfile b/src/shoppinglist-service/Dockerfile index 2a7fe738..b6551081 100644 --- a/src/shoppinglist-service/Dockerfile +++ b/src/shoppinglist-service/Dockerfile @@ -1,4 +1,7 @@ FROM golang:1.21-alpine +RUN apk update && apk add --no-cache make protobuf-dev +RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@latest +RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest WORKDIR /app COPY ./lib ./lib @@ -6,6 +9,7 @@ COPY ./src/shoppinglist-service ./src/shoppinglist-service WORKDIR /app/src/shoppinglist-service RUN go mod tidy +RUN go generate RUN go build -o ./main EXPOSE 3002 diff --git a/src/shoppinglist-service/internal/proto/shoppinglist/shoppinglist.pb.go b/src/shoppinglist-service/internal/proto/shoppinglist/shoppinglist.pb.go new file mode 100644 index 00000000..75f5ce97 --- /dev/null +++ b/src/shoppinglist-service/internal/proto/shoppinglist/shoppinglist.pb.go @@ -0,0 +1,1717 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v4.25.1 +// source: shoppinglist/shoppinglist.proto + +package proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type UserShoppingList struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + UserId uint64 `protobuf:"varint,2,opt,name=userId,proto3" json:"userId,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + Completed bool `protobuf:"varint,4,opt,name=completed,proto3" json:"completed,omitempty"` +} + +func (x *UserShoppingList) Reset() { + *x = UserShoppingList{} + if protoimpl.UnsafeEnabled { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UserShoppingList) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UserShoppingList) ProtoMessage() {} + +func (x *UserShoppingList) ProtoReflect() protoreflect.Message { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UserShoppingList.ProtoReflect.Descriptor instead. +func (*UserShoppingList) Descriptor() ([]byte, []int) { + return file_shoppinglist_shoppinglist_proto_rawDescGZIP(), []int{0} +} + +func (x *UserShoppingList) GetId() uint64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *UserShoppingList) GetUserId() uint64 { + if x != nil { + return x.UserId + } + return 0 +} + +func (x *UserShoppingList) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *UserShoppingList) GetCompleted() bool { + if x != nil { + return x.Completed + } + return false +} + +type UserShoppingListEntry struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ShoppingListId uint64 `protobuf:"varint,1,opt,name=shoppingListId,proto3" json:"shoppingListId,omitempty"` + ProductId uint64 `protobuf:"varint,2,opt,name=productId,proto3" json:"productId,omitempty"` + Count uint64 `protobuf:"varint,3,opt,name=count,proto3" json:"count,omitempty"` + Note string `protobuf:"bytes,4,opt,name=note,proto3" json:"note,omitempty"` + Checked bool `protobuf:"varint,5,opt,name=checked,proto3" json:"checked,omitempty"` +} + +func (x *UserShoppingListEntry) Reset() { + *x = UserShoppingListEntry{} + if protoimpl.UnsafeEnabled { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UserShoppingListEntry) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UserShoppingListEntry) ProtoMessage() {} + +func (x *UserShoppingListEntry) ProtoReflect() protoreflect.Message { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UserShoppingListEntry.ProtoReflect.Descriptor instead. +func (*UserShoppingListEntry) Descriptor() ([]byte, []int) { + return file_shoppinglist_shoppinglist_proto_rawDescGZIP(), []int{1} +} + +func (x *UserShoppingListEntry) GetShoppingListId() uint64 { + if x != nil { + return x.ShoppingListId + } + return 0 +} + +func (x *UserShoppingListEntry) GetProductId() uint64 { + if x != nil { + return x.ProductId + } + return 0 +} + +func (x *UserShoppingListEntry) GetCount() uint64 { + if x != nil { + return x.Count + } + return 0 +} + +func (x *UserShoppingListEntry) GetNote() string { + if x != nil { + return x.Note + } + return "" +} + +func (x *UserShoppingListEntry) GetChecked() bool { + if x != nil { + return x.Checked + } + return false +} + +// Request- and Response-Messages for CreateUserShoppingList +type CreateUserShoppingListRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserShoppingList *UserShoppingList `protobuf:"bytes,1,opt,name=userShoppingList,proto3" json:"userShoppingList,omitempty"` +} + +func (x *CreateUserShoppingListRequest) Reset() { + *x = CreateUserShoppingListRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateUserShoppingListRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateUserShoppingListRequest) ProtoMessage() {} + +func (x *CreateUserShoppingListRequest) ProtoReflect() protoreflect.Message { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateUserShoppingListRequest.ProtoReflect.Descriptor instead. +func (*CreateUserShoppingListRequest) Descriptor() ([]byte, []int) { + return file_shoppinglist_shoppinglist_proto_rawDescGZIP(), []int{2} +} + +func (x *CreateUserShoppingListRequest) GetUserShoppingList() *UserShoppingList { + if x != nil { + return x.UserShoppingList + } + return nil +} + +type CreateUserShoppingListResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserShoppingList *UserShoppingList `protobuf:"bytes,1,opt,name=userShoppingList,proto3" json:"userShoppingList,omitempty"` +} + +func (x *CreateUserShoppingListResponse) Reset() { + *x = CreateUserShoppingListResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateUserShoppingListResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateUserShoppingListResponse) ProtoMessage() {} + +func (x *CreateUserShoppingListResponse) ProtoReflect() protoreflect.Message { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateUserShoppingListResponse.ProtoReflect.Descriptor instead. +func (*CreateUserShoppingListResponse) Descriptor() ([]byte, []int) { + return file_shoppinglist_shoppinglist_proto_rawDescGZIP(), []int{3} +} + +func (x *CreateUserShoppingListResponse) GetUserShoppingList() *UserShoppingList { + if x != nil { + return x.UserShoppingList + } + return nil +} + +// Request- and Response-Messages for GetUserShoppingList +type GetUserShoppingListRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id uint64 `protobuf:"varint,1,opt,name=Id,proto3" json:"Id,omitempty"` +} + +func (x *GetUserShoppingListRequest) Reset() { + *x = GetUserShoppingListRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetUserShoppingListRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserShoppingListRequest) ProtoMessage() {} + +func (x *GetUserShoppingListRequest) ProtoReflect() protoreflect.Message { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetUserShoppingListRequest.ProtoReflect.Descriptor instead. +func (*GetUserShoppingListRequest) Descriptor() ([]byte, []int) { + return file_shoppinglist_shoppinglist_proto_rawDescGZIP(), []int{4} +} + +func (x *GetUserShoppingListRequest) GetId() uint64 { + if x != nil { + return x.Id + } + return 0 +} + +type GetUserShoppingListResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserShoppingList *UserShoppingList `protobuf:"bytes,1,opt,name=userShoppingList,proto3" json:"userShoppingList,omitempty"` +} + +func (x *GetUserShoppingListResponse) Reset() { + *x = GetUserShoppingListResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetUserShoppingListResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserShoppingListResponse) ProtoMessage() {} + +func (x *GetUserShoppingListResponse) ProtoReflect() protoreflect.Message { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetUserShoppingListResponse.ProtoReflect.Descriptor instead. +func (*GetUserShoppingListResponse) Descriptor() ([]byte, []int) { + return file_shoppinglist_shoppinglist_proto_rawDescGZIP(), []int{5} +} + +func (x *GetUserShoppingListResponse) GetUserShoppingList() *UserShoppingList { + if x != nil { + return x.UserShoppingList + } + return nil +} + +// Request- and Response-Messages for ListProducts +type GetAllUserShoppingListsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserId uint64 `protobuf:"varint,1,opt,name=userId,proto3" json:"userId,omitempty"` +} + +func (x *GetAllUserShoppingListsRequest) Reset() { + *x = GetAllUserShoppingListsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllUserShoppingListsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllUserShoppingListsRequest) ProtoMessage() {} + +func (x *GetAllUserShoppingListsRequest) ProtoReflect() protoreflect.Message { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllUserShoppingListsRequest.ProtoReflect.Descriptor instead. +func (*GetAllUserShoppingListsRequest) Descriptor() ([]byte, []int) { + return file_shoppinglist_shoppinglist_proto_rawDescGZIP(), []int{6} +} + +func (x *GetAllUserShoppingListsRequest) GetUserId() uint64 { + if x != nil { + return x.UserId + } + return 0 +} + +type GetAllUserShoppingListsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserShoppingList []*UserShoppingList `protobuf:"bytes,1,rep,name=userShoppingList,proto3" json:"userShoppingList,omitempty"` +} + +func (x *GetAllUserShoppingListsResponse) Reset() { + *x = GetAllUserShoppingListsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllUserShoppingListsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllUserShoppingListsResponse) ProtoMessage() {} + +func (x *GetAllUserShoppingListsResponse) ProtoReflect() protoreflect.Message { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllUserShoppingListsResponse.ProtoReflect.Descriptor instead. +func (*GetAllUserShoppingListsResponse) Descriptor() ([]byte, []int) { + return file_shoppinglist_shoppinglist_proto_rawDescGZIP(), []int{7} +} + +func (x *GetAllUserShoppingListsResponse) GetUserShoppingList() []*UserShoppingList { + if x != nil { + return x.UserShoppingList + } + return nil +} + +// Request- and Response-Messages for UpdateUserShoppingList +type UpdateUserShoppingListRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserShoppingList *UserShoppingList `protobuf:"bytes,1,opt,name=userShoppingList,proto3" json:"userShoppingList,omitempty"` +} + +func (x *UpdateUserShoppingListRequest) Reset() { + *x = UpdateUserShoppingListRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateUserShoppingListRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateUserShoppingListRequest) ProtoMessage() {} + +func (x *UpdateUserShoppingListRequest) ProtoReflect() protoreflect.Message { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateUserShoppingListRequest.ProtoReflect.Descriptor instead. +func (*UpdateUserShoppingListRequest) Descriptor() ([]byte, []int) { + return file_shoppinglist_shoppinglist_proto_rawDescGZIP(), []int{8} +} + +func (x *UpdateUserShoppingListRequest) GetUserShoppingList() *UserShoppingList { + if x != nil { + return x.UserShoppingList + } + return nil +} + +type UpdateUserShoppingListResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserShoppingList *UserShoppingList `protobuf:"bytes,1,opt,name=userShoppingList,proto3" json:"userShoppingList,omitempty"` +} + +func (x *UpdateUserShoppingListResponse) Reset() { + *x = UpdateUserShoppingListResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateUserShoppingListResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateUserShoppingListResponse) ProtoMessage() {} + +func (x *UpdateUserShoppingListResponse) ProtoReflect() protoreflect.Message { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateUserShoppingListResponse.ProtoReflect.Descriptor instead. +func (*UpdateUserShoppingListResponse) Descriptor() ([]byte, []int) { + return file_shoppinglist_shoppinglist_proto_rawDescGZIP(), []int{9} +} + +func (x *UpdateUserShoppingListResponse) GetUserShoppingList() *UserShoppingList { + if x != nil { + return x.UserShoppingList + } + return nil +} + +// Request- and Response-Messages for DeleteUserShoppingList +type DeleteUserShoppingListRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *DeleteUserShoppingListRequest) Reset() { + *x = DeleteUserShoppingListRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteUserShoppingListRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteUserShoppingListRequest) ProtoMessage() {} + +func (x *DeleteUserShoppingListRequest) ProtoReflect() protoreflect.Message { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteUserShoppingListRequest.ProtoReflect.Descriptor instead. +func (*DeleteUserShoppingListRequest) Descriptor() ([]byte, []int) { + return file_shoppinglist_shoppinglist_proto_rawDescGZIP(), []int{10} +} + +func (x *DeleteUserShoppingListRequest) GetId() uint64 { + if x != nil { + return x.Id + } + return 0 +} + +type DeleteUserShoppingListResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeleteUserShoppingListResponse) Reset() { + *x = DeleteUserShoppingListResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteUserShoppingListResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteUserShoppingListResponse) ProtoMessage() {} + +func (x *DeleteUserShoppingListResponse) ProtoReflect() protoreflect.Message { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteUserShoppingListResponse.ProtoReflect.Descriptor instead. +func (*DeleteUserShoppingListResponse) Descriptor() ([]byte, []int) { + return file_shoppinglist_shoppinglist_proto_rawDescGZIP(), []int{11} +} + +// Request- and Response-Messages for CreateUserShoppingListEntry +type CreateUserShoppingListEntryRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserShoppingListEntry *UserShoppingListEntry `protobuf:"bytes,1,opt,name=userShoppingListEntry,proto3" json:"userShoppingListEntry,omitempty"` +} + +func (x *CreateUserShoppingListEntryRequest) Reset() { + *x = CreateUserShoppingListEntryRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateUserShoppingListEntryRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateUserShoppingListEntryRequest) ProtoMessage() {} + +func (x *CreateUserShoppingListEntryRequest) ProtoReflect() protoreflect.Message { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateUserShoppingListEntryRequest.ProtoReflect.Descriptor instead. +func (*CreateUserShoppingListEntryRequest) Descriptor() ([]byte, []int) { + return file_shoppinglist_shoppinglist_proto_rawDescGZIP(), []int{12} +} + +func (x *CreateUserShoppingListEntryRequest) GetUserShoppingListEntry() *UserShoppingListEntry { + if x != nil { + return x.UserShoppingListEntry + } + return nil +} + +type CreateUserShoppingListEntryResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserShoppingListEntry *UserShoppingListEntry `protobuf:"bytes,1,opt,name=userShoppingListEntry,proto3" json:"userShoppingListEntry,omitempty"` +} + +func (x *CreateUserShoppingListEntryResponse) Reset() { + *x = CreateUserShoppingListEntryResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateUserShoppingListEntryResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateUserShoppingListEntryResponse) ProtoMessage() {} + +func (x *CreateUserShoppingListEntryResponse) ProtoReflect() protoreflect.Message { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateUserShoppingListEntryResponse.ProtoReflect.Descriptor instead. +func (*CreateUserShoppingListEntryResponse) Descriptor() ([]byte, []int) { + return file_shoppinglist_shoppinglist_proto_rawDescGZIP(), []int{13} +} + +func (x *CreateUserShoppingListEntryResponse) GetUserShoppingListEntry() *UserShoppingListEntry { + if x != nil { + return x.UserShoppingListEntry + } + return nil +} + +// Request- and Response-Messages for GetUserShoppingListEntry +type GetUserShoppingListEntryRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ShoppingListId uint64 `protobuf:"varint,1,opt,name=shoppingListId,proto3" json:"shoppingListId,omitempty"` + ProductId uint64 `protobuf:"varint,2,opt,name=productId,proto3" json:"productId,omitempty"` +} + +func (x *GetUserShoppingListEntryRequest) Reset() { + *x = GetUserShoppingListEntryRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetUserShoppingListEntryRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserShoppingListEntryRequest) ProtoMessage() {} + +func (x *GetUserShoppingListEntryRequest) ProtoReflect() protoreflect.Message { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetUserShoppingListEntryRequest.ProtoReflect.Descriptor instead. +func (*GetUserShoppingListEntryRequest) Descriptor() ([]byte, []int) { + return file_shoppinglist_shoppinglist_proto_rawDescGZIP(), []int{14} +} + +func (x *GetUserShoppingListEntryRequest) GetShoppingListId() uint64 { + if x != nil { + return x.ShoppingListId + } + return 0 +} + +func (x *GetUserShoppingListEntryRequest) GetProductId() uint64 { + if x != nil { + return x.ProductId + } + return 0 +} + +type GetUserShoppingListEntryResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserShoppingListEntry *UserShoppingListEntry `protobuf:"bytes,1,opt,name=userShoppingListEntry,proto3" json:"userShoppingListEntry,omitempty"` +} + +func (x *GetUserShoppingListEntryResponse) Reset() { + *x = GetUserShoppingListEntryResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetUserShoppingListEntryResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserShoppingListEntryResponse) ProtoMessage() {} + +func (x *GetUserShoppingListEntryResponse) ProtoReflect() protoreflect.Message { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetUserShoppingListEntryResponse.ProtoReflect.Descriptor instead. +func (*GetUserShoppingListEntryResponse) Descriptor() ([]byte, []int) { + return file_shoppinglist_shoppinglist_proto_rawDescGZIP(), []int{15} +} + +func (x *GetUserShoppingListEntryResponse) GetUserShoppingListEntry() *UserShoppingListEntry { + if x != nil { + return x.UserShoppingListEntry + } + return nil +} + +// Request- and Response-Messages for GetAllUserShoppingListEntries +type GetAllUserShoppingListEntriesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *GetAllUserShoppingListEntriesRequest) Reset() { + *x = GetAllUserShoppingListEntriesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllUserShoppingListEntriesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllUserShoppingListEntriesRequest) ProtoMessage() {} + +func (x *GetAllUserShoppingListEntriesRequest) ProtoReflect() protoreflect.Message { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllUserShoppingListEntriesRequest.ProtoReflect.Descriptor instead. +func (*GetAllUserShoppingListEntriesRequest) Descriptor() ([]byte, []int) { + return file_shoppinglist_shoppinglist_proto_rawDescGZIP(), []int{16} +} + +func (x *GetAllUserShoppingListEntriesRequest) GetId() uint64 { + if x != nil { + return x.Id + } + return 0 +} + +type GetAllUserShoppingListEntriesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserShoppingListEntries []*UserShoppingListEntry `protobuf:"bytes,1,rep,name=userShoppingListEntries,proto3" json:"userShoppingListEntries,omitempty"` +} + +func (x *GetAllUserShoppingListEntriesResponse) Reset() { + *x = GetAllUserShoppingListEntriesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllUserShoppingListEntriesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllUserShoppingListEntriesResponse) ProtoMessage() {} + +func (x *GetAllUserShoppingListEntriesResponse) ProtoReflect() protoreflect.Message { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllUserShoppingListEntriesResponse.ProtoReflect.Descriptor instead. +func (*GetAllUserShoppingListEntriesResponse) Descriptor() ([]byte, []int) { + return file_shoppinglist_shoppinglist_proto_rawDescGZIP(), []int{17} +} + +func (x *GetAllUserShoppingListEntriesResponse) GetUserShoppingListEntries() []*UserShoppingListEntry { + if x != nil { + return x.UserShoppingListEntries + } + return nil +} + +// Request- and Response-Messages for UpdateUserShoppingList +type UpdateUserShoppingListEntryRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserShoppingListEntry *UserShoppingListEntry `protobuf:"bytes,1,opt,name=userShoppingListEntry,proto3" json:"userShoppingListEntry,omitempty"` +} + +func (x *UpdateUserShoppingListEntryRequest) Reset() { + *x = UpdateUserShoppingListEntryRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateUserShoppingListEntryRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateUserShoppingListEntryRequest) ProtoMessage() {} + +func (x *UpdateUserShoppingListEntryRequest) ProtoReflect() protoreflect.Message { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateUserShoppingListEntryRequest.ProtoReflect.Descriptor instead. +func (*UpdateUserShoppingListEntryRequest) Descriptor() ([]byte, []int) { + return file_shoppinglist_shoppinglist_proto_rawDescGZIP(), []int{18} +} + +func (x *UpdateUserShoppingListEntryRequest) GetUserShoppingListEntry() *UserShoppingListEntry { + if x != nil { + return x.UserShoppingListEntry + } + return nil +} + +type UpdateUserShoppingListEntryResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserShoppingListEntry *UserShoppingListEntry `protobuf:"bytes,1,opt,name=userShoppingListEntry,proto3" json:"userShoppingListEntry,omitempty"` +} + +func (x *UpdateUserShoppingListEntryResponse) Reset() { + *x = UpdateUserShoppingListEntryResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateUserShoppingListEntryResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateUserShoppingListEntryResponse) ProtoMessage() {} + +func (x *UpdateUserShoppingListEntryResponse) ProtoReflect() protoreflect.Message { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateUserShoppingListEntryResponse.ProtoReflect.Descriptor instead. +func (*UpdateUserShoppingListEntryResponse) Descriptor() ([]byte, []int) { + return file_shoppinglist_shoppinglist_proto_rawDescGZIP(), []int{19} +} + +func (x *UpdateUserShoppingListEntryResponse) GetUserShoppingListEntry() *UserShoppingListEntry { + if x != nil { + return x.UserShoppingListEntry + } + return nil +} + +// Request- and Response-Messages for DeleteUserShoppingList +type DeleteUserShoppingListEntryRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ShoppingListId uint64 `protobuf:"varint,1,opt,name=shoppingListId,proto3" json:"shoppingListId,omitempty"` + ProductId uint64 `protobuf:"varint,2,opt,name=productId,proto3" json:"productId,omitempty"` +} + +func (x *DeleteUserShoppingListEntryRequest) Reset() { + *x = DeleteUserShoppingListEntryRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteUserShoppingListEntryRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteUserShoppingListEntryRequest) ProtoMessage() {} + +func (x *DeleteUserShoppingListEntryRequest) ProtoReflect() protoreflect.Message { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteUserShoppingListEntryRequest.ProtoReflect.Descriptor instead. +func (*DeleteUserShoppingListEntryRequest) Descriptor() ([]byte, []int) { + return file_shoppinglist_shoppinglist_proto_rawDescGZIP(), []int{20} +} + +func (x *DeleteUserShoppingListEntryRequest) GetShoppingListId() uint64 { + if x != nil { + return x.ShoppingListId + } + return 0 +} + +func (x *DeleteUserShoppingListEntryRequest) GetProductId() uint64 { + if x != nil { + return x.ProductId + } + return 0 +} + +type DeleteUserShoppingListEntryResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeleteUserShoppingListEntryResponse) Reset() { + *x = DeleteUserShoppingListEntryResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteUserShoppingListEntryResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteUserShoppingListEntryResponse) ProtoMessage() {} + +func (x *DeleteUserShoppingListEntryResponse) ProtoReflect() protoreflect.Message { + mi := &file_shoppinglist_shoppinglist_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteUserShoppingListEntryResponse.ProtoReflect.Descriptor instead. +func (*DeleteUserShoppingListEntryResponse) Descriptor() ([]byte, []int) { + return file_shoppinglist_shoppinglist_proto_rawDescGZIP(), []int{21} +} + +var File_shoppinglist_shoppinglist_proto protoreflect.FileDescriptor + +var file_shoppinglist_shoppinglist_proto_rawDesc = []byte{ + 0x0a, 0x1f, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2f, 0x73, + 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x0c, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x22, + 0x7a, 0x0a, 0x10, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, + 0x69, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, + 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0xa1, 0x01, 0x0a, 0x15, + 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x73, + 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, + 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x22, + 0x6b, 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x4a, 0x0a, 0x10, 0x75, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, + 0x4c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x68, 0x6f, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, + 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x10, 0x75, 0x73, 0x65, 0x72, + 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x6c, 0x0a, 0x1e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, + 0x0a, 0x10, 0x75, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, + 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, + 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x10, 0x75, 0x73, 0x65, 0x72, 0x53, 0x68, + 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x2c, 0x0a, 0x1a, 0x47, 0x65, + 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x49, 0x64, 0x22, 0x69, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x55, + 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x10, 0x75, 0x73, 0x65, 0x72, 0x53, + 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, + 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x10, 0x75, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, + 0x69, 0x73, 0x74, 0x22, 0x38, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x55, 0x73, 0x65, + 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x6d, 0x0a, + 0x1f, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x4a, 0x0a, 0x10, 0x75, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, + 0x4c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x68, 0x6f, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, + 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x10, 0x75, 0x73, 0x65, 0x72, + 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x6b, 0x0a, 0x1d, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4a, 0x0a, + 0x10, 0x75, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x10, 0x75, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x6c, 0x0a, 0x1e, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, + 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x10, 0x75, + 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, + 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x10, 0x75, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x2f, 0x0a, 0x1d, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x22, 0x20, 0x0a, 0x1e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, + 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7f, 0x0a, 0x22, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, + 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x59, 0x0a, 0x15, 0x75, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, + 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x23, 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x55, + 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x15, 0x75, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x80, 0x01, 0x0a, 0x23, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x15, 0x75, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, + 0x74, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, + 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x15, 0x75, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x67, + 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, + 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x73, 0x68, 0x6f, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x70, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x22, 0x7d, 0x0a, 0x20, 0x47, 0x65, 0x74, 0x55, 0x73, + 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x15, 0x75, + 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x68, 0x6f, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, + 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x15, 0x75, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, + 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x36, 0x0a, 0x24, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, + 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, + 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x22, 0x86, + 0x01, 0x0a, 0x25, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x17, 0x75, 0x73, 0x65, 0x72, + 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, + 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x68, 0x6f, 0x70, + 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x17, + 0x75, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, + 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0x7f, 0x0a, 0x22, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, + 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x59, 0x0a, + 0x15, 0x75, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, + 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, + 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x55, 0x73, 0x65, 0x72, + 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x15, 0x75, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, + 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x80, 0x01, 0x0a, 0x23, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, + 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x59, 0x0a, 0x15, 0x75, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, + 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x23, 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x55, + 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x15, 0x75, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x6a, 0x0a, 0x22, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, + 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x73, 0x68, 0x6f, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x70, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x22, 0x25, 0x0a, 0x23, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, + 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xdc, + 0x04, 0x0a, 0x17, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, + 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x73, 0x0a, 0x16, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, + 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2b, 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, + 0x69, 0x73, 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, + 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2c, 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, + 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x6a, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x28, 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x29, 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, + 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, + 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x17, 0x47, + 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x12, 0x2c, 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x55, 0x73, 0x65, 0x72, + 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, + 0x69, 0x73, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, + 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x73, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, + 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2b, 0x2e, + 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, + 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x73, 0x68, 0x6f, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x73, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, + 0x73, 0x74, 0x12, 0x2b, 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, + 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, + 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2c, 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xb3, 0x05, + 0x0a, 0x1c, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, + 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x82, + 0x01, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x30, + 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, + 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x31, 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x79, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, + 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x2d, 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x47, + 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, + 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, + 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x47, 0x65, + 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, + 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x88, + 0x01, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, + 0x12, 0x32, 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, + 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, + 0x69, 0x73, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, + 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x1b, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, + 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x30, 0x2e, 0x73, 0x68, 0x6f, 0x70, + 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, + 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x73, 0x68, + 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, + 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x82, + 0x01, 0x0a, 0x1b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x30, + 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, + 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x31, 0x2e, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x74, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x42, 0x12, 0x5a, 0x10, 0x2e, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_shoppinglist_shoppinglist_proto_rawDescOnce sync.Once + file_shoppinglist_shoppinglist_proto_rawDescData = file_shoppinglist_shoppinglist_proto_rawDesc +) + +func file_shoppinglist_shoppinglist_proto_rawDescGZIP() []byte { + file_shoppinglist_shoppinglist_proto_rawDescOnce.Do(func() { + file_shoppinglist_shoppinglist_proto_rawDescData = protoimpl.X.CompressGZIP(file_shoppinglist_shoppinglist_proto_rawDescData) + }) + return file_shoppinglist_shoppinglist_proto_rawDescData +} + +var file_shoppinglist_shoppinglist_proto_msgTypes = make([]protoimpl.MessageInfo, 22) +var file_shoppinglist_shoppinglist_proto_goTypes = []interface{}{ + (*UserShoppingList)(nil), // 0: shoppinglist.UserShoppingList + (*UserShoppingListEntry)(nil), // 1: shoppinglist.UserShoppingListEntry + (*CreateUserShoppingListRequest)(nil), // 2: shoppinglist.CreateUserShoppingListRequest + (*CreateUserShoppingListResponse)(nil), // 3: shoppinglist.CreateUserShoppingListResponse + (*GetUserShoppingListRequest)(nil), // 4: shoppinglist.GetUserShoppingListRequest + (*GetUserShoppingListResponse)(nil), // 5: shoppinglist.GetUserShoppingListResponse + (*GetAllUserShoppingListsRequest)(nil), // 6: shoppinglist.GetAllUserShoppingListsRequest + (*GetAllUserShoppingListsResponse)(nil), // 7: shoppinglist.GetAllUserShoppingListsResponse + (*UpdateUserShoppingListRequest)(nil), // 8: shoppinglist.UpdateUserShoppingListRequest + (*UpdateUserShoppingListResponse)(nil), // 9: shoppinglist.UpdateUserShoppingListResponse + (*DeleteUserShoppingListRequest)(nil), // 10: shoppinglist.DeleteUserShoppingListRequest + (*DeleteUserShoppingListResponse)(nil), // 11: shoppinglist.DeleteUserShoppingListResponse + (*CreateUserShoppingListEntryRequest)(nil), // 12: shoppinglist.CreateUserShoppingListEntryRequest + (*CreateUserShoppingListEntryResponse)(nil), // 13: shoppinglist.CreateUserShoppingListEntryResponse + (*GetUserShoppingListEntryRequest)(nil), // 14: shoppinglist.GetUserShoppingListEntryRequest + (*GetUserShoppingListEntryResponse)(nil), // 15: shoppinglist.GetUserShoppingListEntryResponse + (*GetAllUserShoppingListEntriesRequest)(nil), // 16: shoppinglist.GetAllUserShoppingListEntriesRequest + (*GetAllUserShoppingListEntriesResponse)(nil), // 17: shoppinglist.GetAllUserShoppingListEntriesResponse + (*UpdateUserShoppingListEntryRequest)(nil), // 18: shoppinglist.UpdateUserShoppingListEntryRequest + (*UpdateUserShoppingListEntryResponse)(nil), // 19: shoppinglist.UpdateUserShoppingListEntryResponse + (*DeleteUserShoppingListEntryRequest)(nil), // 20: shoppinglist.DeleteUserShoppingListEntryRequest + (*DeleteUserShoppingListEntryResponse)(nil), // 21: shoppinglist.DeleteUserShoppingListEntryResponse +} +var file_shoppinglist_shoppinglist_proto_depIdxs = []int32{ + 0, // 0: shoppinglist.CreateUserShoppingListRequest.userShoppingList:type_name -> shoppinglist.UserShoppingList + 0, // 1: shoppinglist.CreateUserShoppingListResponse.userShoppingList:type_name -> shoppinglist.UserShoppingList + 0, // 2: shoppinglist.GetUserShoppingListResponse.userShoppingList:type_name -> shoppinglist.UserShoppingList + 0, // 3: shoppinglist.GetAllUserShoppingListsResponse.userShoppingList:type_name -> shoppinglist.UserShoppingList + 0, // 4: shoppinglist.UpdateUserShoppingListRequest.userShoppingList:type_name -> shoppinglist.UserShoppingList + 0, // 5: shoppinglist.UpdateUserShoppingListResponse.userShoppingList:type_name -> shoppinglist.UserShoppingList + 1, // 6: shoppinglist.CreateUserShoppingListEntryRequest.userShoppingListEntry:type_name -> shoppinglist.UserShoppingListEntry + 1, // 7: shoppinglist.CreateUserShoppingListEntryResponse.userShoppingListEntry:type_name -> shoppinglist.UserShoppingListEntry + 1, // 8: shoppinglist.GetUserShoppingListEntryResponse.userShoppingListEntry:type_name -> shoppinglist.UserShoppingListEntry + 1, // 9: shoppinglist.GetAllUserShoppingListEntriesResponse.userShoppingListEntries:type_name -> shoppinglist.UserShoppingListEntry + 1, // 10: shoppinglist.UpdateUserShoppingListEntryRequest.userShoppingListEntry:type_name -> shoppinglist.UserShoppingListEntry + 1, // 11: shoppinglist.UpdateUserShoppingListEntryResponse.userShoppingListEntry:type_name -> shoppinglist.UserShoppingListEntry + 2, // 12: shoppinglist.UserShoppingListService.CreateUserShoppingList:input_type -> shoppinglist.CreateUserShoppingListRequest + 4, // 13: shoppinglist.UserShoppingListService.GetUserShoppingList:input_type -> shoppinglist.GetUserShoppingListRequest + 6, // 14: shoppinglist.UserShoppingListService.GetAllUserShoppingLists:input_type -> shoppinglist.GetAllUserShoppingListsRequest + 8, // 15: shoppinglist.UserShoppingListService.UpdateUserShoppingList:input_type -> shoppinglist.UpdateUserShoppingListRequest + 10, // 16: shoppinglist.UserShoppingListService.DeleteUserShoppingList:input_type -> shoppinglist.DeleteUserShoppingListRequest + 12, // 17: shoppinglist.UserShoppingListEntryService.CreateUserShoppingListEntry:input_type -> shoppinglist.CreateUserShoppingListEntryRequest + 14, // 18: shoppinglist.UserShoppingListEntryService.GetUserShoppingListEntry:input_type -> shoppinglist.GetUserShoppingListEntryRequest + 16, // 19: shoppinglist.UserShoppingListEntryService.GetAllUserShoppingListEntries:input_type -> shoppinglist.GetAllUserShoppingListEntriesRequest + 18, // 20: shoppinglist.UserShoppingListEntryService.UpdateUserShoppingListEntry:input_type -> shoppinglist.UpdateUserShoppingListEntryRequest + 20, // 21: shoppinglist.UserShoppingListEntryService.DeleteUserShoppingListEntry:input_type -> shoppinglist.DeleteUserShoppingListEntryRequest + 3, // 22: shoppinglist.UserShoppingListService.CreateUserShoppingList:output_type -> shoppinglist.CreateUserShoppingListResponse + 5, // 23: shoppinglist.UserShoppingListService.GetUserShoppingList:output_type -> shoppinglist.GetUserShoppingListResponse + 7, // 24: shoppinglist.UserShoppingListService.GetAllUserShoppingLists:output_type -> shoppinglist.GetAllUserShoppingListsResponse + 9, // 25: shoppinglist.UserShoppingListService.UpdateUserShoppingList:output_type -> shoppinglist.UpdateUserShoppingListResponse + 11, // 26: shoppinglist.UserShoppingListService.DeleteUserShoppingList:output_type -> shoppinglist.DeleteUserShoppingListResponse + 13, // 27: shoppinglist.UserShoppingListEntryService.CreateUserShoppingListEntry:output_type -> shoppinglist.CreateUserShoppingListEntryResponse + 15, // 28: shoppinglist.UserShoppingListEntryService.GetUserShoppingListEntry:output_type -> shoppinglist.GetUserShoppingListEntryResponse + 17, // 29: shoppinglist.UserShoppingListEntryService.GetAllUserShoppingListEntries:output_type -> shoppinglist.GetAllUserShoppingListEntriesResponse + 19, // 30: shoppinglist.UserShoppingListEntryService.UpdateUserShoppingListEntry:output_type -> shoppinglist.UpdateUserShoppingListEntryResponse + 21, // 31: shoppinglist.UserShoppingListEntryService.DeleteUserShoppingListEntry:output_type -> shoppinglist.DeleteUserShoppingListEntryResponse + 22, // [22:32] is the sub-list for method output_type + 12, // [12:22] is the sub-list for method input_type + 12, // [12:12] is the sub-list for extension type_name + 12, // [12:12] is the sub-list for extension extendee + 0, // [0:12] is the sub-list for field type_name +} + +func init() { file_shoppinglist_shoppinglist_proto_init() } +func file_shoppinglist_shoppinglist_proto_init() { + if File_shoppinglist_shoppinglist_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_shoppinglist_shoppinglist_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UserShoppingList); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shoppinglist_shoppinglist_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UserShoppingListEntry); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shoppinglist_shoppinglist_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateUserShoppingListRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shoppinglist_shoppinglist_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateUserShoppingListResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shoppinglist_shoppinglist_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetUserShoppingListRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shoppinglist_shoppinglist_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetUserShoppingListResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shoppinglist_shoppinglist_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllUserShoppingListsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shoppinglist_shoppinglist_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllUserShoppingListsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shoppinglist_shoppinglist_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateUserShoppingListRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shoppinglist_shoppinglist_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateUserShoppingListResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shoppinglist_shoppinglist_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteUserShoppingListRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shoppinglist_shoppinglist_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteUserShoppingListResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shoppinglist_shoppinglist_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateUserShoppingListEntryRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shoppinglist_shoppinglist_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateUserShoppingListEntryResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shoppinglist_shoppinglist_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetUserShoppingListEntryRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shoppinglist_shoppinglist_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetUserShoppingListEntryResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shoppinglist_shoppinglist_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllUserShoppingListEntriesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shoppinglist_shoppinglist_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllUserShoppingListEntriesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shoppinglist_shoppinglist_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateUserShoppingListEntryRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shoppinglist_shoppinglist_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateUserShoppingListEntryResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shoppinglist_shoppinglist_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteUserShoppingListEntryRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shoppinglist_shoppinglist_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteUserShoppingListEntryResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_shoppinglist_shoppinglist_proto_rawDesc, + NumEnums: 0, + NumMessages: 22, + NumExtensions: 0, + NumServices: 2, + }, + GoTypes: file_shoppinglist_shoppinglist_proto_goTypes, + DependencyIndexes: file_shoppinglist_shoppinglist_proto_depIdxs, + MessageInfos: file_shoppinglist_shoppinglist_proto_msgTypes, + }.Build() + File_shoppinglist_shoppinglist_proto = out.File + file_shoppinglist_shoppinglist_proto_rawDesc = nil + file_shoppinglist_shoppinglist_proto_goTypes = nil + file_shoppinglist_shoppinglist_proto_depIdxs = nil +} diff --git a/src/shoppinglist-service/internal/proto/shoppinglist/shoppinglist_grpc.pb.go b/src/shoppinglist-service/internal/proto/shoppinglist/shoppinglist_grpc.pb.go new file mode 100644 index 00000000..976b76df --- /dev/null +++ b/src/shoppinglist-service/internal/proto/shoppinglist/shoppinglist_grpc.pb.go @@ -0,0 +1,517 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v4.25.1 +// source: shoppinglist/shoppinglist.proto + +package proto + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + UserShoppingListService_CreateUserShoppingList_FullMethodName = "/shoppinglist.UserShoppingListService/CreateUserShoppingList" + UserShoppingListService_GetUserShoppingList_FullMethodName = "/shoppinglist.UserShoppingListService/GetUserShoppingList" + UserShoppingListService_GetAllUserShoppingLists_FullMethodName = "/shoppinglist.UserShoppingListService/GetAllUserShoppingLists" + UserShoppingListService_UpdateUserShoppingList_FullMethodName = "/shoppinglist.UserShoppingListService/UpdateUserShoppingList" + UserShoppingListService_DeleteUserShoppingList_FullMethodName = "/shoppinglist.UserShoppingListService/DeleteUserShoppingList" +) + +// UserShoppingListServiceClient is the client API for UserShoppingListService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type UserShoppingListServiceClient interface { + // create method for adding a new shopping list + CreateUserShoppingList(ctx context.Context, in *CreateUserShoppingListRequest, opts ...grpc.CallOption) (*CreateUserShoppingListResponse, error) + // read method for getting a specific shopping list + GetUserShoppingList(ctx context.Context, in *GetUserShoppingListRequest, opts ...grpc.CallOption) (*GetUserShoppingListResponse, error) + // read method for getting all shopping lists for an user + GetAllUserShoppingLists(ctx context.Context, in *GetAllUserShoppingListsRequest, opts ...grpc.CallOption) (*GetAllUserShoppingListsResponse, error) + // update method for updating a shopping list + UpdateUserShoppingList(ctx context.Context, in *UpdateUserShoppingListRequest, opts ...grpc.CallOption) (*UpdateUserShoppingListResponse, error) + // delete method to get rid of a shopping list + DeleteUserShoppingList(ctx context.Context, in *DeleteUserShoppingListRequest, opts ...grpc.CallOption) (*DeleteUserShoppingListResponse, error) +} + +type userShoppingListServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewUserShoppingListServiceClient(cc grpc.ClientConnInterface) UserShoppingListServiceClient { + return &userShoppingListServiceClient{cc} +} + +func (c *userShoppingListServiceClient) CreateUserShoppingList(ctx context.Context, in *CreateUserShoppingListRequest, opts ...grpc.CallOption) (*CreateUserShoppingListResponse, error) { + out := new(CreateUserShoppingListResponse) + err := c.cc.Invoke(ctx, UserShoppingListService_CreateUserShoppingList_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userShoppingListServiceClient) GetUserShoppingList(ctx context.Context, in *GetUserShoppingListRequest, opts ...grpc.CallOption) (*GetUserShoppingListResponse, error) { + out := new(GetUserShoppingListResponse) + err := c.cc.Invoke(ctx, UserShoppingListService_GetUserShoppingList_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userShoppingListServiceClient) GetAllUserShoppingLists(ctx context.Context, in *GetAllUserShoppingListsRequest, opts ...grpc.CallOption) (*GetAllUserShoppingListsResponse, error) { + out := new(GetAllUserShoppingListsResponse) + err := c.cc.Invoke(ctx, UserShoppingListService_GetAllUserShoppingLists_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userShoppingListServiceClient) UpdateUserShoppingList(ctx context.Context, in *UpdateUserShoppingListRequest, opts ...grpc.CallOption) (*UpdateUserShoppingListResponse, error) { + out := new(UpdateUserShoppingListResponse) + err := c.cc.Invoke(ctx, UserShoppingListService_UpdateUserShoppingList_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userShoppingListServiceClient) DeleteUserShoppingList(ctx context.Context, in *DeleteUserShoppingListRequest, opts ...grpc.CallOption) (*DeleteUserShoppingListResponse, error) { + out := new(DeleteUserShoppingListResponse) + err := c.cc.Invoke(ctx, UserShoppingListService_DeleteUserShoppingList_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// UserShoppingListServiceServer is the server API for UserShoppingListService service. +// All implementations must embed UnimplementedUserShoppingListServiceServer +// for forward compatibility +type UserShoppingListServiceServer interface { + // create method for adding a new shopping list + CreateUserShoppingList(context.Context, *CreateUserShoppingListRequest) (*CreateUserShoppingListResponse, error) + // read method for getting a specific shopping list + GetUserShoppingList(context.Context, *GetUserShoppingListRequest) (*GetUserShoppingListResponse, error) + // read method for getting all shopping lists for an user + GetAllUserShoppingLists(context.Context, *GetAllUserShoppingListsRequest) (*GetAllUserShoppingListsResponse, error) + // update method for updating a shopping list + UpdateUserShoppingList(context.Context, *UpdateUserShoppingListRequest) (*UpdateUserShoppingListResponse, error) + // delete method to get rid of a shopping list + DeleteUserShoppingList(context.Context, *DeleteUserShoppingListRequest) (*DeleteUserShoppingListResponse, error) + mustEmbedUnimplementedUserShoppingListServiceServer() +} + +// UnimplementedUserShoppingListServiceServer must be embedded to have forward compatible implementations. +type UnimplementedUserShoppingListServiceServer struct { +} + +func (UnimplementedUserShoppingListServiceServer) CreateUserShoppingList(context.Context, *CreateUserShoppingListRequest) (*CreateUserShoppingListResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateUserShoppingList not implemented") +} +func (UnimplementedUserShoppingListServiceServer) GetUserShoppingList(context.Context, *GetUserShoppingListRequest) (*GetUserShoppingListResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetUserShoppingList not implemented") +} +func (UnimplementedUserShoppingListServiceServer) GetAllUserShoppingLists(context.Context, *GetAllUserShoppingListsRequest) (*GetAllUserShoppingListsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAllUserShoppingLists not implemented") +} +func (UnimplementedUserShoppingListServiceServer) UpdateUserShoppingList(context.Context, *UpdateUserShoppingListRequest) (*UpdateUserShoppingListResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateUserShoppingList not implemented") +} +func (UnimplementedUserShoppingListServiceServer) DeleteUserShoppingList(context.Context, *DeleteUserShoppingListRequest) (*DeleteUserShoppingListResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteUserShoppingList not implemented") +} +func (UnimplementedUserShoppingListServiceServer) mustEmbedUnimplementedUserShoppingListServiceServer() { +} + +// UnsafeUserShoppingListServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to UserShoppingListServiceServer will +// result in compilation errors. +type UnsafeUserShoppingListServiceServer interface { + mustEmbedUnimplementedUserShoppingListServiceServer() +} + +func RegisterUserShoppingListServiceServer(s grpc.ServiceRegistrar, srv UserShoppingListServiceServer) { + s.RegisterService(&UserShoppingListService_ServiceDesc, srv) +} + +func _UserShoppingListService_CreateUserShoppingList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateUserShoppingListRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserShoppingListServiceServer).CreateUserShoppingList(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserShoppingListService_CreateUserShoppingList_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserShoppingListServiceServer).CreateUserShoppingList(ctx, req.(*CreateUserShoppingListRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserShoppingListService_GetUserShoppingList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetUserShoppingListRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserShoppingListServiceServer).GetUserShoppingList(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserShoppingListService_GetUserShoppingList_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserShoppingListServiceServer).GetUserShoppingList(ctx, req.(*GetUserShoppingListRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserShoppingListService_GetAllUserShoppingLists_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetAllUserShoppingListsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserShoppingListServiceServer).GetAllUserShoppingLists(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserShoppingListService_GetAllUserShoppingLists_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserShoppingListServiceServer).GetAllUserShoppingLists(ctx, req.(*GetAllUserShoppingListsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserShoppingListService_UpdateUserShoppingList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateUserShoppingListRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserShoppingListServiceServer).UpdateUserShoppingList(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserShoppingListService_UpdateUserShoppingList_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserShoppingListServiceServer).UpdateUserShoppingList(ctx, req.(*UpdateUserShoppingListRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserShoppingListService_DeleteUserShoppingList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteUserShoppingListRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserShoppingListServiceServer).DeleteUserShoppingList(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserShoppingListService_DeleteUserShoppingList_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserShoppingListServiceServer).DeleteUserShoppingList(ctx, req.(*DeleteUserShoppingListRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// UserShoppingListService_ServiceDesc is the grpc.ServiceDesc for UserShoppingListService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var UserShoppingListService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "shoppinglist.UserShoppingListService", + HandlerType: (*UserShoppingListServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateUserShoppingList", + Handler: _UserShoppingListService_CreateUserShoppingList_Handler, + }, + { + MethodName: "GetUserShoppingList", + Handler: _UserShoppingListService_GetUserShoppingList_Handler, + }, + { + MethodName: "GetAllUserShoppingLists", + Handler: _UserShoppingListService_GetAllUserShoppingLists_Handler, + }, + { + MethodName: "UpdateUserShoppingList", + Handler: _UserShoppingListService_UpdateUserShoppingList_Handler, + }, + { + MethodName: "DeleteUserShoppingList", + Handler: _UserShoppingListService_DeleteUserShoppingList_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "shoppinglist/shoppinglist.proto", +} + +const ( + UserShoppingListEntryService_CreateUserShoppingListEntry_FullMethodName = "/shoppinglist.UserShoppingListEntryService/CreateUserShoppingListEntry" + UserShoppingListEntryService_GetUserShoppingListEntry_FullMethodName = "/shoppinglist.UserShoppingListEntryService/GetUserShoppingListEntry" + UserShoppingListEntryService_GetAllUserShoppingListEntries_FullMethodName = "/shoppinglist.UserShoppingListEntryService/GetAllUserShoppingListEntries" + UserShoppingListEntryService_UpdateUserShoppingListEntry_FullMethodName = "/shoppinglist.UserShoppingListEntryService/UpdateUserShoppingListEntry" + UserShoppingListEntryService_DeleteUserShoppingListEntry_FullMethodName = "/shoppinglist.UserShoppingListEntryService/DeleteUserShoppingListEntry" +) + +// UserShoppingListEntryServiceClient is the client API for UserShoppingListEntryService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type UserShoppingListEntryServiceClient interface { + // create method for adding a new shopping list entry + CreateUserShoppingListEntry(ctx context.Context, in *CreateUserShoppingListEntryRequest, opts ...grpc.CallOption) (*CreateUserShoppingListEntryResponse, error) + // read method for getting a specific shopping list entry + GetUserShoppingListEntry(ctx context.Context, in *GetUserShoppingListEntryRequest, opts ...grpc.CallOption) (*GetUserShoppingListEntryResponse, error) + // read method for getting all shopping list entry for a specific shopping list + GetAllUserShoppingListEntries(ctx context.Context, in *GetAllUserShoppingListEntriesRequest, opts ...grpc.CallOption) (*GetAllUserShoppingListEntriesResponse, error) + // update method for updating a shopping list + UpdateUserShoppingListEntry(ctx context.Context, in *UpdateUserShoppingListEntryRequest, opts ...grpc.CallOption) (*UpdateUserShoppingListEntryResponse, error) + // delete method to get rid of a shopping list + DeleteUserShoppingListEntry(ctx context.Context, in *DeleteUserShoppingListEntryRequest, opts ...grpc.CallOption) (*DeleteUserShoppingListEntryResponse, error) +} + +type userShoppingListEntryServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewUserShoppingListEntryServiceClient(cc grpc.ClientConnInterface) UserShoppingListEntryServiceClient { + return &userShoppingListEntryServiceClient{cc} +} + +func (c *userShoppingListEntryServiceClient) CreateUserShoppingListEntry(ctx context.Context, in *CreateUserShoppingListEntryRequest, opts ...grpc.CallOption) (*CreateUserShoppingListEntryResponse, error) { + out := new(CreateUserShoppingListEntryResponse) + err := c.cc.Invoke(ctx, UserShoppingListEntryService_CreateUserShoppingListEntry_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userShoppingListEntryServiceClient) GetUserShoppingListEntry(ctx context.Context, in *GetUserShoppingListEntryRequest, opts ...grpc.CallOption) (*GetUserShoppingListEntryResponse, error) { + out := new(GetUserShoppingListEntryResponse) + err := c.cc.Invoke(ctx, UserShoppingListEntryService_GetUserShoppingListEntry_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userShoppingListEntryServiceClient) GetAllUserShoppingListEntries(ctx context.Context, in *GetAllUserShoppingListEntriesRequest, opts ...grpc.CallOption) (*GetAllUserShoppingListEntriesResponse, error) { + out := new(GetAllUserShoppingListEntriesResponse) + err := c.cc.Invoke(ctx, UserShoppingListEntryService_GetAllUserShoppingListEntries_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userShoppingListEntryServiceClient) UpdateUserShoppingListEntry(ctx context.Context, in *UpdateUserShoppingListEntryRequest, opts ...grpc.CallOption) (*UpdateUserShoppingListEntryResponse, error) { + out := new(UpdateUserShoppingListEntryResponse) + err := c.cc.Invoke(ctx, UserShoppingListEntryService_UpdateUserShoppingListEntry_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userShoppingListEntryServiceClient) DeleteUserShoppingListEntry(ctx context.Context, in *DeleteUserShoppingListEntryRequest, opts ...grpc.CallOption) (*DeleteUserShoppingListEntryResponse, error) { + out := new(DeleteUserShoppingListEntryResponse) + err := c.cc.Invoke(ctx, UserShoppingListEntryService_DeleteUserShoppingListEntry_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// UserShoppingListEntryServiceServer is the server API for UserShoppingListEntryService service. +// All implementations must embed UnimplementedUserShoppingListEntryServiceServer +// for forward compatibility +type UserShoppingListEntryServiceServer interface { + // create method for adding a new shopping list entry + CreateUserShoppingListEntry(context.Context, *CreateUserShoppingListEntryRequest) (*CreateUserShoppingListEntryResponse, error) + // read method for getting a specific shopping list entry + GetUserShoppingListEntry(context.Context, *GetUserShoppingListEntryRequest) (*GetUserShoppingListEntryResponse, error) + // read method for getting all shopping list entry for a specific shopping list + GetAllUserShoppingListEntries(context.Context, *GetAllUserShoppingListEntriesRequest) (*GetAllUserShoppingListEntriesResponse, error) + // update method for updating a shopping list + UpdateUserShoppingListEntry(context.Context, *UpdateUserShoppingListEntryRequest) (*UpdateUserShoppingListEntryResponse, error) + // delete method to get rid of a shopping list + DeleteUserShoppingListEntry(context.Context, *DeleteUserShoppingListEntryRequest) (*DeleteUserShoppingListEntryResponse, error) + mustEmbedUnimplementedUserShoppingListEntryServiceServer() +} + +// UnimplementedUserShoppingListEntryServiceServer must be embedded to have forward compatible implementations. +type UnimplementedUserShoppingListEntryServiceServer struct { +} + +func (UnimplementedUserShoppingListEntryServiceServer) CreateUserShoppingListEntry(context.Context, *CreateUserShoppingListEntryRequest) (*CreateUserShoppingListEntryResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateUserShoppingListEntry not implemented") +} +func (UnimplementedUserShoppingListEntryServiceServer) GetUserShoppingListEntry(context.Context, *GetUserShoppingListEntryRequest) (*GetUserShoppingListEntryResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetUserShoppingListEntry not implemented") +} +func (UnimplementedUserShoppingListEntryServiceServer) GetAllUserShoppingListEntries(context.Context, *GetAllUserShoppingListEntriesRequest) (*GetAllUserShoppingListEntriesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAllUserShoppingListEntries not implemented") +} +func (UnimplementedUserShoppingListEntryServiceServer) UpdateUserShoppingListEntry(context.Context, *UpdateUserShoppingListEntryRequest) (*UpdateUserShoppingListEntryResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateUserShoppingListEntry not implemented") +} +func (UnimplementedUserShoppingListEntryServiceServer) DeleteUserShoppingListEntry(context.Context, *DeleteUserShoppingListEntryRequest) (*DeleteUserShoppingListEntryResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteUserShoppingListEntry not implemented") +} +func (UnimplementedUserShoppingListEntryServiceServer) mustEmbedUnimplementedUserShoppingListEntryServiceServer() { +} + +// UnsafeUserShoppingListEntryServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to UserShoppingListEntryServiceServer will +// result in compilation errors. +type UnsafeUserShoppingListEntryServiceServer interface { + mustEmbedUnimplementedUserShoppingListEntryServiceServer() +} + +func RegisterUserShoppingListEntryServiceServer(s grpc.ServiceRegistrar, srv UserShoppingListEntryServiceServer) { + s.RegisterService(&UserShoppingListEntryService_ServiceDesc, srv) +} + +func _UserShoppingListEntryService_CreateUserShoppingListEntry_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateUserShoppingListEntryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserShoppingListEntryServiceServer).CreateUserShoppingListEntry(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserShoppingListEntryService_CreateUserShoppingListEntry_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserShoppingListEntryServiceServer).CreateUserShoppingListEntry(ctx, req.(*CreateUserShoppingListEntryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserShoppingListEntryService_GetUserShoppingListEntry_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetUserShoppingListEntryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserShoppingListEntryServiceServer).GetUserShoppingListEntry(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserShoppingListEntryService_GetUserShoppingListEntry_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserShoppingListEntryServiceServer).GetUserShoppingListEntry(ctx, req.(*GetUserShoppingListEntryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserShoppingListEntryService_GetAllUserShoppingListEntries_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetAllUserShoppingListEntriesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserShoppingListEntryServiceServer).GetAllUserShoppingListEntries(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserShoppingListEntryService_GetAllUserShoppingListEntries_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserShoppingListEntryServiceServer).GetAllUserShoppingListEntries(ctx, req.(*GetAllUserShoppingListEntriesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserShoppingListEntryService_UpdateUserShoppingListEntry_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateUserShoppingListEntryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserShoppingListEntryServiceServer).UpdateUserShoppingListEntry(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserShoppingListEntryService_UpdateUserShoppingListEntry_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserShoppingListEntryServiceServer).UpdateUserShoppingListEntry(ctx, req.(*UpdateUserShoppingListEntryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserShoppingListEntryService_DeleteUserShoppingListEntry_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteUserShoppingListEntryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserShoppingListEntryServiceServer).DeleteUserShoppingListEntry(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserShoppingListEntryService_DeleteUserShoppingListEntry_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserShoppingListEntryServiceServer).DeleteUserShoppingListEntry(ctx, req.(*DeleteUserShoppingListEntryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// UserShoppingListEntryService_ServiceDesc is the grpc.ServiceDesc for UserShoppingListEntryService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var UserShoppingListEntryService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "shoppinglist.UserShoppingListEntryService", + HandlerType: (*UserShoppingListEntryServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateUserShoppingListEntry", + Handler: _UserShoppingListEntryService_CreateUserShoppingListEntry_Handler, + }, + { + MethodName: "GetUserShoppingListEntry", + Handler: _UserShoppingListEntryService_GetUserShoppingListEntry_Handler, + }, + { + MethodName: "GetAllUserShoppingListEntries", + Handler: _UserShoppingListEntryService_GetAllUserShoppingListEntries_Handler, + }, + { + MethodName: "UpdateUserShoppingListEntry", + Handler: _UserShoppingListEntryService_UpdateUserShoppingListEntry_Handler, + }, + { + MethodName: "DeleteUserShoppingListEntry", + Handler: _UserShoppingListEntryService_DeleteUserShoppingListEntry_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "shoppinglist/shoppinglist.proto", +} diff --git a/src/shoppinglist-service/main.go b/src/shoppinglist-service/main.go index 3190f461..5b1535c1 100644 --- a/src/shoppinglist-service/main.go +++ b/src/shoppinglist-service/main.go @@ -1,3 +1,5 @@ +//go:generate protoc --proto_path=../../lib/rpc --go_out=internal/proto --go_opt=paths=source_relative --go-grpc_out=internal/proto --go-grpc_opt=paths=source_relative ../../lib/rpc/shoppinglist/shoppinglist.proto + package main import ( diff --git a/src/user-service/api/handler/login.go b/src/user-service/api/http/handler/login.go similarity index 85% rename from src/user-service/api/handler/login.go rename to src/user-service/api/http/handler/login.go index bf36acfa..7afe9796 100644 --- a/src/user-service/api/handler/login.go +++ b/src/user-service/api/http/handler/login.go @@ -72,23 +72,11 @@ func (handler *LoginHandler) Login(w http.ResponseWriter, r *http.Request) { expiration := 1 * time.Hour accessToken, err := handler.tokenGenerator.CreateToken(map[string]interface{}{ - "email": request.Email, + "id": foundUser.Id, + "email": foundUser.Email, "exp": time.Now().Add(expiration).Unix(), }) - // Set the access token as a cookie - cookie := &http.Cookie{ - Name: "access_token", - Value: accessToken, - Path: "/", - MaxAge: int(expiration.Seconds()), - Secure: false, // Set to true if served over HTTPS - HttpOnly: true, - SameSite: http.SameSiteStrictMode, - } - - http.SetCookie(w, cookie) - json.NewEncoder(w).Encode(loginResponse{ AccessToken: accessToken, TokenType: "Bearer", diff --git a/src/user-service/api/handler/login_test.go b/src/user-service/api/http/handler/login_test.go similarity index 91% rename from src/user-service/api/handler/login_test.go rename to src/user-service/api/http/handler/login_test.go index 391e0c29..d5c32455 100644 --- a/src/user-service/api/handler/login_test.go +++ b/src/user-service/api/http/handler/login_test.go @@ -1,7 +1,12 @@ package handler import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/x509" "encoding/json" + "encoding/pem" "github.com/stretchr/testify/assert" "hsfl.de/group6/hsfl-master-ai-cloud-engineering/user-service/auth" "hsfl.de/group6/hsfl-master-ai-cloud-engineering/user-service/crypto" @@ -184,8 +189,25 @@ func TestLoginHandler(t *testing.T) { } func setupLoginHandler() *LoginHandler { + privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + panic("Error generating private key for testing.") + } + + derFormatKey, err := x509.MarshalECPrivateKey(privateKey) + if err != nil { + panic("Error converting ECDSA key to DER format") + } + + pemKey := pem.EncodeToMemory(&pem.Block{ + Type: "EC PRIVATE KEY", + Bytes: derFormatKey, + }) + + pemPrivateKey := string(pemKey) + var jwtToken, _ = auth.NewJwtTokenGenerator( - auth.JwtConfig{SignKey: "../../auth/test-token"}) + auth.JwtConfig{PrivateKey: pemPrivateKey}) return NewLoginHandler(setupMockRepository(), crypto.NewBcryptHasher(), jwtToken) diff --git a/src/user-service/api/handler/register.go b/src/user-service/api/http/handler/register.go similarity index 100% rename from src/user-service/api/handler/register.go rename to src/user-service/api/http/handler/register.go diff --git a/src/user-service/api/handler/register_test.go b/src/user-service/api/http/handler/register_test.go similarity index 100% rename from src/user-service/api/handler/register_test.go rename to src/user-service/api/http/handler/register_test.go diff --git a/src/user-service/api/router/router.go b/src/user-service/api/http/router/router.go similarity index 60% rename from src/user-service/api/router/router.go rename to src/user-service/api/http/router/router.go index 05269a2f..307d97b3 100644 --- a/src/user-service/api/router/router.go +++ b/src/user-service/api/http/router/router.go @@ -2,7 +2,8 @@ package router import ( router "hsfl.de/group6/hsfl-master-ai-cloud-engineering/lib" - "hsfl.de/group6/hsfl-master-ai-cloud-engineering/user-service/api/handler" + "hsfl.de/group6/hsfl-master-ai-cloud-engineering/lib/middleware" + "hsfl.de/group6/hsfl-master-ai-cloud-engineering/user-service/api/http/handler" "hsfl.de/group6/hsfl-master-ai-cloud-engineering/user-service/user" "net/http" ) @@ -21,12 +22,14 @@ func New( r.POST("/api/v1/authentication/login/", loginHandler.Login) r.POST("/api/v1/authentication/register/", registerHandler.Register) - r.GET("/api/v1/user/", userHandler.GetUsers) - r.GET("/api/v1/user/role/:userRole", userHandler.GetUsersByRole) - r.GET("/api/v1/user/:userId", userHandler.GetUser) - r.PUT("/api/v1/user/:userId", userHandler.PutUser) - r.POST("/api/v1/user/", userHandler.PostUser) - r.DELETE("/api/v1/user/:userId", userHandler.DeleteUser) + authMiddleware := middleware.CreateAuthMiddleware() + + r.GET("/api/v1/user/", userHandler.GetUsers, authMiddleware) + r.GET("/api/v1/user/role/:userRole", userHandler.GetUsersByRole, authMiddleware) + r.GET("/api/v1/user/:userId", userHandler.GetUser, authMiddleware) + r.PUT("/api/v1/user/:userId", userHandler.PutUser, authMiddleware) + r.POST("/api/v1/user/", userHandler.PostUser, authMiddleware) + r.DELETE("/api/v1/user/:userId", userHandler.DeleteUser, authMiddleware) return &Router{r} } diff --git a/src/user-service/api/router/router_test.go b/src/user-service/api/http/router/router_test.go similarity index 93% rename from src/user-service/api/router/router_test.go rename to src/user-service/api/http/router/router_test.go index 5e10e893..d9c7b4dd 100644 --- a/src/user-service/api/router/router_test.go +++ b/src/user-service/api/http/router/router_test.go @@ -2,8 +2,13 @@ package router import ( "bytes" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/x509" + "encoding/pem" "github.com/stretchr/testify/assert" - "hsfl.de/group6/hsfl-master-ai-cloud-engineering/user-service/api/handler" + "hsfl.de/group6/hsfl-master-ai-cloud-engineering/user-service/api/http/handler" "hsfl.de/group6/hsfl-master-ai-cloud-engineering/user-service/auth" "hsfl.de/group6/hsfl-master-ai-cloud-engineering/user-service/crypto" "hsfl.de/group6/hsfl-master-ai-cloud-engineering/user-service/user" @@ -237,8 +242,25 @@ func TestRouter(t *testing.T) { } func setupLoginHandler() *handler.LoginHandler { + privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + panic("Error generating private key for testing.") + } + + derFormatKey, err := x509.MarshalECPrivateKey(privateKey) + if err != nil { + panic("Error converting ECDSA key to DER format") + } + + pemKey := pem.EncodeToMemory(&pem.Block{ + Type: "EC PRIVATE KEY", + Bytes: derFormatKey, + }) + + pemPrivateKey := string(pemKey) + var jwtToken, _ = auth.NewJwtTokenGenerator( - auth.JwtConfig{SignKey: "../../auth/test-token"}) + auth.JwtConfig{PrivateKey: pemPrivateKey}) return handler.NewLoginHandler(setupMockRepository(), crypto.NewBcryptHasher(), jwtToken) diff --git a/src/user-service/api/rpc/server.go b/src/user-service/api/rpc/server.go new file mode 100644 index 00000000..0875a371 --- /dev/null +++ b/src/user-service/api/rpc/server.go @@ -0,0 +1,47 @@ +package rpc + +import ( + "context" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "hsfl.de/group6/hsfl-master-ai-cloud-engineering/user-service/auth" + "hsfl.de/group6/hsfl-master-ai-cloud-engineering/user-service/crypto" + proto "hsfl.de/group6/hsfl-master-ai-cloud-engineering/user-service/internal/proto/user" + "hsfl.de/group6/hsfl-master-ai-cloud-engineering/user-service/user" + "log" + "strconv" +) + +type UserServiceServer struct { + proto.UnimplementedUserServiceServer + userRepository user.Repository + hasher crypto.Hasher + tokenGenerator auth.TokenGenerator +} + +func (u UserServiceServer) ValidateUserToken(_ context.Context, request *proto.ValidateUserTokenRequest) (*proto.ValidateUserTokenResponse, error) { + claims, err := u.tokenGenerator.VerifyToken(request.Token) + if err != nil { + log.Println("Verification failed: ", err.Error()) + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + + id, err := strconv.ParseUint(claims["id"].(string), 10, 64) + if err != nil { + log.Println("Verification failed: Can't find user id in claim.") + return nil, status.Error(codes.DataLoss, "Can't find user id in claim.") + } + + user, err := u.userRepository.FindById(id) + if err != nil { + log.Println("Verification failed: ", err.Error()) + return nil, status.Error(codes.NotFound, err.Error()) + } + + return &proto.ValidateUserTokenResponse{User: &proto.User{ + Id: user.Id, + Email: user.Email, + Name: user.Name, + Role: int64(user.Role), + }}, nil +} diff --git a/src/user-service/auth/jwt_config.go b/src/user-service/auth/jwt_config.go index 6fbbb131..9c3c9bc9 100644 --- a/src/user-service/auth/jwt_config.go +++ b/src/user-service/auth/jwt_config.go @@ -7,15 +7,25 @@ import ( ) type JwtConfig struct { - SignKey string `yaml:"signKey"` + PrivateKey string `yaml:"privateKey"` } func (config JwtConfig) ReadPrivateKey() (any, error) { - bytes, err := os.ReadFile(config.SignKey) - if err != nil { - return nil, err + var block *pem.Block + + if _, err := os.Stat(config.PrivateKey); err == nil { + bytes, err := os.ReadFile(config.PrivateKey) + if err != nil { + return nil, err + } + block, _ = pem.Decode(bytes) + } else { + block, _ = pem.Decode([]byte(config.PrivateKey)) + if block == nil { + return nil, err + } } - block, _ := pem.Decode(bytes) return x509.ParseECPrivateKey(block.Bytes) + } diff --git a/src/user-service/auth/jwt_token_generator.go b/src/user-service/auth/jwt_token_generator.go index cc71b991..3518aacf 100644 --- a/src/user-service/auth/jwt_token_generator.go +++ b/src/user-service/auth/jwt_token_generator.go @@ -2,6 +2,7 @@ package auth import ( "crypto/ecdsa" + "fmt" "github.com/golang-jwt/jwt" ) @@ -33,3 +34,21 @@ func (gen *JwtTokenGenerator) CreateToken(claims map[string]interface{}) (string token := jwt.NewWithClaims(jwt.SigningMethodES256, jwtClaims) return token.SignedString(gen.privateKey) } + +func (gen *JwtTokenGenerator) VerifyToken(tokenString string) (map[string]interface{}, error) { + token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { + if _, ok := token.Method.(*jwt.SigningMethodECDSA); !ok { + return nil, fmt.Errorf("signing algorithm unknown: %v", token.Header["alg"]) + } + return &gen.privateKey.PublicKey, nil + }) + + if err != nil { + return nil, err + } + + if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { + return claims, nil + } + return nil, err +} diff --git a/src/user-service/auth/jwt_token_generator_test.go b/src/user-service/auth/jwt_token_generator_test.go index 483754be..5991b497 100644 --- a/src/user-service/auth/jwt_token_generator_test.go +++ b/src/user-service/auth/jwt_token_generator_test.go @@ -8,6 +8,7 @@ import ( "encoding/json" "strings" "testing" + "time" "github.com/stretchr/testify/assert" ) @@ -18,12 +19,12 @@ func TestJwtAuthorizer(t *testing.T) { t.Run("Create new JWT Token Generator", func(t *testing.T) { t.Run("Invaid Config expect error", func(t *testing.T) { - var jwtToken, err = NewJwtTokenGenerator(JwtConfig{SignKey: "./auth/test-token-nonexistent"}) + var jwtToken, err = NewJwtTokenGenerator(JwtConfig{PrivateKey: "./auth/test-token-nonexistent"}) assert.Nil(t, jwtToken) assert.Error(t, err) }) t.Run("Valid Config expect non-nill Token Generator", func(t *testing.T) { - var jwtToken, err = NewJwtTokenGenerator(JwtConfig{SignKey: "./test-token"}) + var jwtToken, err = NewJwtTokenGenerator(JwtConfig{PrivateKey: "./test-token"}) assert.NoError(t, err) assert.NotNil(t, jwtToken) }) @@ -31,14 +32,11 @@ func TestJwtAuthorizer(t *testing.T) { t.Run("CreateToken", func(t *testing.T) { t.Run("should generate valid JWT token", func(t *testing.T) { - // given - // when token, err := tokenGenerator.CreateToken(map[string]interface{}{ "exp": 12345, "user": "test", }) - // then assert.NoError(t, err) tokenParts := strings.Split(token, ".") assert.Len(t, tokenParts, 3) @@ -55,4 +53,36 @@ func TestJwtAuthorizer(t *testing.T) { assert.Equal(t, "test", claims["user"]) }) }) + + t.Run("VerifyToken", func(t *testing.T) { + t.Run("should successfully verify JWT token", func(t *testing.T) { + expiration := time.Now().Add(12345).Unix() + token, err := tokenGenerator.CreateToken(map[string]interface{}{ + "exp": float64(expiration), + "user": "test", + }) + + claims, err := tokenGenerator.VerifyToken(token) + + assert.NoError(t, err) + assert.Len(t, claims, 2) + + assert.Equal(t, float64(expiration), claims["exp"]) + assert.Equal(t, "test", claims["user"]) + }) + + t.Run("should not verify JWT token", func(t *testing.T) { + token, err := tokenGenerator.CreateToken(map[string]interface{}{ + "exp": 12345, + "user": "test", + }) + + assert.NoError(t, err) + + _, err = tokenGenerator.VerifyToken(token) + + assert.Error(t, err) + }) + }) + } diff --git a/src/user-service/auth/token_generator.go b/src/user-service/auth/token_generator.go index 6c59f5e1..393a0c14 100644 --- a/src/user-service/auth/token_generator.go +++ b/src/user-service/auth/token_generator.go @@ -1,5 +1,6 @@ package auth type TokenGenerator interface { + VerifyToken(tokenString string) (map[string]interface{}, error) CreateToken(claims map[string]interface{}) (string, error) } diff --git a/src/user-service/internal/proto/user/user.pb.go b/src/user-service/internal/proto/user/user.pb.go new file mode 100644 index 00000000..5627c07e --- /dev/null +++ b/src/user-service/internal/proto/user/user.pb.go @@ -0,0 +1,306 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v4.25.1 +// source: user/user.proto + +package proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type User struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Email string `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Role int64 `protobuf:"varint,4,opt,name=role,proto3" json:"role,omitempty"` +} + +func (x *User) Reset() { + *x = User{} + if protoimpl.UnsafeEnabled { + mi := &file_user_user_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *User) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*User) ProtoMessage() {} + +func (x *User) ProtoReflect() protoreflect.Message { + mi := &file_user_user_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use User.ProtoReflect.Descriptor instead. +func (*User) Descriptor() ([]byte, []int) { + return file_user_user_proto_rawDescGZIP(), []int{0} +} + +func (x *User) GetId() uint64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *User) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +func (x *User) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *User) GetRole() int64 { + if x != nil { + return x.Role + } + return 0 +} + +type ValidateUserTokenRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` +} + +func (x *ValidateUserTokenRequest) Reset() { + *x = ValidateUserTokenRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_user_user_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidateUserTokenRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidateUserTokenRequest) ProtoMessage() {} + +func (x *ValidateUserTokenRequest) ProtoReflect() protoreflect.Message { + mi := &file_user_user_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidateUserTokenRequest.ProtoReflect.Descriptor instead. +func (*ValidateUserTokenRequest) Descriptor() ([]byte, []int) { + return file_user_user_proto_rawDescGZIP(), []int{1} +} + +func (x *ValidateUserTokenRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +type ValidateUserTokenResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` +} + +func (x *ValidateUserTokenResponse) Reset() { + *x = ValidateUserTokenResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_user_user_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidateUserTokenResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidateUserTokenResponse) ProtoMessage() {} + +func (x *ValidateUserTokenResponse) ProtoReflect() protoreflect.Message { + mi := &file_user_user_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidateUserTokenResponse.ProtoReflect.Descriptor instead. +func (*ValidateUserTokenResponse) Descriptor() ([]byte, []int) { + return file_user_user_proto_rawDescGZIP(), []int{2} +} + +func (x *ValidateUserTokenResponse) GetUser() *User { + if x != nil { + return x.User + } + return nil +} + +var File_user_user_proto protoreflect.FileDescriptor + +var file_user_user_proto_rawDesc = []byte{ + 0x0a, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x07, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x22, 0x54, 0x0a, 0x04, 0x55, 0x73, + 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, + 0x22, 0x30, 0x0a, 0x18, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x22, 0x3e, 0x0a, 0x19, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, + 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x21, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, + 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, + 0x65, 0x72, 0x32, 0x69, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x5a, 0x0a, 0x11, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, + 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, + 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x12, 0x5a, + 0x10, 0x2e, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_user_user_proto_rawDescOnce sync.Once + file_user_user_proto_rawDescData = file_user_user_proto_rawDesc +) + +func file_user_user_proto_rawDescGZIP() []byte { + file_user_user_proto_rawDescOnce.Do(func() { + file_user_user_proto_rawDescData = protoimpl.X.CompressGZIP(file_user_user_proto_rawDescData) + }) + return file_user_user_proto_rawDescData +} + +var file_user_user_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_user_user_proto_goTypes = []interface{}{ + (*User)(nil), // 0: product.User + (*ValidateUserTokenRequest)(nil), // 1: product.ValidateUserTokenRequest + (*ValidateUserTokenResponse)(nil), // 2: product.ValidateUserTokenResponse +} +var file_user_user_proto_depIdxs = []int32{ + 0, // 0: product.ValidateUserTokenResponse.user:type_name -> product.User + 1, // 1: product.UserService.ValidateUserToken:input_type -> product.ValidateUserTokenRequest + 2, // 2: product.UserService.ValidateUserToken:output_type -> product.ValidateUserTokenResponse + 2, // [2:3] is the sub-list for method output_type + 1, // [1:2] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_user_user_proto_init() } +func file_user_user_proto_init() { + if File_user_user_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_user_user_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*User); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_user_user_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidateUserTokenRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_user_user_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidateUserTokenResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_user_user_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_user_user_proto_goTypes, + DependencyIndexes: file_user_user_proto_depIdxs, + MessageInfos: file_user_user_proto_msgTypes, + }.Build() + File_user_user_proto = out.File + file_user_user_proto_rawDesc = nil + file_user_user_proto_goTypes = nil + file_user_user_proto_depIdxs = nil +} diff --git a/src/user-service/internal/proto/user/user_grpc.pb.go b/src/user-service/internal/proto/user/user_grpc.pb.go new file mode 100644 index 00000000..296f8e4c --- /dev/null +++ b/src/user-service/internal/proto/user/user_grpc.pb.go @@ -0,0 +1,111 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v4.25.1 +// source: user/user.proto + +package proto + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + UserService_ValidateUserToken_FullMethodName = "/product.UserService/ValidateUserToken" +) + +// UserServiceClient is the client API for UserService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type UserServiceClient interface { + // validate a token and return a user + ValidateUserToken(ctx context.Context, in *ValidateUserTokenRequest, opts ...grpc.CallOption) (*ValidateUserTokenResponse, error) +} + +type userServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewUserServiceClient(cc grpc.ClientConnInterface) UserServiceClient { + return &userServiceClient{cc} +} + +func (c *userServiceClient) ValidateUserToken(ctx context.Context, in *ValidateUserTokenRequest, opts ...grpc.CallOption) (*ValidateUserTokenResponse, error) { + out := new(ValidateUserTokenResponse) + err := c.cc.Invoke(ctx, UserService_ValidateUserToken_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// UserServiceServer is the server API for UserService service. +// All implementations must embed UnimplementedUserServiceServer +// for forward compatibility +type UserServiceServer interface { + // validate a token and return a user + ValidateUserToken(context.Context, *ValidateUserTokenRequest) (*ValidateUserTokenResponse, error) + mustEmbedUnimplementedUserServiceServer() +} + +// UnimplementedUserServiceServer must be embedded to have forward compatible implementations. +type UnimplementedUserServiceServer struct { +} + +func (UnimplementedUserServiceServer) ValidateUserToken(context.Context, *ValidateUserTokenRequest) (*ValidateUserTokenResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ValidateUserToken not implemented") +} +func (UnimplementedUserServiceServer) mustEmbedUnimplementedUserServiceServer() {} + +// UnsafeUserServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to UserServiceServer will +// result in compilation errors. +type UnsafeUserServiceServer interface { + mustEmbedUnimplementedUserServiceServer() +} + +func RegisterUserServiceServer(s grpc.ServiceRegistrar, srv UserServiceServer) { + s.RegisterService(&UserService_ServiceDesc, srv) +} + +func _UserService_ValidateUserToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ValidateUserTokenRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).ValidateUserToken(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserService_ValidateUserToken_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).ValidateUserToken(ctx, req.(*ValidateUserTokenRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// UserService_ServiceDesc is the grpc.ServiceDesc for UserService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var UserService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "product.UserService", + HandlerType: (*UserServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "ValidateUserToken", + Handler: _UserService_ValidateUserToken_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "user/user.proto", +} diff --git a/src/user-service/main.go b/src/user-service/main.go index 853562fb..1a572a27 100644 --- a/src/user-service/main.go +++ b/src/user-service/main.go @@ -1,8 +1,10 @@ +//go:generate protoc --proto_path=../../lib/rpc --go_out=internal/proto --go_opt=paths=source_relative --go-grpc_out=internal/proto --go-grpc_opt=paths=source_relative ../../lib/rpc/user/user.proto + package main import ( - "hsfl.de/group6/hsfl-master-ai-cloud-engineering/user-service/api/handler" - "hsfl.de/group6/hsfl-master-ai-cloud-engineering/user-service/api/router" + "hsfl.de/group6/hsfl-master-ai-cloud-engineering/user-service/api/http/handler" + "hsfl.de/group6/hsfl-master-ai-cloud-engineering/user-service/api/http/router" "hsfl.de/group6/hsfl-master-ai-cloud-engineering/user-service/auth" "hsfl.de/group6/hsfl-master-ai-cloud-engineering/user-service/crypto" "hsfl.de/group6/hsfl-master-ai-cloud-engineering/user-service/user" @@ -27,7 +29,7 @@ func main() { func setupLoginHandler(userRepository user.Repository) *handler.LoginHandler { var jwtToken, _ = auth.NewJwtTokenGenerator( - auth.JwtConfig{SignKey: "./auth/test-token"}) + auth.JwtConfig{PrivateKey: "./auth/test-token"}) return handler.NewLoginHandler(setupMockRepository(userRepository), crypto.NewBcryptHasher(), jwtToken) diff --git a/src/web-service/frontend/src/lib/forms/Input.svelte b/src/web-service/frontend/src/lib/forms/Input.svelte index 5f864095..ac17f7a0 100644 --- a/src/web-service/frontend/src/lib/forms/Input.svelte +++ b/src/web-service/frontend/src/lib/forms/Input.svelte @@ -24,5 +24,5 @@ readonly="{readonly}" placeholder="{label}" bind:value={value} - class="text-sm rounded-lg border px-3 py-2 w-full text-left text-green-dark/75 flex items-center justify-between transition-all duration-300 ease-in-out hover:bg-blue-light/25 lg:px-4 lg:py-3 read-only:bg-gray-light"/> + class="text-sm rounded-lg border px-4 py-3 w-full text-left text-green-dark/75 flex items-center justify-between hover:bg-blue-light/25 read-only:bg-gray-light"/> \ No newline at end of file diff --git a/src/web-service/frontend/src/lib/forms/Select.svelte b/src/web-service/frontend/src/lib/forms/SelectProducts.svelte similarity index 82% rename from src/web-service/frontend/src/lib/forms/Select.svelte rename to src/web-service/frontend/src/lib/forms/SelectProducts.svelte index cea656b6..635cb781 100644 --- a/src/web-service/frontend/src/lib/forms/Select.svelte +++ b/src/web-service/frontend/src/lib/forms/SelectProducts.svelte @@ -8,6 +8,7 @@ let listOpen: boolean = false; const itemId = 'id'; const label = 'description'; + const id = 'product'; let items: { id: number, description: string }[] = []; export let justValue: number; @@ -23,11 +24,12 @@
- Anzahl auswählen: -
+