Repository: digitalocean/kubernetes-sample-apps Branch: master Commit: 6d8ffb91dc26 Files: 206 Total size: 1.2 MB Directory structure: gitextract_b1f7n2wi/ ├── .github/ │ └── workflows/ │ ├── game-2048-kubescape.yaml │ ├── game-2048-snyk.yaml │ ├── online-boutique-main-ci.yaml │ ├── online-boutique-pr-ci.yaml │ ├── online-boutique-pr-kustomize-validation.yaml │ ├── online-boutique-release.yaml │ ├── online-boutique-snyk-docker-scan.yaml │ ├── online-boutique-snyk-iac-scan.yaml │ └── online-boutique-snyk-source-code-scan.yaml ├── .gitignore ├── README.md ├── bookinfo-example/ │ ├── README.md │ └── kustomize/ │ ├── kustomization.yaml │ └── resources/ │ └── namespace.yaml ├── doks-example/ │ ├── .travis.yml │ ├── Dockerfile │ ├── LICENSE │ ├── README.md │ ├── manifest.yaml │ ├── script/ │ │ ├── docker-publish │ │ ├── down │ │ ├── up │ │ └── wait-for-service │ └── web/ │ ├── index.html │ └── style.css ├── emojivoto-example/ │ ├── README.md │ └── kustomize/ │ ├── kustomization.yaml │ └── patches/ │ ├── emoji-svc.yaml │ └── voting-svc.yaml ├── game-2048-example/ │ ├── .dockerignore │ ├── .gitignore │ ├── Dockerfile │ ├── LICENSE │ ├── README.md │ ├── Tiltfile │ ├── knative-service.yaml │ ├── kustomize/ │ │ ├── kustomization.yaml │ │ └── resources/ │ │ ├── deployment.yaml │ │ ├── namespace.yaml │ │ └── service.yaml │ ├── package.json │ ├── src/ │ │ └── index.js │ └── webpack.config.js ├── microservices-demo/ │ ├── .gitignore │ ├── CODE_OF_CONDUCT.md │ ├── CONTRIBUTING.md │ ├── LICENSE │ ├── README.md │ ├── Tiltfile │ ├── kustomize/ │ │ ├── base/ │ │ │ ├── cartservice.yaml │ │ │ ├── checkoutservice.yaml │ │ │ ├── currencyservice.yaml │ │ │ ├── emailservice.yaml │ │ │ ├── frontend.yaml │ │ │ ├── kustomization.yaml │ │ │ ├── namespace.yaml │ │ │ ├── paymentservice.yaml │ │ │ ├── productcatalogservice.yaml │ │ │ ├── recommendationservice.yaml │ │ │ ├── redis.yaml │ │ │ └── shippingservice.yaml │ │ ├── dev/ │ │ │ └── kustomization.yaml │ │ ├── kustomization.yaml │ │ ├── prod/ │ │ │ └── kustomization.yaml │ │ └── staging/ │ │ └── kustomization.yaml │ ├── release-scripts/ │ │ ├── README.md │ │ ├── license_header.txt │ │ ├── make-cnb-docker-images.sh │ │ ├── make-docker-images.sh │ │ ├── make-release-artifacts.sh │ │ └── make-release.sh │ ├── src/ │ │ ├── .gitignore │ │ ├── cartservice/ │ │ │ ├── .gitignore │ │ │ ├── cartservice.sln │ │ │ ├── src/ │ │ │ │ ├── .dockerignore │ │ │ │ ├── Dockerfile │ │ │ │ ├── Dockerfile.debug │ │ │ │ ├── Program.cs │ │ │ │ ├── Startup.cs │ │ │ │ ├── appsettings.json │ │ │ │ ├── cartservice.csproj │ │ │ │ ├── cartstore/ │ │ │ │ │ ├── ICartStore.cs │ │ │ │ │ └── RedisCartStore.cs │ │ │ │ ├── protos/ │ │ │ │ │ └── Cart.proto │ │ │ │ └── services/ │ │ │ │ ├── CartService.cs │ │ │ │ └── HealthCheckService.cs │ │ │ └── tests/ │ │ │ ├── .gitignore │ │ │ ├── CartServiceTests.cs │ │ │ └── cartservice.tests.csproj │ │ ├── checkoutservice/ │ │ │ ├── .dockerignore │ │ │ ├── Dockerfile │ │ │ ├── README.md │ │ │ ├── genproto/ │ │ │ │ └── demo.pb.go │ │ │ ├── genproto.sh │ │ │ ├── go.mod │ │ │ ├── go.sum │ │ │ ├── main.go │ │ │ └── money/ │ │ │ ├── money.go │ │ │ └── money_test.go │ │ ├── currencyservice/ │ │ │ ├── .dockerignore │ │ │ ├── .gitignore │ │ │ ├── Dockerfile │ │ │ ├── client.js │ │ │ ├── data/ │ │ │ │ └── currency_conversion.json │ │ │ ├── genproto.sh │ │ │ ├── package.json │ │ │ ├── proto/ │ │ │ │ ├── demo.proto │ │ │ │ └── grpc/ │ │ │ │ └── health/ │ │ │ │ └── v1/ │ │ │ │ └── health.proto │ │ │ └── server.js │ │ ├── emailservice/ │ │ │ ├── .python-version │ │ │ ├── Dockerfile │ │ │ ├── Procfile │ │ │ ├── demo_pb2.py │ │ │ ├── demo_pb2_grpc.py │ │ │ ├── email_client.py │ │ │ ├── email_server.py │ │ │ ├── genproto.sh │ │ │ ├── logger.py │ │ │ ├── pytest.ini │ │ │ ├── requirements.in │ │ │ ├── requirements.txt │ │ │ ├── templates/ │ │ │ │ └── confirmation.html │ │ │ └── tests/ │ │ │ └── test_sample.py │ │ ├── frontend/ │ │ │ ├── .dockerignore │ │ │ ├── .gitkeep │ │ │ ├── Dockerfile │ │ │ ├── README.md │ │ │ ├── deployment_details.go │ │ │ ├── genproto/ │ │ │ │ └── demo.pb.go │ │ │ ├── genproto.sh │ │ │ ├── go.mod │ │ │ ├── go.sum │ │ │ ├── handlers.go │ │ │ ├── main.go │ │ │ ├── middleware.go │ │ │ ├── money/ │ │ │ │ ├── money.go │ │ │ │ └── money_test.go │ │ │ ├── rpc.go │ │ │ ├── static/ │ │ │ │ ├── images/ │ │ │ │ │ └── credits.txt │ │ │ │ └── styles/ │ │ │ │ ├── cart.css │ │ │ │ ├── order.css │ │ │ │ └── styles.css │ │ │ └── templates/ │ │ │ ├── ad.html │ │ │ ├── cart.html │ │ │ ├── error.html │ │ │ ├── footer.html │ │ │ ├── header.html │ │ │ ├── home.html │ │ │ ├── order.html │ │ │ ├── product.html │ │ │ └── recommendations.html │ │ ├── loadgenerator/ │ │ │ ├── Dockerfile │ │ │ ├── loadgenerator.yaml │ │ │ ├── locustfile.py │ │ │ ├── requirements.in │ │ │ └── requirements.txt │ │ ├── paymentservice/ │ │ │ ├── .dockerignore │ │ │ ├── .gitignore │ │ │ ├── Dockerfile │ │ │ ├── charge.js │ │ │ ├── genproto.sh │ │ │ ├── index.js │ │ │ ├── package.json │ │ │ ├── proto/ │ │ │ │ ├── demo.proto │ │ │ │ └── grpc/ │ │ │ │ └── health/ │ │ │ │ └── v1/ │ │ │ │ └── health.proto │ │ │ └── server.js │ │ ├── productcatalogservice/ │ │ │ ├── .dockerignore │ │ │ ├── Dockerfile │ │ │ ├── README.md │ │ │ ├── genproto/ │ │ │ │ └── demo.pb.go │ │ │ ├── genproto.sh │ │ │ ├── go.mod │ │ │ ├── go.sum │ │ │ ├── products.json │ │ │ ├── server.go │ │ │ └── server_test.go │ │ ├── recommendationservice/ │ │ │ ├── .gitignore │ │ │ ├── .python-version │ │ │ ├── Dockerfile │ │ │ ├── Procfile │ │ │ ├── client.py │ │ │ ├── demo_pb2.py │ │ │ ├── demo_pb2_grpc.py │ │ │ ├── genproto.sh │ │ │ ├── logger.py │ │ │ ├── pytest.ini │ │ │ ├── recommendation_server.py │ │ │ ├── requirements.in │ │ │ ├── requirements.txt │ │ │ └── tests/ │ │ │ └── test_sample.py │ │ └── shippingservice/ │ │ ├── .dockerignore │ │ ├── Dockerfile │ │ ├── README.md │ │ ├── genproto/ │ │ │ └── demo.pb.go │ │ ├── genproto.sh │ │ ├── go.mod │ │ ├── go.sum │ │ ├── main.go │ │ ├── quote.go │ │ ├── shippingservice_test.go │ │ └── tracker.go │ └── tilt-resources/ │ ├── dev/ │ │ └── tilt_config.json │ └── local/ │ └── tilt_config.json └── podinfo-example/ ├── README.md └── kustomize/ ├── kustomization.yaml └── resources/ └── namespace.yaml ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/workflows/game-2048-kubescape.yaml ================================================ name: Game 2048 Kubescape CI/CD Example on: # push: # branches: [ master ] # pull_request: # branches: [ master ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: inputs: kubescape_fail_threshold: description: "Sets fail threshold for Kubescape" required: true default: "30" env: ENVIRONMENT: "dev" PROJECT_DIR: "game-2048-example" PROJECT_NAME: "game-2048" KUBESCAPE_FAIL_THRESHOLD: 30 jobs: build-and-test-application: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 - name: npm install, build, and test run: | npm install npm run build --if-present npm test working-directory: ${{ env.PROJECT_DIR }} kubescape-nsa-security-check: runs-on: ubuntu-latest needs: build-and-test-application steps: - name: Checkout uses: actions/checkout@v3 - name: Install Kubescape run: curl -s https://raw.githubusercontent.com/armosec/kubescape/master/install.sh | /bin/bash - name: Scan Kubernetes YAML files run: | kubescape scan framework nsa kustomize/ \ -t ${{ github.event.inputs.kubescape_fail_threshold || env.KUBESCAPE_FAIL_THRESHOLD }} \ --submit --account=${{ secrets.ARMOSEC_PORTAL_ACCOUNT_ID }} working-directory: ${{ env.PROJECT_DIR }} - name: Notify using Slack about Kubescape Scan Issues if: ${{ always() }} uses: 8398a7/action-slack@v3 with: status: custom fields: workflow,job,commit,repo,ref,author,took custom_payload: | { attachments: [ { color: '${{ job.status }}' === 'success' ? 'good' : '${{ job.status }}' === 'failure' ? 'danger' : 'warning', text:` ${process.env.AS_WORKFLOW}\n *Environment*: ${process.env.ENVIRONMENT}\n *Job:* ${process.env.AS_JOB}\n *Commit:* (${process.env.AS_COMMIT})\n *Repo:* ${process.env.AS_REPO}\n *Ref:* ${process.env.AS_REF}\n *Author:* ${process.env.AS_AUTHOR}\n *Status:* ${{ job.status }} in ${process.env.AS_TOOK}\n *Kubescape scan results:* https://cloud.armosec.io/repositories-scan/ `, }] } env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} build-and-push-app-image: runs-on: ubuntu-latest needs: kubescape-nsa-security-check steps: - name: Checkout uses: actions/checkout@v3 - name: Install doctl uses: digitalocean/action-doctl@v2 with: token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} - name: Log in to DigitalOcean Container Registry with short-lived credentials run: doctl registry login --expiry-seconds 600 - name: Push App Image to DigitalOcean Container Registry uses: docker/build-push-action@v3 with: context: ${{ env.PROJECT_DIR }} push: true tags: "${{ secrets.DOCKER_REGISTRY }}/${{ env.PROJECT_NAME }}:${{ github.sha }}" deploy-to-k8s: runs-on: ubuntu-latest needs: build-and-push-app-image steps: - name: Checkout uses: actions/checkout@v3 - name: Install doctl uses: digitalocean/action-doctl@v2 with: token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} - name: Install kubectl uses: azure/setup-kubectl@v3 - name: Configure kubectl run: | doctl kubernetes cluster kubeconfig save ${{ secrets.DOKS_CLUSTER }} --expiry-seconds 600 - name: Configure app deployment registry run: | DOCKER_IMAGE="${{ secrets.DOCKER_REGISTRY }}/${{ env.PROJECT_NAME }}:${{ github.sha }}" sed -i "s#image:.*#image: ${DOCKER_IMAGE}#g" deployment.yaml working-directory: ${{ env.PROJECT_DIR }}/kustomize/resources/ - name: Deploy app to Kubernetes run: kubectl apply --prune --all -k kustomize/ working-directory: ${{ env.PROJECT_DIR }} ================================================ FILE: .github/workflows/game-2048-snyk.yaml ================================================ name: Game 2048 Snyk CI/CD Example on: # push: # branches: [ master ] # pull_request: # branches: [ master ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: inputs: snyk_fail_threshold: description: | Sets fail threshold for Snyk (low | medium | high | critical) required: true default: "medium" env: ENVIRONMENT: "dev" PROJECT_DIR: "game-2048-example" PROJECT_NAME: "game-2048" SNYK_FAIL_THRESHOLD: "medium" jobs: build-and-test-application: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 - name: npm install, build, and test run: | npm install npm run build --if-present npm test working-directory: ${{ env.PROJECT_DIR }} snyk-container-security-check: runs-on: ubuntu-latest needs: build-and-test-application steps: - name: Checkout uses: actions/checkout@v3 - name: Build App Image for Snyk container scanning uses: docker/build-push-action@v3 with: context: ${{ env.PROJECT_DIR }} push: false tags: "${{ secrets.DOCKER_REGISTRY }}/${{ env.PROJECT_NAME }}:${{ github.sha }}" - name: Install Snyk uses: snyk/actions/setup@master - name: Check application container vulnerabilities run: | snyk container test "${{ secrets.DOCKER_REGISTRY }}/${{ env.PROJECT_NAME }}:${{ github.sha }}" \ --file=${{ env.PROJECT_DIR }}/Dockerfile \ --severity-threshold=${{ github.event.inputs.snyk_fail_threshold || env.SNYK_FAIL_THRESHOLD }} \ --target-name=${{ env.PROJECT_NAME }} \ --target-reference=${{ env.ENVIRONMENT }} \ --sarif-file-output=snyk-container-scan.sarif env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} - name: Upload Snyk report SARIF file if: ${{ always() }} uses: github/codeql-action/upload-sarif@v2 with: sarif_file: snyk-container-scan.sarif category: snyk-container-scan - name: Notify using Slack about Snyk Scan Issues if: ${{ always() }} uses: 8398a7/action-slack@v3 with: status: custom fields: workflow,job,commit,repo,ref,author,took custom_payload: | { attachments: [ { color: '${{ job.status }}' === 'success' ? 'good' : '${{ job.status }}' === 'failure' ? 'danger' : 'warning', text:` ${process.env.AS_WORKFLOW}\n *Environment*: ${process.env.ENVIRONMENT}\n *Job:* ${process.env.AS_JOB}\n *Commit:* (${process.env.AS_COMMIT})\n *Repo:* ${process.env.AS_REPO}\n *Ref:* ${process.env.AS_REF}\n *Author:* ${process.env.AS_AUTHOR}\n *Status:* ${{ job.status }} in ${process.env.AS_TOOK}\n *Snyk scan results:* https://app.snyk.io `, }] } env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} build-and-push-app-image: runs-on: ubuntu-latest needs: snyk-container-security-check steps: - name: Checkout uses: actions/checkout@v3 - name: Install doctl uses: digitalocean/action-doctl@v2 with: token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} - name: Log in to DigitalOcean Container Registry with short-lived credentials run: doctl registry login --expiry-seconds 600 - name: Push App Image to DigitalOcean Container Registry uses: docker/build-push-action@v3 with: context: ${{ env.PROJECT_DIR }} push: true tags: "${{ secrets.DOCKER_REGISTRY }}/${{ env.PROJECT_NAME }}:${{ github.sha }}" snyk-iac-security-check: runs-on: ubuntu-latest needs: build-and-push-app-image steps: - name: Checkout uses: actions/checkout@v3 - name: Install Snyk uses: snyk/actions/setup@master - name: Check for Kubernetes manifests vulnerabilities run: | snyk iac test \ --severity-threshold=${{ github.event.inputs.snyk_fail_threshold || env.SNYK_FAIL_THRESHOLD }} \ --target-name=${{ env.PROJECT_NAME }} \ --target-reference=${{ env.ENVIRONMENT }} \ --sarif-file-output=snyk-iac-scan.sarif \ --report env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} working-directory: ${{ env.PROJECT_DIR }} - name: Upload Snyk IAC SARIF file if: ${{ always() }} uses: github/codeql-action/upload-sarif@v2 with: sarif_file: ${{ env.PROJECT_DIR }}/snyk-iac-scan.sarif category: snyk-iac-scan - name: Notify using Slack about Snyk Scan Issues if: ${{ always() }} uses: 8398a7/action-slack@v3 with: status: custom fields: workflow,job,commit,repo,ref,author,took custom_payload: | { attachments: [ { color: '${{ job.status }}' === 'success' ? 'good' : '${{ job.status }}' === 'failure' ? 'danger' : 'warning', text:` ${process.env.AS_WORKFLOW}\n *Environment*: ${process.env.ENVIRONMENT}\n *Job:* ${process.env.AS_JOB}\n *Commit:* (${process.env.AS_COMMIT})\n *Repo:* ${process.env.AS_REPO}\n *Ref:* ${process.env.AS_REF}\n *Author:* ${process.env.AS_AUTHOR}\n *Status:* ${{ job.status }} in ${process.env.AS_TOOK}\n *Snyk scan results:* https://app.snyk.io `, }] } env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} deploy-to-k8s: runs-on: ubuntu-latest needs: - snyk-iac-security-check - build-and-push-app-image steps: - name: Checkout uses: actions/checkout@v3 - name: Install doctl uses: digitalocean/action-doctl@v2 with: token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} - name: Install kubectl uses: azure/setup-kubectl@v3 - name: Configure kubectl run: | doctl kubernetes cluster kubeconfig save ${{ secrets.DOKS_CLUSTER }} --expiry-seconds 600 - name: Configure app deployment registry run: | IMAGE_TAG="${{ github.sha }}" DOCKER_IMAGE="${{ secrets.DOCKER_REGISTRY }}/${PROJECT_NAME}:${IMAGE_TAG}" sed -i "s#image:.*#image: ${DOCKER_IMAGE}#g" deployment.yaml working-directory: ${{ env.PROJECT_DIR }}/kustomize/resources/ - name: Deploy app to Kubernetes run: kubectl apply --prune --all -k kustomize/ working-directory: ${{ env.PROJECT_DIR }} ================================================ FILE: .github/workflows/online-boutique-main-ci.yaml ================================================ name: Online Boutique CI Main on: # Used for testing only (can be disabled afterwards) workflow_dispatch: # Uncomment below lines to enable this workflow on push to main events # push: # branches: # - main # paths-ignore: # - "**/README.md" # - "kustomize/**" # - "argocd/**" # - ".github/workflows/*" # Do not allow concurrent workflows # Changes should be delivered one a time as code is merged into the main branch concurrency: main-ci-dev # Global environment variables env: CI_COMMIT_AUTHOR: "GitHub CI Actions" CI_COMMIT_AUTHOR_EMAIL: "gh-ci-actions@noreply.github.com" DOCR_ENDPOINT: "registry.digitalocean.com/microservices-demo" PROJECT_NAME: "online-boutique" jobs: # There's no point to run unit tests again after PR merge # Unit testing deals with changes for the affected components, # and that it is already taken care in the PR workflow # What it makes sense, is to run integration tests, # to see if the whole application is impacted after merging the changes # # Run deployment tests (integration tests) # Please bear in mind that more tests means increased workflow run time # With workflow concurrency disabled, means more waiting time for other PRs in the queue deployment-tests: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 - name: Run integration tests run: | echo "[INFO] Not implemented yet!" # Build and push project images in parallel using a matrix strategy # Cuts down build time build-and-push-images: needs: deployment-tests runs-on: ubuntu-latest strategy: matrix: project: - cartservice - checkoutservice - currencyservice - emailservice - frontend - paymentservice - productcatalogservice - recommendationservice - shippingservice steps: - name: Checkout code uses: actions/checkout@v3 - name: Install doctl uses: digitalocean/action-doctl@v2 with: token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} - name: Log in to DOCR with short-lived credentials run: doctl registry login --expiry-seconds 600 - name: Build and push image uses: docker/build-push-action@v3 with: # cartservice is an exception - Dockerfile is placed in src/cartservice/src subfolder context: "src/${{ matrix.project }}/${{ matrix.project == 'cartservice' && 'src' || ''}}" push: true tags: "${{ env.DOCR_ENDPOINT }}/${{ matrix.project }}:${{ github.sha }}" # Kustomize image field for each microservice present in the `src/` dir # Finally, commit changes to main branch and let ArgoCD take over afterwards apply-kustomize-changes: needs: build-and-push-images runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 - name: Set up K8S tools uses: yokawasa/action-setup-kube-tools@v0.8.2 with: kustomize: "4.5.7" - name: Kustomize dev environment images run: | for microservice in src/*/; do microservice="$(basename $microservice)" if [[ "$microservice" == "loadgenerator" ]]; then continue fi ( cd kustomize/dev kustomize edit set image $microservice=${{ env.DOCR_ENDPOINT }}/${microservice}:${{ github.sha }} ) done - name: Commit Kustomize manifests for dev env run: | git config --global user.name "${{ env.CI_COMMIT_AUTHOR }}" git config --global user.email "${{ env.CI_COMMIT_AUTHOR_EMAIL }}" git add kustomize/dev/ git commit -m "[CI] Bump docker images tag to ${{ github.sha }}" - name: Push changes uses: ad-m/github-push-action@master with: github_token: ${{ secrets.GITHUB_TOKEN }} ================================================ FILE: .github/workflows/online-boutique-pr-ci.yaml ================================================ name: Online Boutique PR CI on: # Used for testing only (can be disabled afterwards) workflow_dispatch: # Uncomment below lines to enable this workflow on main branch PR events # pull_request: # branches: # - main # paths-ignore: # - "**/README.md" # - "kustomize/**" # - "argocd/**" # - ".github/workflows/*" # Do not allow concurrent workflows for PRs # If disabled, leads to memory exhaustion on the DOKS dev cluster concurrency: pr-ci-dev # Global environment variables env: DOCR_ENDPOINT: "registry.digitalocean.com/microservices-demo" CLUSTER_NAME: "microservices-demo-dev" REGION: "nyc1" K8S_NAMESPACE: "microservices-demo-${{ github.event.pull_request.number }}" PROJECT_NAME: "online-boutique" jobs: # Run unit tests in parallel using below matrix to cut down time # Unit tests are standalone and should not raise conflicts # Each microservice is written in a specific language, hence it's added to the matrix unit-tests: runs-on: ubuntu-latest strategy: matrix: include: - project_name: cartservice project_language: csharp - project_name: checkoutservice project_language: golang - project_name: currencyservice project_language: javascript - project_name: emailservice project_language: python - project_name: frontend project_language: golang - project_name: paymentservice project_language: javascript - project_name: productcatalogservice project_language: golang - project_name: recommendationservice project_language: python - project_name: shippingservice project_language: golang steps: - name: Checkout code uses: actions/checkout@v3 with: ref: ${{github.event.pull_request.head.ref}} repository: ${{github.event.pull_request.head.repo.full_name}} - name: Set up Go env if: ${{ matrix.project_language == 'golang' }} uses: actions/setup-go@v3 with: go-version: "1.19" - name: Go Unit Tests if: ${{ matrix.project_language == 'golang' }} timeout-minutes: 5 run: | ( cd src/${{ matrix.project_name }} go test ) - name: Set up C# env if: ${{ matrix.project_language == 'csharp' }} uses: actions/setup-dotnet@v2 with: dotnet-version: "6.0" include-prerelease: true - name: C# Unit Tests if: ${{ matrix.project_language == 'csharp' }} timeout-minutes: 5 run: dotnet test src/${{ matrix.project_name }}/ - name: Set up NodeJS env if: ${{ matrix.project_language == 'javascript' }} uses: actions/setup-node@v3 with: node-version: 18 - name: Javascript Unit Tests if: ${{ matrix.project_language == 'javascript' }} timeout-minutes: 5 run: | ( cd src/${{ matrix.project_name }} npm install npm run test ) - name: Set up Python env if: ${{ matrix.project_language == 'python' }} uses: actions/setup-python@v3 with: python-version: "3.7" - name: Python Unit Tests if: ${{ matrix.project_language == 'python' }} timeout-minutes: 5 run: | ( cd src/${{ matrix.project_name }} pip install -r requirements.txt pytest ) # Run deployment tests (smoke tests) # You can add integration tests as well # Please bear in mind that more tests means increased workflow run time # With workflow concurrency disabled, means more waiting time for other PRs in the queue deployment-tests: needs: unit-tests runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 with: ref: ${{github.event.pull_request.head.ref}} repository: ${{github.event.pull_request.head.repo.full_name}} - name: Install doctl uses: digitalocean/action-doctl@v2 with: token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} - name: Log in to DOCR with short-lived credentials run: doctl registry login --expiry-seconds 1200 - name: Set up K8S tools uses: yokawasa/action-setup-kube-tools@v0.8.2 with: kubectl: "1.25.2" kustomize: "4.5.7" tilt: "0.30.9" - name: Configure kubectl for DOKS with short-lived credentials run: doctl kubernetes cluster kubeconfig save ${{ env.CLUSTER_NAME }} --expiry-seconds 1200 - name: Deploy microservices to DOKS timeout-minutes: 10 run: | # Bring all microservices up using Tilt and wait for all deployments cp tilt-resources/dev/tilt_config.json . tilt ci -- \ --allowed_contexts "do-${{ env.REGION }}-${{ env.CLUSTER_NAME }}" \ --default_registry "${{ env.DOCR_ENDPOINT }}" \ --environment "dev" \ --namespace "${{ env.K8S_NAMESPACE }}" - name: Build loadgenerator image uses: docker/build-push-action@v3 with: context: "src/loadgenerator" push: true tags: "${{ env.DOCR_ENDPOINT }}/loadgenerator" - name: Smoke tests timeout-minutes: 10 run: | # Prepare load generator # Inject workflow custom docker image sed -i "s##${{ env.DOCR_ENDPOINT }}/loadgenerator#g" loadgenerator.yaml # Deploy load generator kubectl apply -f loadgenerator.yaml -n ${{ env.K8S_NAMESPACE }} # Wait for load generator deployment to be ready kubectl wait --for=condition=available --timeout=60s deployment/loadgenerator -n ${{ env.K8S_NAMESPACE }} || { # Show why load generator failed to start echo "[INFO] Load generator pod events" kubectl describe pod -l app=loadgenerator -n ${{ env.K8S_NAMESPACE }} | tail -10 exit 1 } # Run smoke tests REQUEST_COUNT="0" while [[ "$REQUEST_COUNT" -lt "50" ]]; do sleep 5 REQUEST_COUNT=$(kubectl logs -l app=loadgenerator -n ${{ env.K8S_NAMESPACE }} | grep Aggregated | awk '{print $2}') done # ensure there are no errors hitting endpoints ERROR_COUNT=$(kubectl logs -l app=loadgenerator -n ${{ env.K8S_NAMESPACE }} | grep Aggregated | awk '{print $3}' | sed "s/[(][^)]*[)]//g") if [[ "$ERROR_COUNT" -gt "0" ]]; then # Print final results echo "[INFO] Load generator results" kubectl logs -l app=loadgenerator -n ${{ env.K8S_NAMESPACE }} | tail -20 exit 1 fi # Print final results echo "[INFO] Load generator results" kubectl logs -l app=loadgenerator -n ${{ env.K8S_NAMESPACE }} | tail -20 working-directory: "src/loadgenerator" - name: Clean up Tilt microservices environment if: ${{ always() }} run: | # Remove all microservices and the namespace created by Tilt tilt down --delete-namespaces -- --namespace "${{ env.K8S_NAMESPACE }}" - name: Clean up Tilt docker images from registry if: ${{ always() }} run: | # Remove Tilt docker images from registry for tilt_repo in $(docker images --format "{{.Repository}}:{{.Tag}}" | grep "tilt-.*[a-z|0-9]"); do repo_and_tag="${tilt_repo##*/}" repo="${repo_and_tag%%:*}" tag="${repo_and_tag##*:}" echo "[INFO] Deleting tag $tag from repo $repo ..." doctl registry repository delete-tag "$repo" "$tag" -f done echo "[INFO] Remember to run the DOCR garbage collector from time to time!" ================================================ FILE: .github/workflows/online-boutique-pr-kustomize-validation.yaml ================================================ name: Online Boutique PR Kustomize Validation on: workflow_dispatch: # pull_request: # branches: # - main # paths: # - "kustomize/**" env: KUBECONFORM_VERSION: "0.5.0" KUBERNETES_VERSION: "1.24.4" jobs: job: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 - name: Set up kubeconform run: | ( cd /tmp wget "https://github.com/yannh/kubeconform/releases/download/v${{ env.KUBECONFORM_VERSION }}/kubeconform-linux-amd64.tar.gz" tar xvf kubeconform-linux-amd64.tar.gz chmod u+x ./kubeconform ) - name: Kustomize linting using kubeconform run: | # Test each overlay using kubeconform for kustomize_overlay in kustomize/*/; do kustomize build "$kustomize_overlay" | \ /tmp/kubeconform -kubernetes-version "${{env.KUBERNETES_VERSION}}" -summary -verbose done ================================================ FILE: .github/workflows/online-boutique-release.yaml ================================================ name: Online Boutique Release on: workflow_dispatch: # push: # # Trigger on push events to any tag matching semantic versioning # tags: # - 'v[0-9]+\.[0-9]+\.[0-9]+' env: RELEASE_COMMIT_AUTHOR: "GitHub Release Actions" RELEASE_COMMIT_AUTHOR_EMAIL: "gh-release-actions@noreply.github.com" DOCR_ENDPOINT: "registry.digitalocean.com/microservices-demo" PROJECT_NAME: "online-boutique" jobs: validation-tests: runs-on: ubuntu-latest steps: - run: echo "[INFO] Not implemented yet!" build-and-push-release-images: needs: validation-tests runs-on: ubuntu-latest strategy: matrix: project: - cartservice - checkoutservice - currencyservice - emailservice - frontend - paymentservice - productcatalogservice - recommendationservice - shippingservice steps: - name: Checkout code uses: actions/checkout@v3 - name: Install doctl uses: digitalocean/action-doctl@v2 with: token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} - name: Log in to DOCR with short-lived credentials run: doctl registry login --expiry-seconds 600 - name: Build and push image uses: docker/build-push-action@v3 with: # cartservice is an exception - Dockerfile is placed in src/cartservice/src subfolder context: "src/${{ matrix.project }}/${{ matrix.project == 'cartservice' && 'src' || ''}}" push: true tags: "${{ env.DOCR_ENDPOINT }}/${{ matrix.project }}:${{ github.ref_name }}" # Kustomize image field for each microservice present in the `src/` dir # Finally, commit changes to main branch and let ArgoCD take over afterwards apply-kustomize-changes: needs: build-and-push-release-images runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 - name: Set up K8S tools uses: yokawasa/action-setup-kube-tools@v0.8.2 with: kustomize: "4.5.7" - name: Kustomize staging environment images run: | for microservice in src/*/; do microservice="$(basename $microservice)" if [[ "$microservice" == "loadgenerator" ]]; then continue fi ( cd kustomize/staging/ kustomize edit set image $microservice=${{ env.DOCR_ENDPOINT }}/${microservice}:${{ github.ref_name }} ) done - name: Commit Kustomize manifests for staging env run: | git config --global user.name "${{ env.RELEASE_COMMIT_AUTHOR }}" git config --global user.email "${{ env.RELEASE_COMMIT_AUTHOR_EMAIL }}" git add kustomize/staging/ git commit -m "[Release] Bump docker images tag to ${{ github.ref_name }}" - name: Push changes uses: ad-m/github-push-action@master with: github_token: ${{ secrets.GITHUB_TOKEN }} ================================================ FILE: .github/workflows/online-boutique-snyk-docker-scan.yaml ================================================ name: Online Boutique Snyk Docker Scan on: # pull_request: # branches: # - main # paths: # - "src/**/Dockerfile" # Below configuration is used for manual workflow dispatch workflow_dispatch: inputs: snyk_fail_threshold: description: | Sets fail threshold for Snyk (low | medium | high | critical) required: true default: "high" env: DOCR_ENDPOINT: "registry.digitalocean.com/microservices-demo" PROJECT_NAME: "online-boutique" SNYK_FAIL_THRESHOLD: "high" jobs: container-security-check: runs-on: ubuntu-latest strategy: fail-fast: false matrix: project: - cartservice - checkoutservice - currencyservice - emailservice - frontend - paymentservice - productcatalogservice - recommendationservice - shippingservice steps: - name: Checkout uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.ref }} repository: ${{ github.event.pull_request.head.repo.full_name }} - name: Install Snyk uses: snyk/actions/setup@master - name: Build app image for Snyk container scanning uses: docker/build-push-action@v3 with: # Cartservice is an exception - Dockerfile is placed in `src/cartservice/src` subfolder context: "src/${{ matrix.project }}/${{ matrix.project == 'cartservice' && 'src' || ''}}" push: false tags: "${{ env.DOCR_ENDPOINT }}/${{ matrix.project }}:${{ github.event.pull_request.head.sha }}" - name: Check application container vulnerabilities run: | # Cartservice is an exception regarding project layout # It uses a nested src subfolder - `src/cartservice/src` if [[ "${{ matrix.project }}" == "cartservice" ]]; then cd src/ fi snyk container test "${{ env.DOCR_ENDPOINT }}/${{ matrix.project }}:${{ github.event.pull_request.head.sha }}" \ --file=Dockerfile \ --severity-threshold=${{ github.event.inputs.snyk_fail_threshold || env.SNYK_FAIL_THRESHOLD }} \ --target-name=${{ env.PROJECT_NAME }} \ --target-reference=${{ matrix.project }} env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} working-directory: "src/${{ matrix.project }}" ================================================ FILE: .github/workflows/online-boutique-snyk-iac-scan.yaml ================================================ name: Online Boutique Snyk IAC Scan on: # pull_request: # branches: # - main # paths: # - "argocd/**" # - "kustomize/**" # Below configuration is used for manual workflow dispatch workflow_dispatch: inputs: snyk_fail_threshold: description: | Sets fail threshold for Snyk (low | medium | high | critical) required: true default: "high" env: PROJECT_NAME: "online-boutique" SNYK_FAIL_THRESHOLD: "high" jobs: iac-security-check: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.ref }} repository: ${{ github.event.pull_request.head.repo.full_name }} - name: Install Snyk uses: snyk/actions/setup@master - name: Check for Kubernetes manifests vulnerabilities run: | snyk iac test \ --severity-threshold=${{ github.event.inputs.snyk_fail_threshold || env.SNYK_FAIL_THRESHOLD }} \ --target-name=${{ env.PROJECT_NAME }} \ --target-reference="kustomize-PR#${{ github.event.pull_request.number }}" \ --report env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} working-directory: kustomize - name: Check for Argo CD manifests vulnerabilities run: | snyk iac test \ --severity-threshold=${{ github.event.inputs.snyk_fail_threshold || env.SNYK_FAIL_THRESHOLD }} \ --target-name=${{ env.PROJECT_NAME }} \ --target-reference="argocd-PR#${{ github.event.pull_request.number }}" \ --report env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} working-directory: argocd ================================================ FILE: .github/workflows/online-boutique-snyk-source-code-scan.yaml ================================================ name: Online Boutique Snyk Source Code Scan on: # pull_request: # branches: # - main # paths: # - "src/**" # Below configuration is used for manual workflow dispatch workflow_dispatch: inputs: snyk_fail_threshold: description: | Sets fail threshold for Snyk (low | medium | high | critical) required: true default: "high" env: PROJECT_NAME: "online-boutique" SNYK_FAIL_THRESHOLD: "high" jobs: source-code-security-check: runs-on: ubuntu-latest strategy: fail-fast: false matrix: include: - project_name: cartservice project_language: dotnet - project_name: checkoutservice project_language: golang - project_name: currencyservice project_language: node - project_name: emailservice project_language: python - project_name: frontend project_language: golang - project_name: paymentservice project_language: node - project_name: productcatalogservice project_language: golang - project_name: recommendationservice project_language: python - project_name: shippingservice project_language: golang steps: - name: Checkout uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.ref }} repository: ${{ github.event.pull_request.head.repo.full_name }} - name: Install Snyk uses: snyk/actions/setup@master - name: Setup dotnet if: ${{ matrix.project_language == 'dotnet' }} uses: actions/setup-dotnet@v3 with: dotnet-version: '6.0' - name: Restore dotnet project dependencies if: ${{ matrix.project_language == 'dotnet' }} run: dotnet restore working-directory: "src/${{ matrix.project_name }}" - name: Set up Python env if: ${{ matrix.project_language == 'python' }} uses: actions/setup-python@v3 with: python-version: "3.7" - name: Install Python project dependencies if: ${{ matrix.project_language == 'python' }} run: pip install -r requirements.txt working-directory: "src/${{ matrix.project_name }}" - name: Check application source code for vulnerabilities run: | # Cartservice is an exception regarding project layout # It uses a nested src subfolder - `src/cartservice/src` if [[ "${{ matrix.project_name }}" == "cartservice" ]]; then cd src/ fi snyk code test \ --severity-threshold=${{ github.event.inputs.snyk_fail_threshold || env.SNYK_FAIL_THRESHOLD }} env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} working-directory: "src/${{ matrix.project_name }}" - name: Check 3rd party source code for vulnerabilities run: | # Cartservice is an exception regarding project layout # It uses a nested src subfolder - `src/cartservice/src` if [[ "${{ matrix.project_name }}" == "cartservice" ]]; then cd src/ fi snyk test \ --severity-threshold=${{ github.event.inputs.snyk_fail_threshold || env.SNYK_FAIL_THRESHOLD }} \ --project-name=${{ env.PROJECT_NAME }} \ --target-reference=${{ matrix.project_name }} env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} working-directory: "src/${{ matrix.project_name }}" ================================================ FILE: .gitignore ================================================ # macOS .DS_Store ================================================ FILE: README.md ================================================ # DigitalOcean Kubernetes Sample Apps This repository contains a collection of Kubernetes applications that can be used in various projects. Each sample application has a dedicated folder to keep all resources, and main documentation. Kubernetes sample applications provided by this repository: - [bookinfo-example](bookinfo-example/) - Deploy the [Bookinfo](https://istio.io/latest/docs/examples/bookinfo) sample application. - [doks-example](doks-example/) - Deploy your first application (workload) to a fresh DOKS cluster. - [emojivoto-example](emojivoto-example/) - Deploy the [Emojivoto](https://github.com/BuoyantIO/emojivoto) sample application. - [game-2048-example](game-2048-example/) - Build and deploy the [2048 game](https://en.wikipedia.org/wiki/2048_(video_game)) application. - [podinfo-example](podinfo-example/) - Deploy the [Podinfo](https://github.com/stefanprodan/podinfo) sample application. ================================================ FILE: bookinfo-example/README.md ================================================ # Overview The [Bookinfo](https://istio.io/latest/docs/examples/bookinfo) application displays information about a book, similar to a single catalog entry of an online book store. Displayed on the page is a description of the book, book details (ISBN, number of pages, and so on), and a few book reviews. The `Bookinfo` application is broken into four separate microservices: - `productpage` - calls the details and reviews microservices to populate the page. - `details` - contains book information. - `reviews` - contains book reviews. It also calls the ratings microservice. - `ratings` - contains book ranking information that accompanies a book review. Please visit the [Bookinfo application](https://istio.io/latest/docs/examples/bookinfo) documentation page for more details. ## Requirements To complete all steps and deploy the `Bookinfo` sample application, you will need: 1. A [DOKS](https://docs.digitalocean.com/products/kubernetes/quickstart) cluster configured and running. 2. Latest [Kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) version for Kubernetes interaction. 3. [Git](https://git-scm.com/downloads) client for interacting with the [kubernetes-sample-apps](https://github.com/digitalocean/kubernetes-sample-apps) repository. ## Deploying to Kubernetes The [kustomization manifest](kustomize/kustomization.yaml) provided in this repository will get you started with deploying the `Bookinfo` application Kubernetes resources. First, you need to clone this repository: ```shell git clone https://github.com/digitalocean/kubernetes-sample-apps.git ``` Then, change directory to your local copy: ```shell cd kubernetes-sample-apps ``` Now, create Bookinfo sample application Kubernetes resources using the kubectl kustomize option (`-k` flag): ```shell kubectl apply -k bookinfo-example/kustomize ``` The output looks similar to: ```text namespace/bookinfo created serviceaccount/bookinfo-details created serviceaccount/bookinfo-productpage created serviceaccount/bookinfo-ratings created serviceaccount/bookinfo-reviews created service/details created service/productpage created service/ratings created service/reviews created deployment.apps/details-v1 created deployment.apps/productpage-v1 created deployment.apps/ratings-v1 created deployment.apps/reviews-v1 created deployment.apps/reviews-v2 created deployment.apps/reviews-v3 created ``` If everything went well, you should have a new Kubernetes namespace created named `bookinfo`. Inside the new namespace, you can inspect all resources created by the kustomization manifest from the sample apps repository (all Bookinfo application pods should be up and running): ```shell kubectl get all -n bookinfo ``` The output looks similar to: ```text NAME READY STATUS RESTARTS AGE pod/details-v1-7694bf8b6f-zgdts 1/1 Running 0 82m pod/productpage-v1-659d8f84c9-cr446 1/1 Running 0 82m pod/ratings-v1-65785878bf-7kr2h 1/1 Running 0 82m pod/reviews-v1-b98448d4f-zrfbd 1/1 Running 0 82m pod/reviews-v2-867f95557c-shsw9 1/1 Running 0 81m pod/reviews-v3-7c769464df-gbv5x 1/1 Running 0 81m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/details ClusterIP 10.245.223.202 9080/TCP 82m service/productpage ClusterIP 10.245.139.105 9080/TCP 82m service/ratings ClusterIP 10.245.229.118 9080/TCP 82m service/reviews ClusterIP 10.245.227.244 9080/TCP 82m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/details-v1 1/1 1 1 82m deployment.apps/productpage-v1 1/1 1 1 82m deployment.apps/ratings-v1 1/1 1 1 82m deployment.apps/reviews-v1 1/1 1 1 82m deployment.apps/reviews-v2 1/1 1 1 82m deployment.apps/reviews-v3 1/1 1 1 82m NAME DESIRED CURRENT READY AGE replicaset.apps/details-v1-7694bf8b6f 1 1 1 82m replicaset.apps/productpage-v1-659d8f84c9 1 1 1 82m replicaset.apps/ratings-v1-65785878bf 1 1 1 82m replicaset.apps/reviews-v1-b98448d4f 1 1 1 82m replicaset.apps/reviews-v2-867f95557c 1 1 1 82m replicaset.apps/reviews-v3-7c769464df 1 1 1 82m ``` Finally, port-forward the `productpage` service using `kubectl`: ```shell kubectl port-forward service/productpage -n bookinfo 9080:9080 ``` Open a web browser and point to [localhost:9080](http://localhost:9080/). You should see the `productpage` service welcome page: ![Product Page Welcome](assets/images/product-page-welcome.png) ## Cleaning Up To clean up all Kubernetes resources created by the Bookinfo sample application, below command must be used: ```shell kubectl delete ns bookinfo ``` **Note:** Kubectl kustomize subcommand has a delete option that can be used - `kubectl delete -k bookinfo-example/kustomize`. But, it won't work well in this case because if the namespace is deleted first then the remaining operations will fail. ================================================ FILE: bookinfo-example/kustomize/kustomization.yaml ================================================ ## Bookinfo Sample Application Kustomization apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization # Making sure all resources used in this tutorial are created in a dedicated namespace # Also specific annotations are added for later identification namespace: bookinfo commonAnnotations: provider: kubernetes-sample-apps # Bookinfo resources (namespace, services, deployments, etc) resources: - resources/namespace.yaml - https://raw.githubusercontent.com/istio/istio/release-1.14/samples/bookinfo/platform/kube/bookinfo.yaml # If you want to apply Istio configuration on top of the bookinfo deployment, uncomment below lines (assuming you have Istio already installed) # - https://raw.githubusercontent.com/istio/istio/release-1.14/samples/bookinfo/networking/bookinfo-gateway.yaml # - https://raw.githubusercontent.com/istio/istio/release-1.14/samples/bookinfo/networking/destination-rule-all.yaml ================================================ FILE: bookinfo-example/kustomize/resources/namespace.yaml ================================================ apiVersion: v1 kind: Namespace metadata: name: bookinfo ================================================ FILE: doks-example/.travis.yml ================================================ services: - 'docker' script: - docker build -t doks-example . - docker run --rm -it doks-example sleep 1 notifications: email: false ================================================ FILE: doks-example/Dockerfile ================================================ FROM nginx ADD web /usr/share/nginx/html ================================================ FILE: doks-example/LICENSE ================================================ MIT License Copyright (c) 2019 DigitalOcean Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: doks-example/README.md ================================================ [![Build Status](https://travis-ci.org/digitalocean/doks-example.svg?branch=master)](https://travis-ci.org/digitalocean/doks-example) # Getting Started 1. Create your Kubernetes cluster: `doctl k8s cluster create example` 1. Check that your cluster is available: `kubectl --context do-nyc1-example get nodes` 1. Deploy a workload to your cluster: `kubectl --context do-nyc1-example apply -f manifest.yaml` 1. Wait for the service to be ready: `script/wait-for-service do-nyc1-example doks-example` 1. Open the returned IP address in your browser, or run `open http://$(kubectl --context do-nyc1-example get service doks-example --template="{{range .status.loadBalancer.ingress}}{{.ip}}{{end}}")` Or you can just run `script/up` to do all of this. ## Cleaning up Run `script/down` to tear down the cluster and remove the load-balancer. **Note:** If you delete the cluster directly, the load-balancer will stick around and result in charges. ================================================ FILE: doks-example/manifest.yaml ================================================ --- kind: Service apiVersion: v1 metadata: name: doks-example spec: type: LoadBalancer selector: app: doks-example ports: - name: http protocol: TCP port: 80 targetPort: 80 --- apiVersion: apps/v1 kind: Deployment metadata: name: doks-example spec: replicas: 2 selector: matchLabels: app: doks-example template: metadata: labels: app: doks-example spec: containers: - name: nginx image: digitalocean/doks-example ports: - containerPort: 80 protocol: TCP ================================================ FILE: doks-example/script/docker-publish ================================================ #!/usr/bin/env bash set -euo pipefail TARGET="digitalocean/doks-example" docker build -t ${TARGET} . docker push ${TARGET} ================================================ FILE: doks-example/script/down ================================================ #!/usr/bin/env bash set -euo pipefail CLUSTER="example" doctl compute load-balancer delete --force $(kubectl get svc doks-example -o jsonpath="{.metadata.annotations.kubernetes\.digitalocean\.com/load-balancer-id}") doctl k8s cluster delete ${CLUSTER} ================================================ FILE: doks-example/script/up ================================================ #!/usr/bin/env bash set -euo pipefail CLUSTER="example" SERVICE="doks-example" CONTEXT="do-nyc1-${CLUSTER}" doctl k8s cluster create ${CLUSTER} kubectl --context ${CONTEXT} apply -f manifest.yaml script/wait-for-service ${CONTEXT} ${SERVICE} open http://$(kubectl --context ${CONTEXT} get service ${SERVICE} --template="{{range .status.loadBalancer.ingress}}{{.ip}}{{end}}") ================================================ FILE: doks-example/script/wait-for-service ================================================ #!/usr/bin/env bash # Pass the name of a service to check: sh wait-for-service.sh example set -euo pipefail EXTERNAL_IP="" CONTEXT="$1" SERVICE="$2" while [ -z $EXTERNAL_IP ]; do EXTERNAL_IP=$(kubectl --context ${CONTEXT} get service ${SERVICE} --template="{{range .status.loadBalancer.ingress}}{{.ip}}{{end}}") if [ -z "${EXTERNAL_IP}" ]; then echo "Waiting for external IP..." sleep 10 fi done echo "Ready: ${EXTERNAL_IP}" ================================================ FILE: doks-example/web/index.html ================================================ Welcome to DOKS

Welcome to DOKS

Congratulations, you deployed your first workload! You have just created a Deployment responsible for managing 2 instances of Pod workloads running the docker image given in the manifest. In addition to this Deployment, you have also configured a Service of type LoadBalancer that exposes the Deployment publicly using a DigitalOcean Load Balancer, which is a paid service.

Here's what's running:

---
kind: Service
apiVersion: v1
metadata:
  name: doks-example
spec:
  type: LoadBalancer
  selector:
    app: doks-example
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: doks-example
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: doks-example
    spec:
      containers:
      - name: nginx
        image: digitalocean/doks-example
        ports:
        - containerPort: 80
          protocol: TCP
                        

Learn more about DigitalOcean Kubernetes Service

================================================ FILE: doks-example/web/style.css ================================================ html { height: 100%; } body { margin: 0; padding: 25px; height: 100%; background-color: #0a1e99; background-image: url("/bg.png"); background-repeat: no-repeat; background-position: right bottom; background-size: 800px; } main { margin: auto; width: 900px; } h1, h2, h3 { color: white; } pre { border: 0; background-color: #031b4d; color: white; wdith: 100%; max-height: 400px; overflow: scroll; } .Header { opacity: 0.5; color: white; fill: white; } #welcome { color: white; } #welcome span.bui-u-textCode { background-color: #031b4d; border: 0; } #running { color: white; } #more { margin-top: 30px; font-size: 80%; } .more-item { padding: 20px; background-color: white; border-radius: 5px; } .more-item h3 { padding: 0; margin: 10px 0 10px 0; } .more-type { text-transform: uppercase; font-size: 80%; } #footer { background-color: transparent; color: white; font-size: 60%; } #footer a, #footer a:hover { color: white; } ================================================ FILE: emojivoto-example/README.md ================================================ # Overview [Emojivoto](https://github.com/BuoyantIO/emojivoto) is a microservice application that allows users to vote for their favorite emoji, and tracks votes received on a leaderboard. May the best emoji win. The application is composed of the following 3 services: * [emojivoto-web](https://github.com/BuoyantIO/emojivoto/tree/main/emojivoto-web): Web frontend and REST API. * [emojivoto-emoji-svc](https://github.com/BuoyantIO/emojivoto/tree/main/emojivoto-emoji-svc): gRPC API for finding and listing emoji. * [emojivoto-voting-svc](https://github.com/BuoyantIO/emojivoto/blob/main/emojivoto-voting-svc): gRPC API for voting and leaderboard. Please visit the [Emojivoto](https://github.com/BuoyantIO/emojivoto) documentation page for more details. ## Requirements To complete all steps and deploy the `Emojivoto` sample application, you will need: 1. A [DOKS](https://docs.digitalocean.com/products/kubernetes/quickstart) cluster configured and running. 2. Latest [Kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) version for Kubernetes interaction. 3. [Git](https://git-scm.com/downloads) client for interacting with the [kubernetes-sample-apps](https://github.com/digitalocean/kubernetes-sample-apps) repository. ## Deploying to Kubernetes The [kustomization manifest](kustomize/kustomization.yaml) provided in this repository will get you started with deploying the `Emojivoto` application Kubernetes resources. First, you need to clone this repository: ```shell git clone https://github.com/digitalocean/kubernetes-sample-apps.git ``` Then, change directory to your local copy: ```shell cd kubernetes-sample-apps ``` Now, create Emojivoto sample application Kubernetes resources using the kubectl kustomize option (`-k` flag): ```shell kubectl apply -k emojivoto-example/kustomize ``` The output looks similar to: ```text namespace/emojivoto created serviceaccount/emoji created serviceaccount/voting created serviceaccount/web created service/emoji-svc created service/voting-svc created service/web-svc created deployment.apps/emoji created deployment.apps/vote-bot created deployment.apps/voting created deployment.apps/web created ``` If everything went well, you should have a new Kubernetes namespace created named `emojivoto`. Inside the new namespace, you can inspect all resources created by the kustomization manifest from the sample apps repository (all Emojivoto application pods should be up and running): ```shell kubectl get all -n emojivoto ``` The output looks similar to: ```text NAME READY STATUS RESTARTS AGE pod/emoji-84cd97f89b-cpz4l 1/1 Running 0 10m pod/vote-bot-5b587bbff7-wqv8t 1/1 Running 0 10m pod/voting-74ff7f8b55-5wbgt 1/1 Running 0 10m pod/web-7dfbdc8bf5-247t9 1/1 Running 0 9m59s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/emoji-svc ClusterIP 10.245.140.136 8080/TCP,8801/TCP 10m service/voting-svc ClusterIP 10.245.217.36 8080/TCP,8801/TCP 10m service/web-svc ClusterIP 10.245.137.75 80/TCP 10m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/emoji 1/1 1 1 10m deployment.apps/vote-bot 1/1 1 1 10m deployment.apps/voting 1/1 1 1 10m deployment.apps/web 1/1 1 1 10m NAME DESIRED CURRENT READY AGE replicaset.apps/emoji-84cd97f89b 1 1 1 10m replicaset.apps/vote-bot-5b587bbff7 1 1 1 10m replicaset.apps/voting-74ff7f8b55 1 1 1 10m replicaset.apps/web-7dfbdc8bf5 1 1 1 10m ``` Finally, port-forward the `web-svc` service using `kubectl`: ```shell kubectl port-forward service/web-svc -n emojivoto 8080:80 ``` Open a web browser and point to [localhost:8080](http://localhost:8080/). You should see the Emojivoto application welcome page: ![Emojivoto Welcome Page](assets/images/emojivoto-welcome-page.png) ## Cleaning Up To clean up all Kubernetes resources created by the Emojivoto sample application, below command must be used: ```shell kubectl delete ns emojivoto ``` **Note:** Kubectl kustomize subcommand has a delete option that can be used - `kubectl delete -k emojivoto-example/kustomize`. But, it won't work well in this case because if the namespace is deleted first then the remaining operations will fail. ================================================ FILE: emojivoto-example/kustomize/kustomization.yaml ================================================ ## Emojivoto Sample Application Kustomization apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization # Making sure all resources used in this tutorial are created in a dedicated namespace # Also specific annotations are added for later identification namespace: emojivoto commonAnnotations: provider: kubernetes-sample-apps # Emojivoto resources (namespace, services, deployments, etc) resources: - github.com/BuoyantIO/emojivoto/kustomize/deployment patches: - path: patches/emoji-svc.yaml target: version: v1 kind: Service name: emoji-svc - path: patches/voting-svc.yaml target: version: v1 kind: Service name: voting-svc ================================================ FILE: emojivoto-example/kustomize/patches/emoji-svc.yaml ================================================ - op: add path: /metadata/labels value: app: emoji-svc ================================================ FILE: emojivoto-example/kustomize/patches/voting-svc.yaml ================================================ - op: add path: /metadata/labels value: app: voting-svc ================================================ FILE: game-2048-example/.dockerignore ================================================ **/.classpath **/.dockerignore **/.env **/.git **/.gitignore **/.project **/.settings **/.toolstarget **/.vs **/.vscode **/*.*proj.user **/*.dbmdl **/*.jfm **/charts **/docker-compose* **/compose* **/Dockerfile* **/node_modules **/npm-debug.log **/obj **/secrets.dev.yaml **/values.dev.yaml README.md ================================================ FILE: game-2048-example/.gitignore ================================================ **/node_modules **/dist ================================================ FILE: game-2048-example/Dockerfile ================================================ FROM node:16-slim AS builder WORKDIR /usr/src/app COPY . . RUN npm install --include=dev # # Build mode can be set via NODE_ENV environment variable (development or production) # See project package.json and webpack.config.js # ENV NODE_ENV=development RUN npm run build FROM node:16-slim RUN npm install http-server -g RUN mkdir /public WORKDIR /public COPY --from=builder /usr/src/app/dist/ ./ EXPOSE 8080 USER 1000 CMD ["http-server"] ================================================ FILE: game-2048-example/LICENSE ================================================ MIT License Copyright (c) 2019 DigitalOcean Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: game-2048-example/README.md ================================================ # Overview Sample javascript application implementing the classic [2048 game](https://en.wikipedia.org/wiki/2048_(video_game)). Main project is based on the [game-2048 library](https://www.npmjs.com/package/game-2048) and [Webpack](https://webpack.js.org). Main purpose is to serve as a demo for the [DOKS-CI-CD](https://github.com/digitalocean/container-blueprints/tree/main/DOKS-CI-CD) blueprint. ## Requirements To complete all steps and deploy the `2048-game` sample application, you will need: 1. A [DOKS](https://docs.digitalocean.com/products/kubernetes/quickstart) cluster configured and running. 2. Latest [Kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) version for Kubernetes interaction. 3. [Git](https://git-scm.com/downloads) client for interacting with the [kubernetes-sample-apps](https://github.com/digitalocean/kubernetes-sample-apps) repository. 4. [NodeJS](https://nodejs.org) and `npm` to build and test the 2048-game application code. 5. [Docker Desktop](https://www.docker.com/products/docker-desktop) to build and test the 2048-game application docker image locally. ## Building the 2048 Game Application Main project is `javascript` based, hence you can build the application via `npm`: ```shell npm install --include=dev npm run build ``` You can test the application locally, by running below command: ```shell npm start ``` Above command will start a web server in development mode, which you can access at [localhost:8080](http://localhost:8080). Please visit the main library [configuration](https://www.npmjs.com/package/game-2048#config) section from the public npm registry to see all available options. ## Building the Docker Image A sample [Dockerfile](./Dockerfile) is provided in this repository as well, to help you get started with dockerizing the 2048 game app. Depending on the `NODE_ENV` environment variable, you can create and publish a `development` or `production` ready Docker image. First, you need to clone this repository (if not already): ```shell git clone https://github.com/digitalocean/kubernetes-sample-apps.git ``` Then, change directory to your local copy: ```shell cd kubernetes-sample-apps ``` Next, issue below command to build the docker image for the 2048 game app, Below examples assume you already have a [DigitalOcean Docker Registry](https://docs.digitalocean.com/products/container-registry) set up (make sure to replace the `<>` placeholders accordingly): ```shell docker build -t registry.digitalocean.com//2048-game ./game-2048-example ``` **Note:** The sample [Dockerfile](./Dockerfile) provided in this repository is using the [multistage build](https://docs.docker.com/develop/develop-images/multistage-build) feature. It means, the final image contains only the application assets (build process artifacts are automatically discarded). Then, you can issue bellow command to launch the `2048-game` container (make sure to replace the `<>` placeholders accordingly): ```shell docker run --rm -it -p 8080:8080 registry.digitalocean.com//2048-game ``` Now, visit [localhost:8080](http://localhost:8080) to check the 2048 game app in your web browser. Finally, you can push the image to your DigitalOcean docker registry (make sure to replace the `<>` placeholders accordingly): ```shell docker push registry.digitalocean.com//2048-game ``` **Note:** Pushing images to your DigitalOcean docker registry is possible only after a successful authentication. Please read the official DigitalOcean [guide](https://docs.digitalocean.com/products/container-registry/how-to/use-registry-docker-kubernetes) and follow the steps. [Integrating with Kubernetes](https://docs.digitalocean.com/products/container-registry/how-to/use-registry-docker-kubernetes/#kubernetes-integration) step is important as well. ## Deploying to Kubernetes The [kustomization manifest](kustomize/kustomization.yaml) provided in this repository will get you started with deploying the `2048-game` Kubernetes resources. First, you need to clone this repository (if not already): ```shell git clone https://github.com/digitalocean/kubernetes-sample-apps.git ``` Then, change directory to your local copy: ```shell cd kubernetes-sample-apps ``` Next, edit the game-2048 [deployment manifest](kustomize/resources/deployment.yaml) using your favorite text editor (preferably with YAML lint support), and replace the `<>` placeholders. For example, you can use [VS Code](https://code.visualstudio.com/): ```shell code game-2048-example/kustomize/resources/deployment.yaml ``` Now, create 2048 game Kubernetes resources using the kubectl kustomize option (`-k` flag): ```shell kubectl apply -k game-2048-example/kustomize ``` The output looks similar to: ```text namespace/game-2048 created service/game-2048 created deployment.apps/game-2048 created ``` If everything went well, you should have a new Kubernetes namespace created named `game-2048`. Inside the new namespace, you can inspect all resources created by the kustomization manifest from the sample apps repository (all game-2048 application pods should be up and running): ```shell kubectl get all -n game-2048 ``` The output looks similar to: ```text NAME READY STATUS RESTARTS AGE pod/game-2048-f96755947-dgj7z 1/1 Running 0 5m19s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/game-2048 ClusterIP 10.245.120.202 8080/TCP 5m21s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/game-2048 1/1 1 1 5m22s NAME DESIRED CURRENT READY AGE replicaset.apps/game-2048-f96755947 1 1 1 5m22s ``` Finally, port-forward the `game-2048` service using `kubectl`: ```shell kubectl port-forward service/game-2048 -n game-2048 8080:8080 ``` Open a web browser and point to [localhost:8080](http://localhost:8080/). You should see the `game-2048` welcome page: ![2048 Game Welcome Page](assets/images/game-2048-welcome-page.png) ## Cleaning Up To clean up all Kubernetes resources created by the 2048 game application, below command must be used: ```shell kubectl delete ns game-2048 ``` **Note:** Kubectl kustomize subcommand has a delete option that can be used - `kubectl delete -k game-2048-example/kustomize`. But, it won't work well in this case because if the namespace is deleted first then the remaining operations will fail. ================================================ FILE: game-2048-example/Tiltfile ================================================ os.putenv('DOCKER_DEFAULT_PLATFORM', 'linux/amd64') k8s_yaml(kustomize('kustomize')) docker_build('game-2048', '.') k8s_resource('game-2048', port_forwards='8080') ================================================ FILE: game-2048-example/knative-service.yaml ================================================ apiVersion: serving.knative.dev/v1 kind: Service metadata: name: game-2048 spec: template: spec: containers: # Replace with your docker registry info - image: registry.digitalocean.com//2048-game:latest ports: - containerPort: 80 ================================================ FILE: game-2048-example/kustomize/kustomization.yaml ================================================ ## 2048 Game Sample Application Kustomization apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization # Making sure all resources used in this tutorial are created in a dedicated namespace # Also specific annotations are added for later identification namespace: game-2048 commonAnnotations: provider: kubernetes-sample-apps # 2048 game resources (namespace, services, deployments, etc) resources: - resources/namespace.yaml - resources/deployment.yaml - resources/service.yaml ================================================ FILE: game-2048-example/kustomize/resources/deployment.yaml ================================================ --- apiVersion: apps/v1 kind: Deployment metadata: name: game-2048 spec: replicas: 1 selector: matchLabels: app: game-2048 strategy: type: RollingUpdate template: metadata: labels: app: game-2048 spec: containers: - name: backend # Replace the `<>` placeholders with your docker registry info image: registry.digitalocean.com//2048-game:latest ports: - name: http containerPort: 8080 resources: requests: cpu: 200m memory: 100Mi limits: cpu: 300m memory: 200Mi # securityContext: # readOnlyRootFilesystem: true # runAsNonRoot: true # allowPrivilegeEscalation: false # capabilities: # drop: # - all ================================================ FILE: game-2048-example/kustomize/resources/namespace.yaml ================================================ apiVersion: v1 kind: Namespace metadata: name: game-2048 ================================================ FILE: game-2048-example/kustomize/resources/service.yaml ================================================ apiVersion: v1 kind: Service metadata: name: game-2048 spec: ports: - name: http port: 8080 targetPort: 8080 selector: app: game-2048 ================================================ FILE: game-2048-example/package.json ================================================ { "name": "knative-example", "version": "0.0.1", "private": true, "scripts": { "start": "webpack server --config webpack.config.js --mode development", "build": "webpack", "build-dev": "webpack --mode development", "build-prod": "webpack --mode production", "test": "echo '=== DUMMY TEST ==='" }, "dependencies": { "game-2048": "^0.0.7" }, "devDependencies": { "css-loader": "^6.7.1", "html-webpack-plugin": "^5.5.0", "style-loader": "^3.3.1", "webpack": "^5.72.1", "webpack-cli": "^4.9.2", "webpack-dev-server": "^4.9.0" }, "author": "", "license": "MIT", "description": "Sample 2048 Game App" } ================================================ FILE: game-2048-example/src/index.js ================================================ import 'game-2048/style/main.css'; import Game from 'game-2048'; var gameContainerDiv = document.createElement('div'); gameContainerDiv.setAttribute('id', 'game-container'); gameContainerDiv.className = 'container'; document.body.appendChild(gameContainerDiv); const game = new Game({ gameContainer: gameContainerDiv }); ================================================ FILE: game-2048-example/webpack.config.js ================================================ const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { mode: process.env.NODE_ENV || 'none', module: { rules: [ { test: /\.css$/i, use: ["style-loader", "css-loader"], }, ], }, entry: './src/index.js', output: { filename: 'lib/bundle.js', path: path.resolve(__dirname, 'dist'), clean: true, }, plugins: [ new HtmlWebpackPlugin({ title: '2048 Game', }) ], devServer: { static: { directory: path.join(__dirname, 'dist'), }, compress: true, port: 8080, }, }; ================================================ FILE: microservices-demo/.gitignore ================================================ # macOS .DS_Store # Tilt settings /tilt_config.json ================================================ FILE: microservices-demo/CODE_OF_CONDUCT.md ================================================ # Contributor Code of Conduct As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery * Personal attacks * Trolling or insulting/derogatory comments * Public or private harassment * Publishing other's private information, such as physical or electronic addresses, without explicit permission * Other unethical or unprofessional conduct. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) ================================================ FILE: microservices-demo/CONTRIBUTING.md ================================================ # How to Contribute We'd love to accept your patches and contributions to this project. There are just a few small guidelines you need to follow. ## Development Principles (for Googlers) There are a few principles for developing or refactoring the service implementations. Read the [Development Principles Guide](./docs/development-principles.md). ## Contributor License Agreement Contributions to this project must be accompanied by a Contributor License Agreement. You (or your employer) retain the copyright to your contribution; this simply gives us permission to use and redistribute your contributions as part of the project. Head over to to see your current agreements on file or to sign a new one. You generally only need to submit a CLA once, so if you've already submitted one (even if it was for a different project), you probably don't need to do it again. ## Code reviews All submissions, including submissions by project members, require review. We use GitHub pull requests for this purpose. Consult [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more information on using pull requests. ## Community Guidelines This project follows [Google's Open Source Community Guidelines](https://opensource.google.com/conduct/). ================================================ FILE: microservices-demo/LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: microservices-demo/README.md ================================================ # Overview **Note:** **This demo application serves as a companion for the [Kubernetes Adoption Journey](https://digitalocean.github.io/k8s-adoption-journey/) project. Please follow the Kubernetes adoption journey project for more information and comprehensive guidelines.** This application is a clone of this [GoogleCloudPlatform](https://github.com/GoogleCloudPlatform/microservices-demo) project. It will be used as a demo for the K8s adoption journey. This clone of the project has been stripped down to focus only on the major parts as required by the adoption journey. ## Prerequisites 1. [Tilt](https://tilt.dev/) installed on your local machine. 2. [Docker Desktop](https://www.docker.com/products/docker-desktop/) installed on your local machine, with built-in Kubernetes cluster enabled and running. ## Quick Start 1. Run the following command in the project root directory to deploy the **microservices-demo** app to your local Kubernetes cluster: ```shell cp tilt-resources/local/tilt_config.json . tilt up ``` 2. Open Tilt [web interface](http://localhost:10350/), and wait for all services to be ready. 3. Access the [web frontend](http://localhost:9090/) in a browser. ## Cleaning Up Run following command from this project root directory to clean up all resources: ```shell tilt down ``` ================================================ FILE: microservices-demo/Tiltfile ================================================ ######################################################################### # # Tiltfile logic # ######################################################################### # Import required functions from Tilt extensions load( "ext://namespace", "namespace_create", "namespace_inject" ) # Import settings from tilt_config.json if not os.path.exists("./tilt_config.json"): fail( """ # ================================================ # # Tilt config file not found in current directory! # # Please copy a template from tilt-resources dir. # # # # E.g.: # # cp tilt-resources/local/tilt_config.json . # # ================================================ # """ ) config.define_string_list("allowed_contexts") config.define_string("default_registry") config.define_string("environment") config.define_string_list("microservices") config.define_string("namespace") config.define_string_list("port_forwards") cfg = config.parse() # Compatibilty setting for ARM arch os.putenv("DOCKER_DEFAULT_PLATFORM", "linux/amd64") # Allow default K8S context as stated in the tilt_config.json file allow_k8s_contexts(cfg.get("allowed_contexts")) # Set default registry as stated in the tilt_config.json file if cfg.get("default_registry") != "": default_registry(cfg.get("default_registry")) # Build each microservice image as stated in the tilt_config.json file for microservice in cfg.get("microservices"): if "redis" in microservice: continue docker_build( microservice, # cartservice is an exception regarding source folder path "src/{}/src".format(microservice) if "cartservice" in microservice else "src/{}".format(microservice) ) # Create namespace as stated in the tilt_config.json file namespace_create(cfg.get("namespace")) # Deploy each microservice as stated in the tilt_config.json file for microservice in cfg.get("microservices"): k8s_yaml( namespace_inject( read_file("kustomize/base/{}.yaml".format(microservice)), cfg.get("namespace") ) ) # Port forwards as stated in the tilt_config.json file for port_forward in cfg.get("port_forwards"): mapping = port_forward.split(":") if (len(mapping) != 2): fail( """ # =================================================== # # Invalid port forward specified in tilt_config.json! # # Should be :. # # # # E.g.: frontend:9090 # # =================================================== # """ ) service = mapping[0] port = mapping[1] k8s_resource(service, port_forwards=port) ================================================ FILE: microservices-demo/kustomize/base/cartservice.yaml ================================================ # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: apps/v1 kind: Deployment metadata: name: cartservice spec: replicas: 1 selector: matchLabels: app: cartservice template: metadata: labels: app: cartservice spec: serviceAccountName: default terminationGracePeriodSeconds: 5 securityContext: fsGroup: 1000 runAsGroup: 1000 runAsNonRoot: true runAsUser: 1000 containers: - name: server securityContext: allowPrivilegeEscalation: false capabilities: drop: - all privileged: false readOnlyRootFilesystem: true imagePullPolicy: Always image: cartservice:latest ports: - containerPort: 7070 env: - name: REDIS_ADDR value: "redis-cart:6379" resources: requests: cpu: 200m memory: 128Mi limits: cpu: 300m memory: 256Mi readinessProbe: timeoutSeconds: 15 initialDelaySeconds: 20 exec: command: [ "/bin/grpc_health_probe", "-addr=:7070", "-rpc-timeout=10s", "-connect-timeout=10s", ] livenessProbe: timeoutSeconds: 15 initialDelaySeconds: 20 periodSeconds: 15 exec: command: [ "/bin/grpc_health_probe", "-addr=:7070", "-rpc-timeout=10s", "-connect-timeout=10s", ] --- apiVersion: v1 kind: Service metadata: name: cartservice spec: type: ClusterIP selector: app: cartservice ports: - name: grpc port: 7070 targetPort: 7070 ================================================ FILE: microservices-demo/kustomize/base/checkoutservice.yaml ================================================ # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: apps/v1 kind: Deployment metadata: name: checkoutservice spec: replicas: 1 selector: matchLabels: app: checkoutservice template: metadata: labels: app: checkoutservice spec: serviceAccountName: default securityContext: fsGroup: 1000 runAsGroup: 1000 runAsNonRoot: true runAsUser: 1000 containers: - name: server securityContext: allowPrivilegeEscalation: false capabilities: drop: - all privileged: false readOnlyRootFilesystem: true imagePullPolicy: Always image: checkoutservice:latest ports: - containerPort: 5050 readinessProbe: timeoutSeconds: 15 initialDelaySeconds: 15 exec: command: ["/bin/grpc_health_probe", "-addr=:5050"] livenessProbe: timeoutSeconds: 15 initialDelaySeconds: 15 exec: command: ["/bin/grpc_health_probe", "-addr=:5050"] env: - name: PORT value: "5050" - name: PRODUCT_CATALOG_SERVICE_ADDR value: "productcatalogservice:3550" - name: SHIPPING_SERVICE_ADDR value: "shippingservice:50051" - name: PAYMENT_SERVICE_ADDR value: "paymentservice:50051" - name: EMAIL_SERVICE_ADDR value: "emailservice:5000" - name: CURRENCY_SERVICE_ADDR value: "currencyservice:7000" - name: CART_SERVICE_ADDR value: "cartservice:7070" - name: DISABLE_STATS value: "1" - name: DISABLE_TRACING value: "1" - name: DISABLE_PROFILER value: "1" # - name: JAEGER_SERVICE_ADDR # value: "jaeger-collector:14268" resources: requests: cpu: 100m memory: 64Mi limits: cpu: 200m memory: 128Mi --- apiVersion: v1 kind: Service metadata: name: checkoutservice spec: type: ClusterIP selector: app: checkoutservice ports: - name: grpc port: 5050 targetPort: 5050 ================================================ FILE: microservices-demo/kustomize/base/currencyservice.yaml ================================================ # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: apps/v1 kind: Deployment metadata: name: currencyservice spec: replicas: 1 selector: matchLabels: app: currencyservice template: metadata: labels: app: currencyservice spec: serviceAccountName: default terminationGracePeriodSeconds: 5 securityContext: fsGroup: 1000 runAsGroup: 1000 runAsNonRoot: true runAsUser: 1000 containers: - name: server securityContext: allowPrivilegeEscalation: false capabilities: drop: - all privileged: false readOnlyRootFilesystem: true imagePullPolicy: Always image: currencyservice:latest ports: - name: grpc containerPort: 7000 env: - name: PORT value: "7000" - name: DISABLE_TRACING value: "1" - name: DISABLE_PROFILER value: "1" - name: DISABLE_DEBUGGER value: "1" readinessProbe: timeoutSeconds: 15 initialDelaySeconds: 15 exec: command: ["/bin/grpc_health_probe", "-rpc-timeout=5s", "-addr=:7000"] livenessProbe: timeoutSeconds: 15 initialDelaySeconds: 15 exec: command: ["/bin/grpc_health_probe", "-rpc-timeout=5s", "-addr=:7000"] resources: requests: cpu: 100m memory: 128Mi limits: cpu: 200m memory: 256Mi --- apiVersion: v1 kind: Service metadata: name: currencyservice spec: type: ClusterIP selector: app: currencyservice ports: - name: grpc port: 7000 targetPort: 7000 ================================================ FILE: microservices-demo/kustomize/base/emailservice.yaml ================================================ # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: apps/v1 kind: Deployment metadata: name: emailservice spec: replicas: 1 selector: matchLabels: app: emailservice template: metadata: labels: app: emailservice spec: serviceAccountName: default terminationGracePeriodSeconds: 5 securityContext: fsGroup: 1000 runAsGroup: 1000 runAsNonRoot: true runAsUser: 1000 containers: - name: server securityContext: allowPrivilegeEscalation: false capabilities: drop: - all privileged: false readOnlyRootFilesystem: true imagePullPolicy: Always image: emailservice:latest ports: - containerPort: 8080 env: - name: PORT value: "8080" - name: DISABLE_TRACING value: "1" - name: DISABLE_PROFILER value: "1" readinessProbe: timeoutSeconds: 15 periodSeconds: 15 initialDelaySeconds: 15 exec: command: ["/bin/grpc_health_probe", "-rpc-timeout=5s", "-addr=:8080"] livenessProbe: timeoutSeconds: 15 periodSeconds: 15 initialDelaySeconds: 15 exec: command: ["/bin/grpc_health_probe", "-rpc-timeout=5s", "-addr=:8080"] resources: requests: cpu: 100m memory: 128Mi limits: cpu: 200m memory: 256Mi --- apiVersion: v1 kind: Service metadata: name: emailservice spec: type: ClusterIP selector: app: emailservice ports: - name: grpc port: 5000 targetPort: 8080 ================================================ FILE: microservices-demo/kustomize/base/frontend.yaml ================================================ # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: apps/v1 kind: Deployment metadata: name: frontend spec: replicas: 1 selector: matchLabels: app: frontend template: metadata: labels: app: frontend spec: serviceAccountName: default securityContext: fsGroup: 1000 runAsGroup: 1000 runAsNonRoot: true runAsUser: 1000 containers: - name: server securityContext: allowPrivilegeEscalation: false capabilities: drop: - all privileged: false readOnlyRootFilesystem: true imagePullPolicy: Always image: frontend:latest ports: - containerPort: 8080 readinessProbe: initialDelaySeconds: 10 httpGet: path: "/_healthz" port: 8080 httpHeaders: - name: "Cookie" value: "shop_session-id=x-readiness-probe" livenessProbe: initialDelaySeconds: 10 httpGet: path: "/_healthz" port: 8080 httpHeaders: - name: "Cookie" value: "shop_session-id=x-liveness-probe" env: - name: PORT value: "8080" - name: PRODUCT_CATALOG_SERVICE_ADDR value: "productcatalogservice:3550" - name: CURRENCY_SERVICE_ADDR value: "currencyservice:7000" - name: CART_SERVICE_ADDR value: "cartservice:7070" - name: RECOMMENDATION_SERVICE_ADDR value: "recommendationservice:8080" - name: SHIPPING_SERVICE_ADDR value: "shippingservice:50051" - name: CHECKOUT_SERVICE_ADDR value: "checkoutservice:5050" - name: AD_SERVICE_ADDR value: "adservice:9555" # # ENV_PLATFORM: One of: local, gcp, aws, azure, onprem, alibaba # # When not set, defaults to "local" unless running in GKE, otherwies auto-sets to gcp # - name: ENV_PLATFORM # value: "local" - name: DISABLE_TRACING value: "1" - name: DISABLE_PROFILER value: "1" resources: requests: cpu: 100m memory: 64Mi limits: cpu: 200m memory: 128Mi --- apiVersion: v1 kind: Service metadata: name: frontend spec: type: ClusterIP selector: app: frontend ports: - name: http port: 80 targetPort: 8080 ================================================ FILE: microservices-demo/kustomize/base/kustomization.yaml ================================================ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - namespace.yaml - cartservice.yaml - checkoutservice.yaml - currencyservice.yaml - emailservice.yaml - frontend.yaml - paymentservice.yaml - productcatalogservice.yaml - recommendationservice.yaml - redis.yaml - shippingservice.yaml ================================================ FILE: microservices-demo/kustomize/base/namespace.yaml ================================================ apiVersion: v1 kind: Namespace metadata: name: microservices-demo ================================================ FILE: microservices-demo/kustomize/base/paymentservice.yaml ================================================ # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: apps/v1 kind: Deployment metadata: name: paymentservice spec: replicas: 1 selector: matchLabels: app: paymentservice template: metadata: labels: app: paymentservice spec: serviceAccountName: default terminationGracePeriodSeconds: 5 securityContext: fsGroup: 1000 runAsGroup: 1000 runAsNonRoot: true runAsUser: 1000 containers: - name: server securityContext: allowPrivilegeEscalation: false capabilities: drop: - all privileged: false readOnlyRootFilesystem: true imagePullPolicy: Always image: paymentservice:latest ports: - containerPort: 50051 env: - name: PORT value: "50051" - name: DISABLE_TRACING value: "1" - name: DISABLE_PROFILER value: "1" - name: DISABLE_DEBUGGER value: "1" readinessProbe: timeoutSeconds: 15 initialDelaySeconds: 15 exec: command: ["/bin/grpc_health_probe", "-rpc-timeout=5s", "-addr=:50051"] livenessProbe: timeoutSeconds: 15 initialDelaySeconds: 15 exec: command: ["/bin/grpc_health_probe", "-rpc-timeout=5s", "-addr=:50051"] resources: requests: cpu: 100m memory: 128Mi limits: cpu: 200m memory: 256Mi --- apiVersion: v1 kind: Service metadata: name: paymentservice spec: type: ClusterIP selector: app: paymentservice ports: - name: grpc port: 50051 targetPort: 50051 ================================================ FILE: microservices-demo/kustomize/base/productcatalogservice.yaml ================================================ # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: apps/v1 kind: Deployment metadata: name: productcatalogservice spec: replicas: 1 selector: matchLabels: app: productcatalogservice template: metadata: labels: app: productcatalogservice spec: serviceAccountName: default terminationGracePeriodSeconds: 5 securityContext: fsGroup: 1000 runAsGroup: 1000 runAsNonRoot: true runAsUser: 1000 containers: - name: server securityContext: allowPrivilegeEscalation: false capabilities: drop: - all privileged: false readOnlyRootFilesystem: true imagePullPolicy: Always image: productcatalogservice:latest ports: - containerPort: 3550 env: - name: PORT value: "3550" - name: DISABLE_STATS value: "1" - name: DISABLE_TRACING value: "1" - name: DISABLE_PROFILER value: "1" # - name: JAEGER_SERVICE_ADDR # value: "jaeger-collector:14268" readinessProbe: timeoutSeconds: 15 initialDelaySeconds: 15 exec: command: ["/bin/grpc_health_probe", "-addr=:3550"] livenessProbe: timeoutSeconds: 15 initialDelaySeconds: 15 exec: command: ["/bin/grpc_health_probe", "-addr=:3550"] resources: requests: cpu: 100m memory: 64Mi limits: cpu: 200m memory: 128Mi --- apiVersion: v1 kind: Service metadata: name: productcatalogservice spec: type: ClusterIP selector: app: productcatalogservice ports: - name: grpc port: 3550 targetPort: 3550 ================================================ FILE: microservices-demo/kustomize/base/recommendationservice.yaml ================================================ # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: apps/v1 kind: Deployment metadata: name: recommendationservice spec: replicas: 1 selector: matchLabels: app: recommendationservice template: metadata: labels: app: recommendationservice spec: serviceAccountName: default terminationGracePeriodSeconds: 5 securityContext: fsGroup: 1000 runAsGroup: 1000 runAsNonRoot: true runAsUser: 1000 containers: - name: server securityContext: allowPrivilegeEscalation: false capabilities: drop: - all privileged: false readOnlyRootFilesystem: true imagePullPolicy: Always image: recommendationservice:latest ports: - containerPort: 8080 readinessProbe: timeoutSeconds: 15 initialDelaySeconds: 15 periodSeconds: 15 exec: command: ["/bin/grpc_health_probe", "-addr=:8080"] livenessProbe: timeoutSeconds: 15 initialDelaySeconds: 15 periodSeconds: 15 exec: command: ["/bin/grpc_health_probe", "-addr=:8080"] env: - name: PORT value: "8080" - name: PRODUCT_CATALOG_SERVICE_ADDR value: "productcatalogservice:3550" - name: DISABLE_TRACING value: "1" - name: DISABLE_PROFILER value: "1" - name: DISABLE_DEBUGGER value: "1" resources: requests: cpu: 100m memory: 220Mi limits: cpu: 200m memory: 450Mi --- apiVersion: v1 kind: Service metadata: name: recommendationservice spec: type: ClusterIP selector: app: recommendationservice ports: - name: grpc port: 8080 targetPort: 8080 ================================================ FILE: microservices-demo/kustomize/base/redis.yaml ================================================ # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: apps/v1 kind: Deployment metadata: name: redis-cart spec: replicas: 1 selector: matchLabels: app: redis-cart template: metadata: labels: app: redis-cart spec: securityContext: fsGroup: 1000 runAsGroup: 1000 runAsNonRoot: true runAsUser: 1000 containers: - name: redis securityContext: allowPrivilegeEscalation: false capabilities: drop: - all privileged: false readOnlyRootFilesystem: true image: redis:alpine ports: - containerPort: 6379 readinessProbe: periodSeconds: 5 tcpSocket: port: 6379 livenessProbe: periodSeconds: 5 tcpSocket: port: 6379 volumeMounts: - mountPath: /data name: redis-data resources: limits: memory: 256Mi cpu: 125m requests: cpu: 70m memory: 200Mi volumes: - name: redis-data emptyDir: {} --- apiVersion: v1 kind: Service metadata: name: redis-cart spec: type: ClusterIP selector: app: redis-cart ports: - name: tls-redis port: 6379 targetPort: 6379 ================================================ FILE: microservices-demo/kustomize/base/shippingservice.yaml ================================================ # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: apps/v1 kind: Deployment metadata: name: shippingservice spec: replicas: 1 selector: matchLabels: app: shippingservice template: metadata: labels: app: shippingservice spec: serviceAccountName: default securityContext: fsGroup: 1000 runAsGroup: 1000 runAsNonRoot: true runAsUser: 1000 containers: - name: server securityContext: allowPrivilegeEscalation: false capabilities: drop: - all privileged: false readOnlyRootFilesystem: true imagePullPolicy: Always image: shippingservice:latest ports: - containerPort: 50051 env: - name: PORT value: "50051" - name: DISABLE_STATS value: "1" - name: DISABLE_TRACING value: "1" - name: DISABLE_PROFILER value: "1" # - name: JAEGER_SERVICE_ADDR # value: "jaeger-collector:14268" readinessProbe: timeoutSeconds: 15 periodSeconds: 15 initialDelaySeconds: 15 exec: command: ["/bin/grpc_health_probe", "-addr=:50051"] livenessProbe: timeoutSeconds: 15 initialDelaySeconds: 15 exec: command: ["/bin/grpc_health_probe", "-addr=:50051"] resources: requests: cpu: 100m memory: 64Mi limits: cpu: 200m memory: 128Mi --- apiVersion: v1 kind: Service metadata: name: shippingservice spec: type: ClusterIP selector: app: shippingservice ports: - name: grpc port: 50051 targetPort: 50051 ================================================ FILE: microservices-demo/kustomize/dev/kustomization.yaml ================================================ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: microservices-demo-dev commonLabels: variant: dev resources: - ../base images: - name: cartservice newName: registry.digitalocean.com/microservices-demo/cartservice newTag: v1.0.0 - name: checkoutservice newName: registry.digitalocean.com/microservices-demo/checkoutservice newTag: v1.0.0 - name: currencyservice newName: registry.digitalocean.com/microservices-demo/currencyservice newTag: v1.0.0 - name: emailservice newName: registry.digitalocean.com/microservices-demo/emailservice newTag: v1.0.0 - name: frontend newName: registry.digitalocean.com/microservices-demo/frontend newTag: v1.0.0 - name: paymentservice newName: registry.digitalocean.com/microservices-demo/paymentservice newTag: v1.0.0 - name: productcatalogservice newName: registry.digitalocean.com/microservices-demo/productcatalogservice newTag: v1.0.0 - name: recommendationservice newName: registry.digitalocean.com/microservices-demo/recommendationservice newTag: v1.0.0 - name: shippingservice newName: registry.digitalocean.com/microservices-demo/shippingservice newTag: v1.0.0 ================================================ FILE: microservices-demo/kustomize/kustomization.yaml ================================================ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - dev - staging - prod ================================================ FILE: microservices-demo/kustomize/prod/kustomization.yaml ================================================ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: microservices-demo-prod commonLabels: variant: prod resources: - ../base images: - name: cartservice newName: registry.digitalocean.com/microservices-demo/cartservice newTag: v1.0.0 - name: checkoutservice newName: registry.digitalocean.com/microservices-demo/checkoutservice newTag: v1.0.0 - name: currencyservice newName: registry.digitalocean.com/microservices-demo/currencyservice newTag: v1.0.0 - name: emailservice newName: registry.digitalocean.com/microservices-demo/emailservice newTag: v1.0.0 - name: frontend newName: registry.digitalocean.com/microservices-demo/frontend newTag: v1.0.0 - name: paymentservice newName: registry.digitalocean.com/microservices-demo/paymentservice newTag: v1.0.0 - name: productcatalogservice newName: registry.digitalocean.com/microservices-demo/productcatalogservice newTag: v1.0.0 - name: recommendationservice newName: registry.digitalocean.com/microservices-demo/recommendationservice newTag: v1.0.0 - name: shippingservice newName: registry.digitalocean.com/microservices-demo/shippingservice newTag: v1.0.0 replicas: - name: cartservice count: 2 - name: checkoutservice count: 2 - name: currencyservice count: 2 - name: emailservice count: 2 - name: frontend count: 2 - name: paymentservice count: 2 - name: productcatalogservice count: 2 - name: recommendationservice count: 2 - name: shippingservice count: 2 ================================================ FILE: microservices-demo/kustomize/staging/kustomization.yaml ================================================ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: microservices-demo-staging commonLabels: variant: staging resources: - ../base images: - name: cartservice newName: registry.digitalocean.com/microservices-demo/cartservice newTag: v1.0.0 - name: checkoutservice newName: registry.digitalocean.com/microservices-demo/checkoutservice newTag: v1.0.0 - name: currencyservice newName: registry.digitalocean.com/microservices-demo/currencyservice newTag: v1.0.0 - name: emailservice newName: registry.digitalocean.com/microservices-demo/emailservice newTag: v1.0.0 - name: frontend newName: registry.digitalocean.com/microservices-demo/frontend newTag: v1.0.0 - name: paymentservice newName: registry.digitalocean.com/microservices-demo/paymentservice newTag: v1.0.0 - name: productcatalogservice newName: registry.digitalocean.com/microservices-demo/productcatalogservice newTag: v1.0.0 - name: recommendationservice newName: registry.digitalocean.com/microservices-demo/recommendationservice newTag: v1.0.0 - name: shippingservice newName: registry.digitalocean.com/microservices-demo/shippingservice newTag: v1.0.0 replicas: - name: cartservice count: 2 - name: checkoutservice count: 2 - name: currencyservice count: 2 - name: emailservice count: 2 - name: frontend count: 2 - name: paymentservice count: 2 - name: productcatalogservice count: 2 - name: recommendationservice count: 2 - name: shippingservice count: 2 ================================================ FILE: microservices-demo/release-scripts/README.md ================================================ # Overview of the Release Scripts This directory contains the scripts for creating a new `microservices-demo` release. ## Create a New Release ### 1. Decide on the next release version number using [semantic versioning](https://semver.org/). - Look at the [commits since the previous release](https://github.com/GoogleCloudPlatform/microservices-demo/commits/main). #### 2. Open a new terminal #### 3. Make sure you have `gsed` installed. If not, `brew install gnu-sed`. #### 4. Set the following environment variables - `TAG` - This is the new version (e.g., `v0.3.5`). - `REPO_PREFIX` - This is the Docker repository. ##### Example ```shell export TAG=v0.3.5 export REPO_PREFIX=gcr.io/google-samples/microservices-demo ``` #### 5. Run `./release-scripts/make-release.sh` - Make sure you run `./hack/make-release.sh` from this project's root folder — **not** from inside the `release-scripts/` folder. - This script: 1. uses `make-docker-images.sh` to build and push a Docker image for each microservice to the previously specified repository. 1. uses `make-release-artifacts.sh` to regenerates (and update the image $TAGS) YAML file at `./release/kubernetes-manifests.yaml`. 1. runs `git tag` and pushes a new branch (e.g., `release/v0.3.5`) with the changes to `release/kubernetes-manifests.yaml`. #### 6. [Draft a new release on GitHub](https://github.com/GoogleCloudPlatform/microservices-demo/releases). - Summarize the [commits since the previous release](https://github.com/GoogleCloudPlatform/microservices-demo/commits/main). - See previous releases for inspiration on release notes. #### 7. Create a new pull-request - When you ran `make-release.sh`, it created a new branch (e.g., `release/v0.3.5`). - Include the new release draft in the pull-request description for reviewers to see. #### 8. Once your pull-request is approved, merge it #### 9. Deploy `release/kubernetes-manifests.yaml` ```shell kubectl apply -f ./release/kubernetes-manifests.yaml ``` ================================================ FILE: microservices-demo/release-scripts/license_header.txt ================================================ # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ================================================ FILE: microservices-demo/release-scripts/make-cnb-docker-images.sh ================================================ #!/usr/bin/env bash set -euo pipefail SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" log() { echo "$1" >&2; } TAG="${TAG:?TAG env variable must be specified}" REPO_PREFIX="${REPO_PREFIX:?REPO_PREFIX env variable must be specified}" while IFS= read -d $'\0' -r dir; do # build image svcname="$(basename "${dir}")" builddir="${dir}" #PR 516 moved cartservice build artifacts one level down to src if [ $svcname == "cartservice" ] then builddir="${dir}/src" fi ## skipping loadgenerator service building as it's used only in CI for tests if [ $svcname == "loadgenerator" ] then continue fi image="${REPO_PREFIX}/$svcname:$TAG" ( cd "${builddir}" log "Building and pushing: ${image}" ## we are not using the --publish pack flag due to an issue preventing the pack CLI from pushing to DOCR pack build ${image} --builder gcr.io/buildpacks/builder:v1 docker push ${image} ) done < <(find "${SCRIPTDIR}/../src" -mindepth 1 -maxdepth 1 -type d -print0) log "Successfully built and pushed all images." ================================================ FILE: microservices-demo/release-scripts/make-docker-images.sh ================================================ #!/usr/bin/env bash # Copyright 2019 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Builds and pushes docker image for each demo microservice. set -euo pipefail SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" log() { echo "$1" >&2; } TAG="${TAG:?TAG env variable must be specified}" REPO_PREFIX="${REPO_PREFIX:?REPO_PREFIX env variable must be specified}" while IFS= read -d $'\0' -r dir; do # build image svcname="$(basename "${dir}")" builddir="${dir}" #PR 516 moved cartservice build artifacts one level down to src if [ $svcname == "cartservice" ] then builddir="${dir}/src" fi image="${REPO_PREFIX}/$svcname:$TAG" ( cd "${builddir}" log "Building and pushing: ${image}" docker buildx build --platform linux/amd64 -t "${image}" --push . ) done < <(find "${SCRIPTDIR}/../src" -mindepth 1 -maxdepth 1 -type d -print0) log "Successfully built and pushed all images." ================================================ FILE: microservices-demo/release-scripts/make-release-artifacts.sh ================================================ #!/usr/bin/env bash # Copyright 2019 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # This script compiles manifest files with the image tags and places them in # /release/... set -euo pipefail SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" [[ -n "${DEBUG:-}" ]] && set -x log() { echo "$1" >&2; } TAG="${TAG:?TAG env variable must be specified}" REPO_PREFIX="${REPO_PREFIX:?REPO_PREFIX env variable must be specified}" OUT_DIR="${OUT_DIR:-${SCRIPTDIR}/../release}" print_license_header() { cat "${SCRIPTDIR}/license_header.txt" echo } print_autogenerated_warning() { cat< "${k8s_manifests_file}" log "Written ${k8s_manifests_file}" istio_manifests_file="${OUT_DIR}/istio-manifests.yaml" mk_istio_manifests > "${istio_manifests_file}" log "Written ${istio_manifests_file}" } main ================================================ FILE: microservices-demo/release-scripts/make-release.sh ================================================ #!/usr/bin/env bash # Copyright 2019 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # This script creates a new release by: # - 1. building/pushing images # - 2. injecting tags into YAML manifests # - 3. creating a new git tag # - 4. pushing the tag/commit to main. set -euo pipefail SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" [[ -n "${DEBUG:-}" ]] && set -x log() { echo "$1" >&2; } fail() { log "$1"; exit 1; } TAG="${TAG:?TAG env variable must be specified}" REPO_PREFIX="${REPO_PREFIX:?REPO_PREFIX env variable must be specified e.g. gcr.io\/google-samples\/microservices-demo}" if [[ "$TAG" != v* ]]; then fail "\$TAG must start with 'v', e.g. v0.1.0 (got: $TAG)" fi # build and push images "${SCRIPTDIR}"/make-docker-images.sh # update yaml "${SCRIPTDIR}"/make-release-artifacts.sh # create git release / push to new branch git checkout -b "release/${TAG}" git add "${SCRIPTDIR}/../release/" git commit --allow-empty -m "Release $TAG" log "Pushing k8s manifests to release/${TAG}..." git tag "$TAG" git push --set-upstream origin "release/${TAG}" git push --tags log "Successfully tagged release $TAG." ================================================ FILE: microservices-demo/src/.gitignore ================================================ # Go: for the time being we are not checking in the vendor/ directories to git # to prevent the repo from getting larger forever. In each Go service, you can # run "dep ensure --vendor-only" to download the dependencies to vendor/ based # on the Gopkg.{toml,lock} files in that directory. vendor/ ================================================ FILE: microservices-demo/src/cartservice/.gitignore ================================================ **/bin/ **/obj/ .vs/*.* ================================================ FILE: microservices-demo/src/cartservice/cartservice.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26124.0 MinimumVisualStudioVersion = 15.0.26124.0 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cartservice", "src\cartservice.csproj", "{2348C29F-E8D3-4955-916D-D609CBC97FCB}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cartservice.tests", "tests\cartservice.tests.csproj", "{59825342-CE64-4AFA-8744-781692C0811B}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {2348C29F-E8D3-4955-916D-D609CBC97FCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2348C29F-E8D3-4955-916D-D609CBC97FCB}.Debug|Any CPU.Build.0 = Debug|Any CPU {2348C29F-E8D3-4955-916D-D609CBC97FCB}.Debug|x64.ActiveCfg = Debug|Any CPU {2348C29F-E8D3-4955-916D-D609CBC97FCB}.Debug|x64.Build.0 = Debug|Any CPU {2348C29F-E8D3-4955-916D-D609CBC97FCB}.Debug|x86.ActiveCfg = Debug|Any CPU {2348C29F-E8D3-4955-916D-D609CBC97FCB}.Debug|x86.Build.0 = Debug|Any CPU {2348C29F-E8D3-4955-916D-D609CBC97FCB}.Release|Any CPU.ActiveCfg = Release|Any CPU {2348C29F-E8D3-4955-916D-D609CBC97FCB}.Release|Any CPU.Build.0 = Release|Any CPU {2348C29F-E8D3-4955-916D-D609CBC97FCB}.Release|x64.ActiveCfg = Release|Any CPU {2348C29F-E8D3-4955-916D-D609CBC97FCB}.Release|x64.Build.0 = Release|Any CPU {2348C29F-E8D3-4955-916D-D609CBC97FCB}.Release|x86.ActiveCfg = Release|Any CPU {2348C29F-E8D3-4955-916D-D609CBC97FCB}.Release|x86.Build.0 = Release|Any CPU {59825342-CE64-4AFA-8744-781692C0811B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {59825342-CE64-4AFA-8744-781692C0811B}.Debug|Any CPU.Build.0 = Debug|Any CPU {59825342-CE64-4AFA-8744-781692C0811B}.Debug|x64.ActiveCfg = Debug|Any CPU {59825342-CE64-4AFA-8744-781692C0811B}.Debug|x64.Build.0 = Debug|Any CPU {59825342-CE64-4AFA-8744-781692C0811B}.Debug|x86.ActiveCfg = Debug|Any CPU {59825342-CE64-4AFA-8744-781692C0811B}.Debug|x86.Build.0 = Debug|Any CPU {59825342-CE64-4AFA-8744-781692C0811B}.Release|Any CPU.ActiveCfg = Release|Any CPU {59825342-CE64-4AFA-8744-781692C0811B}.Release|Any CPU.Build.0 = Release|Any CPU {59825342-CE64-4AFA-8744-781692C0811B}.Release|x64.ActiveCfg = Release|Any CPU {59825342-CE64-4AFA-8744-781692C0811B}.Release|x64.Build.0 = Release|Any CPU {59825342-CE64-4AFA-8744-781692C0811B}.Release|x86.ActiveCfg = Release|Any CPU {59825342-CE64-4AFA-8744-781692C0811B}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection EndGlobal ================================================ FILE: microservices-demo/src/cartservice/src/.dockerignore ================================================ **/*.sh **/*.bat **/bin/ **/obj/ **/out/ Dockerfile* ================================================ FILE: microservices-demo/src/cartservice/src/Dockerfile ================================================ # Copyright 2021 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # https://mcr.microsoft.com/v2/dotnet/sdk/tags/list FROM mcr.microsoft.com/dotnet/sdk:6.0.400 as builder WORKDIR /app COPY cartservice.csproj . RUN dotnet restore cartservice.csproj -r linux-musl-x64 COPY . . RUN dotnet publish cartservice.csproj -p:PublishSingleFile=true -r linux-musl-x64 --self-contained true -p:PublishTrimmed=True -p:TrimMode=Link -c release -o /cartservice --no-restore # https://mcr.microsoft.com/v2/dotnet/runtime-deps/tags/list FROM mcr.microsoft.com/dotnet/runtime-deps:6.0.8-alpine3.16-amd64 RUN GRPC_HEALTH_PROBE_VERSION=v0.4.11 && \ wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \ chmod +x /bin/grpc_health_probe WORKDIR /app COPY --from=builder /cartservice . ENV ASPNETCORE_URLS http://*:7070 ENV DOTNET_EnableDiagnostics=0 ENTRYPOINT ["/app/cartservice"] ================================================ FILE: microservices-demo/src/cartservice/src/Dockerfile.debug ================================================ # Copyright 2021 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build WORKDIR /app COPY . . RUN dotnet restore cartservice.csproj RUN dotnet build "./cartservice.csproj" -c Debug -o /out FROM build AS publish RUN dotnet publish cartservice.csproj -c Debug -o /out # Building final image used in running container FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS final # Installing procps on the container to enable debugging of .NET Core RUN apt-get update \ && apt-get install -y unzip procps wget RUN GRPC_HEALTH_PROBE_VERSION=v0.4.11 && \ wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \ chmod +x /bin/grpc_health_probe WORKDIR /app COPY --from=publish /out . ENV ASPNETCORE_URLS=http://*:7070 ENTRYPOINT ["dotnet", "cartservice.dll"] ================================================ FILE: microservices-demo/src/cartservice/src/Program.cs ================================================ // Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; using cartservice; CreateHostBuilder(args).Build().Run(); static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); }); ================================================ FILE: microservices-demo/src/cartservice/src/Startup.cs ================================================ using System; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Diagnostics.HealthChecks; using Microsoft.Extensions.Hosting; using cartservice.cartstore; using cartservice.services; using Microsoft.Extensions.Caching.StackExchangeRedis; namespace cartservice { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { string redisAddress = Configuration["REDIS_ADDR"]; if (!string.IsNullOrEmpty(redisAddress)) { services.AddStackExchangeRedisCache(options => { options.Configuration = redisAddress; }); } else { Console.WriteLine("Redis cache host(hostname+port) was not specified. Starting a cart service using in memory store"); services.AddDistributedMemoryCache(); } services.AddSingleton(); services.AddGrpc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapGrpcService(); endpoints.MapGrpcService(); endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909"); }); }); } } } ================================================ FILE: microservices-demo/src/cartservice/src/appsettings.json ================================================ { "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*", "Kestrel": { "EndpointDefaults": { "Protocols": "Http2" } } } ================================================ FILE: microservices-demo/src/cartservice/src/cartservice.csproj ================================================ net6.0 ================================================ FILE: microservices-demo/src/cartservice/src/cartstore/ICartStore.cs ================================================ // Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using System.Threading.Tasks; namespace cartservice.cartstore { public interface ICartStore { Task AddItemAsync(string userId, string productId, int quantity); Task EmptyCartAsync(string userId); Task GetCartAsync(string userId); bool Ping(); } } ================================================ FILE: microservices-demo/src/cartservice/src/cartstore/RedisCartStore.cs ================================================ // Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using System; using System.Linq; using System.Threading.Tasks; using Grpc.Core; using Microsoft.Extensions.Caching.Distributed; using Google.Protobuf; namespace cartservice.cartstore { public class RedisCartStore : ICartStore { private readonly IDistributedCache _cache; public RedisCartStore(IDistributedCache cache) { _cache = cache; } public async Task AddItemAsync(string userId, string productId, int quantity) { Console.WriteLine($"AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity}"); try { Hipstershop.Cart cart; var value = await _cache.GetAsync(userId); if (value == null) { cart = new Hipstershop.Cart(); cart.UserId = userId; cart.Items.Add(new Hipstershop.CartItem { ProductId = productId, Quantity = quantity }); } else { cart = Hipstershop.Cart.Parser.ParseFrom(value); var existingItem = cart.Items.SingleOrDefault(i => i.ProductId == productId); if (existingItem == null) { cart.Items.Add(new Hipstershop.CartItem { ProductId = productId, Quantity = quantity }); } else { existingItem.Quantity += quantity; } } await _cache.SetAsync(userId, cart.ToByteArray()); } catch (Exception ex) { throw new RpcException(new Status(StatusCode.FailedPrecondition, $"Can't access cart storage. {ex}")); } } public async Task EmptyCartAsync(string userId) { Console.WriteLine($"EmptyCartAsync called with userId={userId}"); try { var cart = new Hipstershop.Cart(); await _cache.SetAsync(userId, cart.ToByteArray()); } catch (Exception ex) { throw new RpcException(new Status(StatusCode.FailedPrecondition, $"Can't access cart storage. {ex}")); } } public async Task GetCartAsync(string userId) { Console.WriteLine($"GetCartAsync called with userId={userId}"); try { // Access the cart from the cache var value = await _cache.GetAsync(userId); if (value != null) { return Hipstershop.Cart.Parser.ParseFrom(value); } // We decided to return empty cart in cases when user wasn't in the cache before return new Hipstershop.Cart(); } catch (Exception ex) { throw new RpcException(new Status(StatusCode.FailedPrecondition, $"Can't access cart storage. {ex}")); } } public bool Ping() { try { return true; } catch (Exception) { return false; } } } } ================================================ FILE: microservices-demo/src/cartservice/src/protos/Cart.proto ================================================ // Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. syntax = "proto3"; package hipstershop; // -----------------Cart service----------------- service CartService { rpc AddItem(AddItemRequest) returns (Empty) {} rpc GetCart(GetCartRequest) returns (Cart) {} rpc EmptyCart(EmptyCartRequest) returns (Empty) {} } message CartItem { string product_id = 1; int32 quantity = 2; } message AddItemRequest { string user_id = 1; CartItem item = 2; } message EmptyCartRequest { string user_id = 1; } message GetCartRequest { string user_id = 1; } message Cart { string user_id = 1; repeated CartItem items = 2; } message Empty {} ================================================ FILE: microservices-demo/src/cartservice/src/services/CartService.cs ================================================ // Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using System; using System.Threading.Tasks; using Grpc.Core; using Microsoft.Extensions.Logging; using cartservice.cartstore; using Hipstershop; namespace cartservice.services { public class CartService : Hipstershop.CartService.CartServiceBase { private readonly static Empty Empty = new Empty(); private readonly ICartStore _cartStore; public CartService(ICartStore cartStore) { _cartStore = cartStore; } public async override Task AddItem(AddItemRequest request, ServerCallContext context) { await _cartStore.AddItemAsync(request.UserId, request.Item.ProductId, request.Item.Quantity); return Empty; } public override Task GetCart(GetCartRequest request, ServerCallContext context) { return _cartStore.GetCartAsync(request.UserId); } public async override Task EmptyCart(EmptyCartRequest request, ServerCallContext context) { await _cartStore.EmptyCartAsync(request.UserId); return Empty; } } } ================================================ FILE: microservices-demo/src/cartservice/src/services/HealthCheckService.cs ================================================ // Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using System; using System.Threading.Tasks; using Grpc.Core; using Grpc.Health.V1; using static Grpc.Health.V1.Health; using cartservice.cartstore; namespace cartservice.services { internal class HealthCheckService : HealthBase { private ICartStore _cartStore { get; } public HealthCheckService (ICartStore cartStore) { _cartStore = cartStore; } public override Task Check(HealthCheckRequest request, ServerCallContext context) { Console.WriteLine ("Checking CartService Health"); return Task.FromResult(new HealthCheckResponse { Status = _cartStore.Ping() ? HealthCheckResponse.Types.ServingStatus.Serving : HealthCheckResponse.Types.ServingStatus.NotServing }); } } } ================================================ FILE: microservices-demo/src/cartservice/tests/.gitignore ================================================ /bin/* /obj/* /.vs/* ================================================ FILE: microservices-demo/src/cartservice/tests/CartServiceTests.cs ================================================ // Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using System; using System.Threading.Tasks; using Grpc.Net.Client; using Hipstershop; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.TestHost; using Microsoft.Extensions.Hosting; using Xunit; using static Hipstershop.CartService; namespace cartservice.tests { public class CartServiceTests { private readonly IHostBuilder _host; public CartServiceTests() { _host = new HostBuilder().ConfigureWebHost(webBuilder => { webBuilder .UseStartup() .UseTestServer(); }); } [Fact] public async Task GetItem_NoAddItemBefore_EmptyCartReturned() { // Setup test server and client using var server = await _host.StartAsync(); var httpClient = server.GetTestClient(); string userId = Guid.NewGuid().ToString(); // Create a GRPC communication channel between the client and the server var channel = GrpcChannel.ForAddress(httpClient.BaseAddress, new GrpcChannelOptions { HttpClient = httpClient }); var cartClient = new CartServiceClient(channel); var request = new GetCartRequest { UserId = userId, }; var cart = await cartClient.GetCartAsync(request); Assert.NotNull(cart); // All grpc objects implement IEquitable, so we can compare equality with by-value semantics Assert.Equal(new Cart(), cart); } [Fact] public async Task AddItem_ItemExists_Updated() { // Setup test server and client using var server = await _host.StartAsync(); var httpClient = server.GetTestClient(); string userId = Guid.NewGuid().ToString(); // Create a GRPC communication channel between the client and the server var channel = GrpcChannel.ForAddress(httpClient.BaseAddress, new GrpcChannelOptions { HttpClient = httpClient }); var client = new CartServiceClient(channel); var request = new AddItemRequest { UserId = userId, Item = new CartItem { ProductId = "1", Quantity = 1 } }; // First add - nothing should fail await client.AddItemAsync(request); // Second add of existing product - quantity should be updated await client.AddItemAsync(request); var getCartRequest = new GetCartRequest { UserId = userId }; var cart = await client.GetCartAsync(getCartRequest); Assert.NotNull(cart); Assert.Equal(userId, cart.UserId); Assert.Single(cart.Items); Assert.Equal(2, cart.Items[0].Quantity); // Cleanup await client.EmptyCartAsync(new EmptyCartRequest { UserId = userId }); } [Fact] public async Task AddItem_New_Inserted() { // Setup test server and client using var server = await _host.StartAsync(); var httpClient = server.GetTestClient(); string userId = Guid.NewGuid().ToString(); // Create a GRPC communication channel between the client and the server var channel = GrpcChannel.ForAddress(httpClient.BaseAddress, new GrpcChannelOptions { HttpClient = httpClient }); // Create a proxy object to work with the server var client = new CartServiceClient(channel); var request = new AddItemRequest { UserId = userId, Item = new CartItem { ProductId = "1", Quantity = 1 } }; await client.AddItemAsync(request); var getCartRequest = new GetCartRequest { UserId = userId }; var cart = await client.GetCartAsync(getCartRequest); Assert.NotNull(cart); Assert.Equal(userId, cart.UserId); Assert.Single(cart.Items); await client.EmptyCartAsync(new EmptyCartRequest { UserId = userId }); cart = await client.GetCartAsync(getCartRequest); Assert.Empty(cart.Items); } } } ================================================ FILE: microservices-demo/src/cartservice/tests/cartservice.tests.csproj ================================================ net6.0 false ================================================ FILE: microservices-demo/src/checkoutservice/.dockerignore ================================================ vendor/ ================================================ FILE: microservices-demo/src/checkoutservice/Dockerfile ================================================ # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. FROM golang:1.18.4-alpine as builder RUN apk add --no-cache ca-certificates git RUN apk add build-base WORKDIR /src # restore dependencies COPY go.mod go.sum ./ RUN go mod download COPY . . # Skaffold passes in debug-oriented compiler flags ARG SKAFFOLD_GO_GCFLAGS RUN go build -gcflags="${SKAFFOLD_GO_GCFLAGS}" -o /checkoutservice . FROM alpine as release RUN apk add --no-cache ca-certificates RUN GRPC_HEALTH_PROBE_VERSION=v0.4.11 && \ wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \ chmod +x /bin/grpc_health_probe WORKDIR /src COPY --from=builder /checkoutservice /src/checkoutservice # Definition of this variable is used by 'skaffold debug' to identify a golang binary. # Default behavior - a failure prints a stack trace for the current goroutine. # See https://golang.org/pkg/runtime/ ENV GOTRACEBACK=single EXPOSE 5050 ENTRYPOINT ["/src/checkoutservice"] ================================================ FILE: microservices-demo/src/checkoutservice/README.md ================================================ # checkoutservice Run the following command to restore dependencies to `vendor/` directory: dep ensure --vendor-only ================================================ FILE: microservices-demo/src/checkoutservice/genproto/demo.pb.go ================================================ // Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go. DO NOT EDIT. // source: demo.proto package hipstershop import ( fmt "fmt" proto "github.com/golang/protobuf/proto" math "math" ) import ( context "golang.org/x/net/context" grpc "google.golang.org/grpc" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package type CartItem struct { ProductId string `protobuf:"bytes,1,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` Quantity int32 `protobuf:"varint,2,opt,name=quantity,proto3" json:"quantity,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *CartItem) Reset() { *m = CartItem{} } func (m *CartItem) String() string { return proto.CompactTextString(m) } func (*CartItem) ProtoMessage() {} func (*CartItem) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{0} } func (m *CartItem) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CartItem.Unmarshal(m, b) } func (m *CartItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CartItem.Marshal(b, m, deterministic) } func (m *CartItem) XXX_Merge(src proto.Message) { xxx_messageInfo_CartItem.Merge(m, src) } func (m *CartItem) XXX_Size() int { return xxx_messageInfo_CartItem.Size(m) } func (m *CartItem) XXX_DiscardUnknown() { xxx_messageInfo_CartItem.DiscardUnknown(m) } var xxx_messageInfo_CartItem proto.InternalMessageInfo func (m *CartItem) GetProductId() string { if m != nil { return m.ProductId } return "" } func (m *CartItem) GetQuantity() int32 { if m != nil { return m.Quantity } return 0 } type AddItemRequest struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` Item *CartItem `protobuf:"bytes,2,opt,name=item,proto3" json:"item,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *AddItemRequest) Reset() { *m = AddItemRequest{} } func (m *AddItemRequest) String() string { return proto.CompactTextString(m) } func (*AddItemRequest) ProtoMessage() {} func (*AddItemRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{1} } func (m *AddItemRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AddItemRequest.Unmarshal(m, b) } func (m *AddItemRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_AddItemRequest.Marshal(b, m, deterministic) } func (m *AddItemRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_AddItemRequest.Merge(m, src) } func (m *AddItemRequest) XXX_Size() int { return xxx_messageInfo_AddItemRequest.Size(m) } func (m *AddItemRequest) XXX_DiscardUnknown() { xxx_messageInfo_AddItemRequest.DiscardUnknown(m) } var xxx_messageInfo_AddItemRequest proto.InternalMessageInfo func (m *AddItemRequest) GetUserId() string { if m != nil { return m.UserId } return "" } func (m *AddItemRequest) GetItem() *CartItem { if m != nil { return m.Item } return nil } type EmptyCartRequest struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *EmptyCartRequest) Reset() { *m = EmptyCartRequest{} } func (m *EmptyCartRequest) String() string { return proto.CompactTextString(m) } func (*EmptyCartRequest) ProtoMessage() {} func (*EmptyCartRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{2} } func (m *EmptyCartRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_EmptyCartRequest.Unmarshal(m, b) } func (m *EmptyCartRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_EmptyCartRequest.Marshal(b, m, deterministic) } func (m *EmptyCartRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_EmptyCartRequest.Merge(m, src) } func (m *EmptyCartRequest) XXX_Size() int { return xxx_messageInfo_EmptyCartRequest.Size(m) } func (m *EmptyCartRequest) XXX_DiscardUnknown() { xxx_messageInfo_EmptyCartRequest.DiscardUnknown(m) } var xxx_messageInfo_EmptyCartRequest proto.InternalMessageInfo func (m *EmptyCartRequest) GetUserId() string { if m != nil { return m.UserId } return "" } type GetCartRequest struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *GetCartRequest) Reset() { *m = GetCartRequest{} } func (m *GetCartRequest) String() string { return proto.CompactTextString(m) } func (*GetCartRequest) ProtoMessage() {} func (*GetCartRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{3} } func (m *GetCartRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetCartRequest.Unmarshal(m, b) } func (m *GetCartRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetCartRequest.Marshal(b, m, deterministic) } func (m *GetCartRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_GetCartRequest.Merge(m, src) } func (m *GetCartRequest) XXX_Size() int { return xxx_messageInfo_GetCartRequest.Size(m) } func (m *GetCartRequest) XXX_DiscardUnknown() { xxx_messageInfo_GetCartRequest.DiscardUnknown(m) } var xxx_messageInfo_GetCartRequest proto.InternalMessageInfo func (m *GetCartRequest) GetUserId() string { if m != nil { return m.UserId } return "" } type Cart struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Cart) Reset() { *m = Cart{} } func (m *Cart) String() string { return proto.CompactTextString(m) } func (*Cart) ProtoMessage() {} func (*Cart) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{4} } func (m *Cart) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Cart.Unmarshal(m, b) } func (m *Cart) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Cart.Marshal(b, m, deterministic) } func (m *Cart) XXX_Merge(src proto.Message) { xxx_messageInfo_Cart.Merge(m, src) } func (m *Cart) XXX_Size() int { return xxx_messageInfo_Cart.Size(m) } func (m *Cart) XXX_DiscardUnknown() { xxx_messageInfo_Cart.DiscardUnknown(m) } var xxx_messageInfo_Cart proto.InternalMessageInfo func (m *Cart) GetUserId() string { if m != nil { return m.UserId } return "" } func (m *Cart) GetItems() []*CartItem { if m != nil { return m.Items } return nil } type Empty struct { XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Empty) Reset() { *m = Empty{} } func (m *Empty) String() string { return proto.CompactTextString(m) } func (*Empty) ProtoMessage() {} func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{5} } func (m *Empty) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Empty.Unmarshal(m, b) } func (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Empty.Marshal(b, m, deterministic) } func (m *Empty) XXX_Merge(src proto.Message) { xxx_messageInfo_Empty.Merge(m, src) } func (m *Empty) XXX_Size() int { return xxx_messageInfo_Empty.Size(m) } func (m *Empty) XXX_DiscardUnknown() { xxx_messageInfo_Empty.DiscardUnknown(m) } var xxx_messageInfo_Empty proto.InternalMessageInfo type ListRecommendationsRequest struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` ProductIds []string `protobuf:"bytes,2,rep,name=product_ids,json=productIds,proto3" json:"product_ids,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ListRecommendationsRequest) Reset() { *m = ListRecommendationsRequest{} } func (m *ListRecommendationsRequest) String() string { return proto.CompactTextString(m) } func (*ListRecommendationsRequest) ProtoMessage() {} func (*ListRecommendationsRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{6} } func (m *ListRecommendationsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ListRecommendationsRequest.Unmarshal(m, b) } func (m *ListRecommendationsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ListRecommendationsRequest.Marshal(b, m, deterministic) } func (m *ListRecommendationsRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_ListRecommendationsRequest.Merge(m, src) } func (m *ListRecommendationsRequest) XXX_Size() int { return xxx_messageInfo_ListRecommendationsRequest.Size(m) } func (m *ListRecommendationsRequest) XXX_DiscardUnknown() { xxx_messageInfo_ListRecommendationsRequest.DiscardUnknown(m) } var xxx_messageInfo_ListRecommendationsRequest proto.InternalMessageInfo func (m *ListRecommendationsRequest) GetUserId() string { if m != nil { return m.UserId } return "" } func (m *ListRecommendationsRequest) GetProductIds() []string { if m != nil { return m.ProductIds } return nil } type ListRecommendationsResponse struct { ProductIds []string `protobuf:"bytes,1,rep,name=product_ids,json=productIds,proto3" json:"product_ids,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ListRecommendationsResponse) Reset() { *m = ListRecommendationsResponse{} } func (m *ListRecommendationsResponse) String() string { return proto.CompactTextString(m) } func (*ListRecommendationsResponse) ProtoMessage() {} func (*ListRecommendationsResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{7} } func (m *ListRecommendationsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ListRecommendationsResponse.Unmarshal(m, b) } func (m *ListRecommendationsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ListRecommendationsResponse.Marshal(b, m, deterministic) } func (m *ListRecommendationsResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_ListRecommendationsResponse.Merge(m, src) } func (m *ListRecommendationsResponse) XXX_Size() int { return xxx_messageInfo_ListRecommendationsResponse.Size(m) } func (m *ListRecommendationsResponse) XXX_DiscardUnknown() { xxx_messageInfo_ListRecommendationsResponse.DiscardUnknown(m) } var xxx_messageInfo_ListRecommendationsResponse proto.InternalMessageInfo func (m *ListRecommendationsResponse) GetProductIds() []string { if m != nil { return m.ProductIds } return nil } type Product struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` Picture string `protobuf:"bytes,4,opt,name=picture,proto3" json:"picture,omitempty"` PriceUsd *Money `protobuf:"bytes,5,opt,name=price_usd,json=priceUsd,proto3" json:"price_usd,omitempty"` // Categories such as "clothing" or "kitchen" that can be used to look up // other related products. Categories []string `protobuf:"bytes,6,rep,name=categories,proto3" json:"categories,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Product) Reset() { *m = Product{} } func (m *Product) String() string { return proto.CompactTextString(m) } func (*Product) ProtoMessage() {} func (*Product) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{8} } func (m *Product) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Product.Unmarshal(m, b) } func (m *Product) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Product.Marshal(b, m, deterministic) } func (m *Product) XXX_Merge(src proto.Message) { xxx_messageInfo_Product.Merge(m, src) } func (m *Product) XXX_Size() int { return xxx_messageInfo_Product.Size(m) } func (m *Product) XXX_DiscardUnknown() { xxx_messageInfo_Product.DiscardUnknown(m) } var xxx_messageInfo_Product proto.InternalMessageInfo func (m *Product) GetId() string { if m != nil { return m.Id } return "" } func (m *Product) GetName() string { if m != nil { return m.Name } return "" } func (m *Product) GetDescription() string { if m != nil { return m.Description } return "" } func (m *Product) GetPicture() string { if m != nil { return m.Picture } return "" } func (m *Product) GetPriceUsd() *Money { if m != nil { return m.PriceUsd } return nil } func (m *Product) GetCategories() []string { if m != nil { return m.Categories } return nil } type ListProductsResponse struct { Products []*Product `protobuf:"bytes,1,rep,name=products,proto3" json:"products,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ListProductsResponse) Reset() { *m = ListProductsResponse{} } func (m *ListProductsResponse) String() string { return proto.CompactTextString(m) } func (*ListProductsResponse) ProtoMessage() {} func (*ListProductsResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{9} } func (m *ListProductsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ListProductsResponse.Unmarshal(m, b) } func (m *ListProductsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ListProductsResponse.Marshal(b, m, deterministic) } func (m *ListProductsResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_ListProductsResponse.Merge(m, src) } func (m *ListProductsResponse) XXX_Size() int { return xxx_messageInfo_ListProductsResponse.Size(m) } func (m *ListProductsResponse) XXX_DiscardUnknown() { xxx_messageInfo_ListProductsResponse.DiscardUnknown(m) } var xxx_messageInfo_ListProductsResponse proto.InternalMessageInfo func (m *ListProductsResponse) GetProducts() []*Product { if m != nil { return m.Products } return nil } type GetProductRequest struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *GetProductRequest) Reset() { *m = GetProductRequest{} } func (m *GetProductRequest) String() string { return proto.CompactTextString(m) } func (*GetProductRequest) ProtoMessage() {} func (*GetProductRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{10} } func (m *GetProductRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetProductRequest.Unmarshal(m, b) } func (m *GetProductRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetProductRequest.Marshal(b, m, deterministic) } func (m *GetProductRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_GetProductRequest.Merge(m, src) } func (m *GetProductRequest) XXX_Size() int { return xxx_messageInfo_GetProductRequest.Size(m) } func (m *GetProductRequest) XXX_DiscardUnknown() { xxx_messageInfo_GetProductRequest.DiscardUnknown(m) } var xxx_messageInfo_GetProductRequest proto.InternalMessageInfo func (m *GetProductRequest) GetId() string { if m != nil { return m.Id } return "" } type SearchProductsRequest struct { Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *SearchProductsRequest) Reset() { *m = SearchProductsRequest{} } func (m *SearchProductsRequest) String() string { return proto.CompactTextString(m) } func (*SearchProductsRequest) ProtoMessage() {} func (*SearchProductsRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{11} } func (m *SearchProductsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SearchProductsRequest.Unmarshal(m, b) } func (m *SearchProductsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SearchProductsRequest.Marshal(b, m, deterministic) } func (m *SearchProductsRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_SearchProductsRequest.Merge(m, src) } func (m *SearchProductsRequest) XXX_Size() int { return xxx_messageInfo_SearchProductsRequest.Size(m) } func (m *SearchProductsRequest) XXX_DiscardUnknown() { xxx_messageInfo_SearchProductsRequest.DiscardUnknown(m) } var xxx_messageInfo_SearchProductsRequest proto.InternalMessageInfo func (m *SearchProductsRequest) GetQuery() string { if m != nil { return m.Query } return "" } type SearchProductsResponse struct { Results []*Product `protobuf:"bytes,1,rep,name=results,proto3" json:"results,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *SearchProductsResponse) Reset() { *m = SearchProductsResponse{} } func (m *SearchProductsResponse) String() string { return proto.CompactTextString(m) } func (*SearchProductsResponse) ProtoMessage() {} func (*SearchProductsResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{12} } func (m *SearchProductsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SearchProductsResponse.Unmarshal(m, b) } func (m *SearchProductsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SearchProductsResponse.Marshal(b, m, deterministic) } func (m *SearchProductsResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_SearchProductsResponse.Merge(m, src) } func (m *SearchProductsResponse) XXX_Size() int { return xxx_messageInfo_SearchProductsResponse.Size(m) } func (m *SearchProductsResponse) XXX_DiscardUnknown() { xxx_messageInfo_SearchProductsResponse.DiscardUnknown(m) } var xxx_messageInfo_SearchProductsResponse proto.InternalMessageInfo func (m *SearchProductsResponse) GetResults() []*Product { if m != nil { return m.Results } return nil } type GetQuoteRequest struct { Address *Address `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *GetQuoteRequest) Reset() { *m = GetQuoteRequest{} } func (m *GetQuoteRequest) String() string { return proto.CompactTextString(m) } func (*GetQuoteRequest) ProtoMessage() {} func (*GetQuoteRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{13} } func (m *GetQuoteRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetQuoteRequest.Unmarshal(m, b) } func (m *GetQuoteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetQuoteRequest.Marshal(b, m, deterministic) } func (m *GetQuoteRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_GetQuoteRequest.Merge(m, src) } func (m *GetQuoteRequest) XXX_Size() int { return xxx_messageInfo_GetQuoteRequest.Size(m) } func (m *GetQuoteRequest) XXX_DiscardUnknown() { xxx_messageInfo_GetQuoteRequest.DiscardUnknown(m) } var xxx_messageInfo_GetQuoteRequest proto.InternalMessageInfo func (m *GetQuoteRequest) GetAddress() *Address { if m != nil { return m.Address } return nil } func (m *GetQuoteRequest) GetItems() []*CartItem { if m != nil { return m.Items } return nil } type GetQuoteResponse struct { CostUsd *Money `protobuf:"bytes,1,opt,name=cost_usd,json=costUsd,proto3" json:"cost_usd,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *GetQuoteResponse) Reset() { *m = GetQuoteResponse{} } func (m *GetQuoteResponse) String() string { return proto.CompactTextString(m) } func (*GetQuoteResponse) ProtoMessage() {} func (*GetQuoteResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{14} } func (m *GetQuoteResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetQuoteResponse.Unmarshal(m, b) } func (m *GetQuoteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetQuoteResponse.Marshal(b, m, deterministic) } func (m *GetQuoteResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_GetQuoteResponse.Merge(m, src) } func (m *GetQuoteResponse) XXX_Size() int { return xxx_messageInfo_GetQuoteResponse.Size(m) } func (m *GetQuoteResponse) XXX_DiscardUnknown() { xxx_messageInfo_GetQuoteResponse.DiscardUnknown(m) } var xxx_messageInfo_GetQuoteResponse proto.InternalMessageInfo func (m *GetQuoteResponse) GetCostUsd() *Money { if m != nil { return m.CostUsd } return nil } type ShipOrderRequest struct { Address *Address `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ShipOrderRequest) Reset() { *m = ShipOrderRequest{} } func (m *ShipOrderRequest) String() string { return proto.CompactTextString(m) } func (*ShipOrderRequest) ProtoMessage() {} func (*ShipOrderRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{15} } func (m *ShipOrderRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ShipOrderRequest.Unmarshal(m, b) } func (m *ShipOrderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ShipOrderRequest.Marshal(b, m, deterministic) } func (m *ShipOrderRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_ShipOrderRequest.Merge(m, src) } func (m *ShipOrderRequest) XXX_Size() int { return xxx_messageInfo_ShipOrderRequest.Size(m) } func (m *ShipOrderRequest) XXX_DiscardUnknown() { xxx_messageInfo_ShipOrderRequest.DiscardUnknown(m) } var xxx_messageInfo_ShipOrderRequest proto.InternalMessageInfo func (m *ShipOrderRequest) GetAddress() *Address { if m != nil { return m.Address } return nil } func (m *ShipOrderRequest) GetItems() []*CartItem { if m != nil { return m.Items } return nil } type ShipOrderResponse struct { TrackingId string `protobuf:"bytes,1,opt,name=tracking_id,json=trackingId,proto3" json:"tracking_id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ShipOrderResponse) Reset() { *m = ShipOrderResponse{} } func (m *ShipOrderResponse) String() string { return proto.CompactTextString(m) } func (*ShipOrderResponse) ProtoMessage() {} func (*ShipOrderResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{16} } func (m *ShipOrderResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ShipOrderResponse.Unmarshal(m, b) } func (m *ShipOrderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ShipOrderResponse.Marshal(b, m, deterministic) } func (m *ShipOrderResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_ShipOrderResponse.Merge(m, src) } func (m *ShipOrderResponse) XXX_Size() int { return xxx_messageInfo_ShipOrderResponse.Size(m) } func (m *ShipOrderResponse) XXX_DiscardUnknown() { xxx_messageInfo_ShipOrderResponse.DiscardUnknown(m) } var xxx_messageInfo_ShipOrderResponse proto.InternalMessageInfo func (m *ShipOrderResponse) GetTrackingId() string { if m != nil { return m.TrackingId } return "" } type Address struct { StreetAddress string `protobuf:"bytes,1,opt,name=street_address,json=streetAddress,proto3" json:"street_address,omitempty"` City string `protobuf:"bytes,2,opt,name=city,proto3" json:"city,omitempty"` State string `protobuf:"bytes,3,opt,name=state,proto3" json:"state,omitempty"` Country string `protobuf:"bytes,4,opt,name=country,proto3" json:"country,omitempty"` ZipCode int32 `protobuf:"varint,5,opt,name=zip_code,json=zipCode,proto3" json:"zip_code,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Address) Reset() { *m = Address{} } func (m *Address) String() string { return proto.CompactTextString(m) } func (*Address) ProtoMessage() {} func (*Address) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{17} } func (m *Address) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Address.Unmarshal(m, b) } func (m *Address) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Address.Marshal(b, m, deterministic) } func (m *Address) XXX_Merge(src proto.Message) { xxx_messageInfo_Address.Merge(m, src) } func (m *Address) XXX_Size() int { return xxx_messageInfo_Address.Size(m) } func (m *Address) XXX_DiscardUnknown() { xxx_messageInfo_Address.DiscardUnknown(m) } var xxx_messageInfo_Address proto.InternalMessageInfo func (m *Address) GetStreetAddress() string { if m != nil { return m.StreetAddress } return "" } func (m *Address) GetCity() string { if m != nil { return m.City } return "" } func (m *Address) GetState() string { if m != nil { return m.State } return "" } func (m *Address) GetCountry() string { if m != nil { return m.Country } return "" } func (m *Address) GetZipCode() int32 { if m != nil { return m.ZipCode } return 0 } // Represents an amount of money with its currency type. type Money struct { // The 3-letter currency code defined in ISO 4217. CurrencyCode string `protobuf:"bytes,1,opt,name=currency_code,json=currencyCode,proto3" json:"currency_code,omitempty"` // The whole units of the amount. // For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar. Units int64 `protobuf:"varint,2,opt,name=units,proto3" json:"units,omitempty"` // Number of nano (10^-9) units of the amount. // The value must be between -999,999,999 and +999,999,999 inclusive. // If `units` is positive, `nanos` must be positive or zero. // If `units` is zero, `nanos` can be positive, zero, or negative. // If `units` is negative, `nanos` must be negative or zero. // For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000. Nanos int32 `protobuf:"varint,3,opt,name=nanos,proto3" json:"nanos,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Money) Reset() { *m = Money{} } func (m *Money) String() string { return proto.CompactTextString(m) } func (*Money) ProtoMessage() {} func (*Money) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{18} } func (m *Money) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Money.Unmarshal(m, b) } func (m *Money) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Money.Marshal(b, m, deterministic) } func (m *Money) XXX_Merge(src proto.Message) { xxx_messageInfo_Money.Merge(m, src) } func (m *Money) XXX_Size() int { return xxx_messageInfo_Money.Size(m) } func (m *Money) XXX_DiscardUnknown() { xxx_messageInfo_Money.DiscardUnknown(m) } var xxx_messageInfo_Money proto.InternalMessageInfo func (m *Money) GetCurrencyCode() string { if m != nil { return m.CurrencyCode } return "" } func (m *Money) GetUnits() int64 { if m != nil { return m.Units } return 0 } func (m *Money) GetNanos() int32 { if m != nil { return m.Nanos } return 0 } type GetSupportedCurrenciesResponse struct { // The 3-letter currency code defined in ISO 4217. CurrencyCodes []string `protobuf:"bytes,1,rep,name=currency_codes,json=currencyCodes,proto3" json:"currency_codes,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *GetSupportedCurrenciesResponse) Reset() { *m = GetSupportedCurrenciesResponse{} } func (m *GetSupportedCurrenciesResponse) String() string { return proto.CompactTextString(m) } func (*GetSupportedCurrenciesResponse) ProtoMessage() {} func (*GetSupportedCurrenciesResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{19} } func (m *GetSupportedCurrenciesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSupportedCurrenciesResponse.Unmarshal(m, b) } func (m *GetSupportedCurrenciesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetSupportedCurrenciesResponse.Marshal(b, m, deterministic) } func (m *GetSupportedCurrenciesResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_GetSupportedCurrenciesResponse.Merge(m, src) } func (m *GetSupportedCurrenciesResponse) XXX_Size() int { return xxx_messageInfo_GetSupportedCurrenciesResponse.Size(m) } func (m *GetSupportedCurrenciesResponse) XXX_DiscardUnknown() { xxx_messageInfo_GetSupportedCurrenciesResponse.DiscardUnknown(m) } var xxx_messageInfo_GetSupportedCurrenciesResponse proto.InternalMessageInfo func (m *GetSupportedCurrenciesResponse) GetCurrencyCodes() []string { if m != nil { return m.CurrencyCodes } return nil } type CurrencyConversionRequest struct { From *Money `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"` // The 3-letter currency code defined in ISO 4217. ToCode string `protobuf:"bytes,2,opt,name=to_code,json=toCode,proto3" json:"to_code,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *CurrencyConversionRequest) Reset() { *m = CurrencyConversionRequest{} } func (m *CurrencyConversionRequest) String() string { return proto.CompactTextString(m) } func (*CurrencyConversionRequest) ProtoMessage() {} func (*CurrencyConversionRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{20} } func (m *CurrencyConversionRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CurrencyConversionRequest.Unmarshal(m, b) } func (m *CurrencyConversionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CurrencyConversionRequest.Marshal(b, m, deterministic) } func (m *CurrencyConversionRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_CurrencyConversionRequest.Merge(m, src) } func (m *CurrencyConversionRequest) XXX_Size() int { return xxx_messageInfo_CurrencyConversionRequest.Size(m) } func (m *CurrencyConversionRequest) XXX_DiscardUnknown() { xxx_messageInfo_CurrencyConversionRequest.DiscardUnknown(m) } var xxx_messageInfo_CurrencyConversionRequest proto.InternalMessageInfo func (m *CurrencyConversionRequest) GetFrom() *Money { if m != nil { return m.From } return nil } func (m *CurrencyConversionRequest) GetToCode() string { if m != nil { return m.ToCode } return "" } type CreditCardInfo struct { CreditCardNumber string `protobuf:"bytes,1,opt,name=credit_card_number,json=creditCardNumber,proto3" json:"credit_card_number,omitempty"` CreditCardCvv int32 `protobuf:"varint,2,opt,name=credit_card_cvv,json=creditCardCvv,proto3" json:"credit_card_cvv,omitempty"` CreditCardExpirationYear int32 `protobuf:"varint,3,opt,name=credit_card_expiration_year,json=creditCardExpirationYear,proto3" json:"credit_card_expiration_year,omitempty"` CreditCardExpirationMonth int32 `protobuf:"varint,4,opt,name=credit_card_expiration_month,json=creditCardExpirationMonth,proto3" json:"credit_card_expiration_month,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *CreditCardInfo) Reset() { *m = CreditCardInfo{} } func (m *CreditCardInfo) String() string { return proto.CompactTextString(m) } func (*CreditCardInfo) ProtoMessage() {} func (*CreditCardInfo) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{21} } func (m *CreditCardInfo) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CreditCardInfo.Unmarshal(m, b) } func (m *CreditCardInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CreditCardInfo.Marshal(b, m, deterministic) } func (m *CreditCardInfo) XXX_Merge(src proto.Message) { xxx_messageInfo_CreditCardInfo.Merge(m, src) } func (m *CreditCardInfo) XXX_Size() int { return xxx_messageInfo_CreditCardInfo.Size(m) } func (m *CreditCardInfo) XXX_DiscardUnknown() { xxx_messageInfo_CreditCardInfo.DiscardUnknown(m) } var xxx_messageInfo_CreditCardInfo proto.InternalMessageInfo func (m *CreditCardInfo) GetCreditCardNumber() string { if m != nil { return m.CreditCardNumber } return "" } func (m *CreditCardInfo) GetCreditCardCvv() int32 { if m != nil { return m.CreditCardCvv } return 0 } func (m *CreditCardInfo) GetCreditCardExpirationYear() int32 { if m != nil { return m.CreditCardExpirationYear } return 0 } func (m *CreditCardInfo) GetCreditCardExpirationMonth() int32 { if m != nil { return m.CreditCardExpirationMonth } return 0 } type ChargeRequest struct { Amount *Money `protobuf:"bytes,1,opt,name=amount,proto3" json:"amount,omitempty"` CreditCard *CreditCardInfo `protobuf:"bytes,2,opt,name=credit_card,json=creditCard,proto3" json:"credit_card,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ChargeRequest) Reset() { *m = ChargeRequest{} } func (m *ChargeRequest) String() string { return proto.CompactTextString(m) } func (*ChargeRequest) ProtoMessage() {} func (*ChargeRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{22} } func (m *ChargeRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ChargeRequest.Unmarshal(m, b) } func (m *ChargeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ChargeRequest.Marshal(b, m, deterministic) } func (m *ChargeRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_ChargeRequest.Merge(m, src) } func (m *ChargeRequest) XXX_Size() int { return xxx_messageInfo_ChargeRequest.Size(m) } func (m *ChargeRequest) XXX_DiscardUnknown() { xxx_messageInfo_ChargeRequest.DiscardUnknown(m) } var xxx_messageInfo_ChargeRequest proto.InternalMessageInfo func (m *ChargeRequest) GetAmount() *Money { if m != nil { return m.Amount } return nil } func (m *ChargeRequest) GetCreditCard() *CreditCardInfo { if m != nil { return m.CreditCard } return nil } type ChargeResponse struct { TransactionId string `protobuf:"bytes,1,opt,name=transaction_id,json=transactionId,proto3" json:"transaction_id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ChargeResponse) Reset() { *m = ChargeResponse{} } func (m *ChargeResponse) String() string { return proto.CompactTextString(m) } func (*ChargeResponse) ProtoMessage() {} func (*ChargeResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{23} } func (m *ChargeResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ChargeResponse.Unmarshal(m, b) } func (m *ChargeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ChargeResponse.Marshal(b, m, deterministic) } func (m *ChargeResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_ChargeResponse.Merge(m, src) } func (m *ChargeResponse) XXX_Size() int { return xxx_messageInfo_ChargeResponse.Size(m) } func (m *ChargeResponse) XXX_DiscardUnknown() { xxx_messageInfo_ChargeResponse.DiscardUnknown(m) } var xxx_messageInfo_ChargeResponse proto.InternalMessageInfo func (m *ChargeResponse) GetTransactionId() string { if m != nil { return m.TransactionId } return "" } type OrderItem struct { Item *CartItem `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` Cost *Money `protobuf:"bytes,2,opt,name=cost,proto3" json:"cost,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *OrderItem) Reset() { *m = OrderItem{} } func (m *OrderItem) String() string { return proto.CompactTextString(m) } func (*OrderItem) ProtoMessage() {} func (*OrderItem) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{24} } func (m *OrderItem) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_OrderItem.Unmarshal(m, b) } func (m *OrderItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_OrderItem.Marshal(b, m, deterministic) } func (m *OrderItem) XXX_Merge(src proto.Message) { xxx_messageInfo_OrderItem.Merge(m, src) } func (m *OrderItem) XXX_Size() int { return xxx_messageInfo_OrderItem.Size(m) } func (m *OrderItem) XXX_DiscardUnknown() { xxx_messageInfo_OrderItem.DiscardUnknown(m) } var xxx_messageInfo_OrderItem proto.InternalMessageInfo func (m *OrderItem) GetItem() *CartItem { if m != nil { return m.Item } return nil } func (m *OrderItem) GetCost() *Money { if m != nil { return m.Cost } return nil } type OrderResult struct { OrderId string `protobuf:"bytes,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` ShippingTrackingId string `protobuf:"bytes,2,opt,name=shipping_tracking_id,json=shippingTrackingId,proto3" json:"shipping_tracking_id,omitempty"` ShippingCost *Money `protobuf:"bytes,3,opt,name=shipping_cost,json=shippingCost,proto3" json:"shipping_cost,omitempty"` ShippingAddress *Address `protobuf:"bytes,4,opt,name=shipping_address,json=shippingAddress,proto3" json:"shipping_address,omitempty"` Items []*OrderItem `protobuf:"bytes,5,rep,name=items,proto3" json:"items,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *OrderResult) Reset() { *m = OrderResult{} } func (m *OrderResult) String() string { return proto.CompactTextString(m) } func (*OrderResult) ProtoMessage() {} func (*OrderResult) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{25} } func (m *OrderResult) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_OrderResult.Unmarshal(m, b) } func (m *OrderResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_OrderResult.Marshal(b, m, deterministic) } func (m *OrderResult) XXX_Merge(src proto.Message) { xxx_messageInfo_OrderResult.Merge(m, src) } func (m *OrderResult) XXX_Size() int { return xxx_messageInfo_OrderResult.Size(m) } func (m *OrderResult) XXX_DiscardUnknown() { xxx_messageInfo_OrderResult.DiscardUnknown(m) } var xxx_messageInfo_OrderResult proto.InternalMessageInfo func (m *OrderResult) GetOrderId() string { if m != nil { return m.OrderId } return "" } func (m *OrderResult) GetShippingTrackingId() string { if m != nil { return m.ShippingTrackingId } return "" } func (m *OrderResult) GetShippingCost() *Money { if m != nil { return m.ShippingCost } return nil } func (m *OrderResult) GetShippingAddress() *Address { if m != nil { return m.ShippingAddress } return nil } func (m *OrderResult) GetItems() []*OrderItem { if m != nil { return m.Items } return nil } type SendOrderConfirmationRequest struct { Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` Order *OrderResult `protobuf:"bytes,2,opt,name=order,proto3" json:"order,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *SendOrderConfirmationRequest) Reset() { *m = SendOrderConfirmationRequest{} } func (m *SendOrderConfirmationRequest) String() string { return proto.CompactTextString(m) } func (*SendOrderConfirmationRequest) ProtoMessage() {} func (*SendOrderConfirmationRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{26} } func (m *SendOrderConfirmationRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SendOrderConfirmationRequest.Unmarshal(m, b) } func (m *SendOrderConfirmationRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SendOrderConfirmationRequest.Marshal(b, m, deterministic) } func (m *SendOrderConfirmationRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_SendOrderConfirmationRequest.Merge(m, src) } func (m *SendOrderConfirmationRequest) XXX_Size() int { return xxx_messageInfo_SendOrderConfirmationRequest.Size(m) } func (m *SendOrderConfirmationRequest) XXX_DiscardUnknown() { xxx_messageInfo_SendOrderConfirmationRequest.DiscardUnknown(m) } var xxx_messageInfo_SendOrderConfirmationRequest proto.InternalMessageInfo func (m *SendOrderConfirmationRequest) GetEmail() string { if m != nil { return m.Email } return "" } func (m *SendOrderConfirmationRequest) GetOrder() *OrderResult { if m != nil { return m.Order } return nil } type PlaceOrderRequest struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` UserCurrency string `protobuf:"bytes,2,opt,name=user_currency,json=userCurrency,proto3" json:"user_currency,omitempty"` Address *Address `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"` Email string `protobuf:"bytes,5,opt,name=email,proto3" json:"email,omitempty"` CreditCard *CreditCardInfo `protobuf:"bytes,6,opt,name=credit_card,json=creditCard,proto3" json:"credit_card,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *PlaceOrderRequest) Reset() { *m = PlaceOrderRequest{} } func (m *PlaceOrderRequest) String() string { return proto.CompactTextString(m) } func (*PlaceOrderRequest) ProtoMessage() {} func (*PlaceOrderRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{27} } func (m *PlaceOrderRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PlaceOrderRequest.Unmarshal(m, b) } func (m *PlaceOrderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PlaceOrderRequest.Marshal(b, m, deterministic) } func (m *PlaceOrderRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_PlaceOrderRequest.Merge(m, src) } func (m *PlaceOrderRequest) XXX_Size() int { return xxx_messageInfo_PlaceOrderRequest.Size(m) } func (m *PlaceOrderRequest) XXX_DiscardUnknown() { xxx_messageInfo_PlaceOrderRequest.DiscardUnknown(m) } var xxx_messageInfo_PlaceOrderRequest proto.InternalMessageInfo func (m *PlaceOrderRequest) GetUserId() string { if m != nil { return m.UserId } return "" } func (m *PlaceOrderRequest) GetUserCurrency() string { if m != nil { return m.UserCurrency } return "" } func (m *PlaceOrderRequest) GetAddress() *Address { if m != nil { return m.Address } return nil } func (m *PlaceOrderRequest) GetEmail() string { if m != nil { return m.Email } return "" } func (m *PlaceOrderRequest) GetCreditCard() *CreditCardInfo { if m != nil { return m.CreditCard } return nil } type PlaceOrderResponse struct { Order *OrderResult `protobuf:"bytes,1,opt,name=order,proto3" json:"order,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *PlaceOrderResponse) Reset() { *m = PlaceOrderResponse{} } func (m *PlaceOrderResponse) String() string { return proto.CompactTextString(m) } func (*PlaceOrderResponse) ProtoMessage() {} func (*PlaceOrderResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{28} } func (m *PlaceOrderResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PlaceOrderResponse.Unmarshal(m, b) } func (m *PlaceOrderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PlaceOrderResponse.Marshal(b, m, deterministic) } func (m *PlaceOrderResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_PlaceOrderResponse.Merge(m, src) } func (m *PlaceOrderResponse) XXX_Size() int { return xxx_messageInfo_PlaceOrderResponse.Size(m) } func (m *PlaceOrderResponse) XXX_DiscardUnknown() { xxx_messageInfo_PlaceOrderResponse.DiscardUnknown(m) } var xxx_messageInfo_PlaceOrderResponse proto.InternalMessageInfo func (m *PlaceOrderResponse) GetOrder() *OrderResult { if m != nil { return m.Order } return nil } type AdRequest struct { // List of important key words from the current page describing the context. ContextKeys []string `protobuf:"bytes,1,rep,name=context_keys,json=contextKeys,proto3" json:"context_keys,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *AdRequest) Reset() { *m = AdRequest{} } func (m *AdRequest) String() string { return proto.CompactTextString(m) } func (*AdRequest) ProtoMessage() {} func (*AdRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{29} } func (m *AdRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AdRequest.Unmarshal(m, b) } func (m *AdRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_AdRequest.Marshal(b, m, deterministic) } func (m *AdRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_AdRequest.Merge(m, src) } func (m *AdRequest) XXX_Size() int { return xxx_messageInfo_AdRequest.Size(m) } func (m *AdRequest) XXX_DiscardUnknown() { xxx_messageInfo_AdRequest.DiscardUnknown(m) } var xxx_messageInfo_AdRequest proto.InternalMessageInfo func (m *AdRequest) GetContextKeys() []string { if m != nil { return m.ContextKeys } return nil } type AdResponse struct { Ads []*Ad `protobuf:"bytes,1,rep,name=ads,proto3" json:"ads,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *AdResponse) Reset() { *m = AdResponse{} } func (m *AdResponse) String() string { return proto.CompactTextString(m) } func (*AdResponse) ProtoMessage() {} func (*AdResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{30} } func (m *AdResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AdResponse.Unmarshal(m, b) } func (m *AdResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_AdResponse.Marshal(b, m, deterministic) } func (m *AdResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_AdResponse.Merge(m, src) } func (m *AdResponse) XXX_Size() int { return xxx_messageInfo_AdResponse.Size(m) } func (m *AdResponse) XXX_DiscardUnknown() { xxx_messageInfo_AdResponse.DiscardUnknown(m) } var xxx_messageInfo_AdResponse proto.InternalMessageInfo func (m *AdResponse) GetAds() []*Ad { if m != nil { return m.Ads } return nil } type Ad struct { // url to redirect to when an ad is clicked. RedirectUrl string `protobuf:"bytes,1,opt,name=redirect_url,json=redirectUrl,proto3" json:"redirect_url,omitempty"` // short advertisement text to display. Text string `protobuf:"bytes,2,opt,name=text,proto3" json:"text,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Ad) Reset() { *m = Ad{} } func (m *Ad) String() string { return proto.CompactTextString(m) } func (*Ad) ProtoMessage() {} func (*Ad) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{31} } func (m *Ad) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Ad.Unmarshal(m, b) } func (m *Ad) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Ad.Marshal(b, m, deterministic) } func (m *Ad) XXX_Merge(src proto.Message) { xxx_messageInfo_Ad.Merge(m, src) } func (m *Ad) XXX_Size() int { return xxx_messageInfo_Ad.Size(m) } func (m *Ad) XXX_DiscardUnknown() { xxx_messageInfo_Ad.DiscardUnknown(m) } var xxx_messageInfo_Ad proto.InternalMessageInfo func (m *Ad) GetRedirectUrl() string { if m != nil { return m.RedirectUrl } return "" } func (m *Ad) GetText() string { if m != nil { return m.Text } return "" } func init() { proto.RegisterType((*CartItem)(nil), "hipstershop.CartItem") proto.RegisterType((*AddItemRequest)(nil), "hipstershop.AddItemRequest") proto.RegisterType((*EmptyCartRequest)(nil), "hipstershop.EmptyCartRequest") proto.RegisterType((*GetCartRequest)(nil), "hipstershop.GetCartRequest") proto.RegisterType((*Cart)(nil), "hipstershop.Cart") proto.RegisterType((*Empty)(nil), "hipstershop.Empty") proto.RegisterType((*ListRecommendationsRequest)(nil), "hipstershop.ListRecommendationsRequest") proto.RegisterType((*ListRecommendationsResponse)(nil), "hipstershop.ListRecommendationsResponse") proto.RegisterType((*Product)(nil), "hipstershop.Product") proto.RegisterType((*ListProductsResponse)(nil), "hipstershop.ListProductsResponse") proto.RegisterType((*GetProductRequest)(nil), "hipstershop.GetProductRequest") proto.RegisterType((*SearchProductsRequest)(nil), "hipstershop.SearchProductsRequest") proto.RegisterType((*SearchProductsResponse)(nil), "hipstershop.SearchProductsResponse") proto.RegisterType((*GetQuoteRequest)(nil), "hipstershop.GetQuoteRequest") proto.RegisterType((*GetQuoteResponse)(nil), "hipstershop.GetQuoteResponse") proto.RegisterType((*ShipOrderRequest)(nil), "hipstershop.ShipOrderRequest") proto.RegisterType((*ShipOrderResponse)(nil), "hipstershop.ShipOrderResponse") proto.RegisterType((*Address)(nil), "hipstershop.Address") proto.RegisterType((*Money)(nil), "hipstershop.Money") proto.RegisterType((*GetSupportedCurrenciesResponse)(nil), "hipstershop.GetSupportedCurrenciesResponse") proto.RegisterType((*CurrencyConversionRequest)(nil), "hipstershop.CurrencyConversionRequest") proto.RegisterType((*CreditCardInfo)(nil), "hipstershop.CreditCardInfo") proto.RegisterType((*ChargeRequest)(nil), "hipstershop.ChargeRequest") proto.RegisterType((*ChargeResponse)(nil), "hipstershop.ChargeResponse") proto.RegisterType((*OrderItem)(nil), "hipstershop.OrderItem") proto.RegisterType((*OrderResult)(nil), "hipstershop.OrderResult") proto.RegisterType((*SendOrderConfirmationRequest)(nil), "hipstershop.SendOrderConfirmationRequest") proto.RegisterType((*PlaceOrderRequest)(nil), "hipstershop.PlaceOrderRequest") proto.RegisterType((*PlaceOrderResponse)(nil), "hipstershop.PlaceOrderResponse") proto.RegisterType((*AdRequest)(nil), "hipstershop.AdRequest") proto.RegisterType((*AdResponse)(nil), "hipstershop.AdResponse") proto.RegisterType((*Ad)(nil), "hipstershop.Ad") } // Reference imports to suppress errors if they are not otherwise used. var _ context.Context var _ grpc.ClientConn // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. const _ = grpc.SupportPackageIsVersion4 // CartServiceClient is the client API for CartService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type CartServiceClient interface { AddItem(ctx context.Context, in *AddItemRequest, opts ...grpc.CallOption) (*Empty, error) GetCart(ctx context.Context, in *GetCartRequest, opts ...grpc.CallOption) (*Cart, error) EmptyCart(ctx context.Context, in *EmptyCartRequest, opts ...grpc.CallOption) (*Empty, error) } type cartServiceClient struct { cc *grpc.ClientConn } func NewCartServiceClient(cc *grpc.ClientConn) CartServiceClient { return &cartServiceClient{cc} } func (c *cartServiceClient) AddItem(ctx context.Context, in *AddItemRequest, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) err := c.cc.Invoke(ctx, "/hipstershop.CartService/AddItem", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *cartServiceClient) GetCart(ctx context.Context, in *GetCartRequest, opts ...grpc.CallOption) (*Cart, error) { out := new(Cart) err := c.cc.Invoke(ctx, "/hipstershop.CartService/GetCart", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *cartServiceClient) EmptyCart(ctx context.Context, in *EmptyCartRequest, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) err := c.cc.Invoke(ctx, "/hipstershop.CartService/EmptyCart", in, out, opts...) if err != nil { return nil, err } return out, nil } // CartServiceServer is the server API for CartService service. type CartServiceServer interface { AddItem(context.Context, *AddItemRequest) (*Empty, error) GetCart(context.Context, *GetCartRequest) (*Cart, error) EmptyCart(context.Context, *EmptyCartRequest) (*Empty, error) } func RegisterCartServiceServer(s *grpc.Server, srv CartServiceServer) { s.RegisterService(&_CartService_serviceDesc, srv) } func _CartService_AddItem_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AddItemRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CartServiceServer).AddItem(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CartService/AddItem", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CartServiceServer).AddItem(ctx, req.(*AddItemRequest)) } return interceptor(ctx, in, info, handler) } func _CartService_GetCart_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetCartRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CartServiceServer).GetCart(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CartService/GetCart", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CartServiceServer).GetCart(ctx, req.(*GetCartRequest)) } return interceptor(ctx, in, info, handler) } func _CartService_EmptyCart_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(EmptyCartRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CartServiceServer).EmptyCart(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CartService/EmptyCart", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CartServiceServer).EmptyCart(ctx, req.(*EmptyCartRequest)) } return interceptor(ctx, in, info, handler) } var _CartService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.CartService", HandlerType: (*CartServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "AddItem", Handler: _CartService_AddItem_Handler, }, { MethodName: "GetCart", Handler: _CartService_GetCart_Handler, }, { MethodName: "EmptyCart", Handler: _CartService_EmptyCart_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // RecommendationServiceClient is the client API for RecommendationService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type RecommendationServiceClient interface { ListRecommendations(ctx context.Context, in *ListRecommendationsRequest, opts ...grpc.CallOption) (*ListRecommendationsResponse, error) } type recommendationServiceClient struct { cc *grpc.ClientConn } func NewRecommendationServiceClient(cc *grpc.ClientConn) RecommendationServiceClient { return &recommendationServiceClient{cc} } func (c *recommendationServiceClient) ListRecommendations(ctx context.Context, in *ListRecommendationsRequest, opts ...grpc.CallOption) (*ListRecommendationsResponse, error) { out := new(ListRecommendationsResponse) err := c.cc.Invoke(ctx, "/hipstershop.RecommendationService/ListRecommendations", in, out, opts...) if err != nil { return nil, err } return out, nil } // RecommendationServiceServer is the server API for RecommendationService service. type RecommendationServiceServer interface { ListRecommendations(context.Context, *ListRecommendationsRequest) (*ListRecommendationsResponse, error) } func RegisterRecommendationServiceServer(s *grpc.Server, srv RecommendationServiceServer) { s.RegisterService(&_RecommendationService_serviceDesc, srv) } func _RecommendationService_ListRecommendations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListRecommendationsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(RecommendationServiceServer).ListRecommendations(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.RecommendationService/ListRecommendations", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(RecommendationServiceServer).ListRecommendations(ctx, req.(*ListRecommendationsRequest)) } return interceptor(ctx, in, info, handler) } var _RecommendationService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.RecommendationService", HandlerType: (*RecommendationServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "ListRecommendations", Handler: _RecommendationService_ListRecommendations_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // ProductCatalogServiceClient is the client API for ProductCatalogService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type ProductCatalogServiceClient interface { ListProducts(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ListProductsResponse, error) GetProduct(ctx context.Context, in *GetProductRequest, opts ...grpc.CallOption) (*Product, error) SearchProducts(ctx context.Context, in *SearchProductsRequest, opts ...grpc.CallOption) (*SearchProductsResponse, error) } type productCatalogServiceClient struct { cc *grpc.ClientConn } func NewProductCatalogServiceClient(cc *grpc.ClientConn) ProductCatalogServiceClient { return &productCatalogServiceClient{cc} } func (c *productCatalogServiceClient) ListProducts(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ListProductsResponse, error) { out := new(ListProductsResponse) err := c.cc.Invoke(ctx, "/hipstershop.ProductCatalogService/ListProducts", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *productCatalogServiceClient) GetProduct(ctx context.Context, in *GetProductRequest, opts ...grpc.CallOption) (*Product, error) { out := new(Product) err := c.cc.Invoke(ctx, "/hipstershop.ProductCatalogService/GetProduct", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *productCatalogServiceClient) SearchProducts(ctx context.Context, in *SearchProductsRequest, opts ...grpc.CallOption) (*SearchProductsResponse, error) { out := new(SearchProductsResponse) err := c.cc.Invoke(ctx, "/hipstershop.ProductCatalogService/SearchProducts", in, out, opts...) if err != nil { return nil, err } return out, nil } // ProductCatalogServiceServer is the server API for ProductCatalogService service. type ProductCatalogServiceServer interface { ListProducts(context.Context, *Empty) (*ListProductsResponse, error) GetProduct(context.Context, *GetProductRequest) (*Product, error) SearchProducts(context.Context, *SearchProductsRequest) (*SearchProductsResponse, error) } func RegisterProductCatalogServiceServer(s *grpc.Server, srv ProductCatalogServiceServer) { s.RegisterService(&_ProductCatalogService_serviceDesc, srv) } func _ProductCatalogService_ListProducts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(Empty) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(ProductCatalogServiceServer).ListProducts(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.ProductCatalogService/ListProducts", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ProductCatalogServiceServer).ListProducts(ctx, req.(*Empty)) } return interceptor(ctx, in, info, handler) } func _ProductCatalogService_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.(ProductCatalogServiceServer).GetProduct(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.ProductCatalogService/GetProduct", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ProductCatalogServiceServer).GetProduct(ctx, req.(*GetProductRequest)) } return interceptor(ctx, in, info, handler) } func _ProductCatalogService_SearchProducts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(SearchProductsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(ProductCatalogServiceServer).SearchProducts(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.ProductCatalogService/SearchProducts", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ProductCatalogServiceServer).SearchProducts(ctx, req.(*SearchProductsRequest)) } return interceptor(ctx, in, info, handler) } var _ProductCatalogService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.ProductCatalogService", HandlerType: (*ProductCatalogServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "ListProducts", Handler: _ProductCatalogService_ListProducts_Handler, }, { MethodName: "GetProduct", Handler: _ProductCatalogService_GetProduct_Handler, }, { MethodName: "SearchProducts", Handler: _ProductCatalogService_SearchProducts_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // ShippingServiceClient is the client API for ShippingService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type ShippingServiceClient interface { GetQuote(ctx context.Context, in *GetQuoteRequest, opts ...grpc.CallOption) (*GetQuoteResponse, error) ShipOrder(ctx context.Context, in *ShipOrderRequest, opts ...grpc.CallOption) (*ShipOrderResponse, error) } type shippingServiceClient struct { cc *grpc.ClientConn } func NewShippingServiceClient(cc *grpc.ClientConn) ShippingServiceClient { return &shippingServiceClient{cc} } func (c *shippingServiceClient) GetQuote(ctx context.Context, in *GetQuoteRequest, opts ...grpc.CallOption) (*GetQuoteResponse, error) { out := new(GetQuoteResponse) err := c.cc.Invoke(ctx, "/hipstershop.ShippingService/GetQuote", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *shippingServiceClient) ShipOrder(ctx context.Context, in *ShipOrderRequest, opts ...grpc.CallOption) (*ShipOrderResponse, error) { out := new(ShipOrderResponse) err := c.cc.Invoke(ctx, "/hipstershop.ShippingService/ShipOrder", in, out, opts...) if err != nil { return nil, err } return out, nil } // ShippingServiceServer is the server API for ShippingService service. type ShippingServiceServer interface { GetQuote(context.Context, *GetQuoteRequest) (*GetQuoteResponse, error) ShipOrder(context.Context, *ShipOrderRequest) (*ShipOrderResponse, error) } func RegisterShippingServiceServer(s *grpc.Server, srv ShippingServiceServer) { s.RegisterService(&_ShippingService_serviceDesc, srv) } func _ShippingService_GetQuote_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetQuoteRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(ShippingServiceServer).GetQuote(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.ShippingService/GetQuote", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ShippingServiceServer).GetQuote(ctx, req.(*GetQuoteRequest)) } return interceptor(ctx, in, info, handler) } func _ShippingService_ShipOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ShipOrderRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(ShippingServiceServer).ShipOrder(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.ShippingService/ShipOrder", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ShippingServiceServer).ShipOrder(ctx, req.(*ShipOrderRequest)) } return interceptor(ctx, in, info, handler) } var _ShippingService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.ShippingService", HandlerType: (*ShippingServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "GetQuote", Handler: _ShippingService_GetQuote_Handler, }, { MethodName: "ShipOrder", Handler: _ShippingService_ShipOrder_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // CurrencyServiceClient is the client API for CurrencyService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type CurrencyServiceClient interface { GetSupportedCurrencies(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetSupportedCurrenciesResponse, error) Convert(ctx context.Context, in *CurrencyConversionRequest, opts ...grpc.CallOption) (*Money, error) } type currencyServiceClient struct { cc *grpc.ClientConn } func NewCurrencyServiceClient(cc *grpc.ClientConn) CurrencyServiceClient { return ¤cyServiceClient{cc} } func (c *currencyServiceClient) GetSupportedCurrencies(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetSupportedCurrenciesResponse, error) { out := new(GetSupportedCurrenciesResponse) err := c.cc.Invoke(ctx, "/hipstershop.CurrencyService/GetSupportedCurrencies", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *currencyServiceClient) Convert(ctx context.Context, in *CurrencyConversionRequest, opts ...grpc.CallOption) (*Money, error) { out := new(Money) err := c.cc.Invoke(ctx, "/hipstershop.CurrencyService/Convert", in, out, opts...) if err != nil { return nil, err } return out, nil } // CurrencyServiceServer is the server API for CurrencyService service. type CurrencyServiceServer interface { GetSupportedCurrencies(context.Context, *Empty) (*GetSupportedCurrenciesResponse, error) Convert(context.Context, *CurrencyConversionRequest) (*Money, error) } func RegisterCurrencyServiceServer(s *grpc.Server, srv CurrencyServiceServer) { s.RegisterService(&_CurrencyService_serviceDesc, srv) } func _CurrencyService_GetSupportedCurrencies_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(Empty) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CurrencyServiceServer).GetSupportedCurrencies(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CurrencyService/GetSupportedCurrencies", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CurrencyServiceServer).GetSupportedCurrencies(ctx, req.(*Empty)) } return interceptor(ctx, in, info, handler) } func _CurrencyService_Convert_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CurrencyConversionRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CurrencyServiceServer).Convert(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CurrencyService/Convert", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CurrencyServiceServer).Convert(ctx, req.(*CurrencyConversionRequest)) } return interceptor(ctx, in, info, handler) } var _CurrencyService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.CurrencyService", HandlerType: (*CurrencyServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "GetSupportedCurrencies", Handler: _CurrencyService_GetSupportedCurrencies_Handler, }, { MethodName: "Convert", Handler: _CurrencyService_Convert_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // PaymentServiceClient is the client API for PaymentService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type PaymentServiceClient interface { Charge(ctx context.Context, in *ChargeRequest, opts ...grpc.CallOption) (*ChargeResponse, error) } type paymentServiceClient struct { cc *grpc.ClientConn } func NewPaymentServiceClient(cc *grpc.ClientConn) PaymentServiceClient { return &paymentServiceClient{cc} } func (c *paymentServiceClient) Charge(ctx context.Context, in *ChargeRequest, opts ...grpc.CallOption) (*ChargeResponse, error) { out := new(ChargeResponse) err := c.cc.Invoke(ctx, "/hipstershop.PaymentService/Charge", in, out, opts...) if err != nil { return nil, err } return out, nil } // PaymentServiceServer is the server API for PaymentService service. type PaymentServiceServer interface { Charge(context.Context, *ChargeRequest) (*ChargeResponse, error) } func RegisterPaymentServiceServer(s *grpc.Server, srv PaymentServiceServer) { s.RegisterService(&_PaymentService_serviceDesc, srv) } func _PaymentService_Charge_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ChargeRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(PaymentServiceServer).Charge(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.PaymentService/Charge", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(PaymentServiceServer).Charge(ctx, req.(*ChargeRequest)) } return interceptor(ctx, in, info, handler) } var _PaymentService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.PaymentService", HandlerType: (*PaymentServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "Charge", Handler: _PaymentService_Charge_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // EmailServiceClient is the client API for EmailService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type EmailServiceClient interface { SendOrderConfirmation(ctx context.Context, in *SendOrderConfirmationRequest, opts ...grpc.CallOption) (*Empty, error) } type emailServiceClient struct { cc *grpc.ClientConn } func NewEmailServiceClient(cc *grpc.ClientConn) EmailServiceClient { return &emailServiceClient{cc} } func (c *emailServiceClient) SendOrderConfirmation(ctx context.Context, in *SendOrderConfirmationRequest, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) err := c.cc.Invoke(ctx, "/hipstershop.EmailService/SendOrderConfirmation", in, out, opts...) if err != nil { return nil, err } return out, nil } // EmailServiceServer is the server API for EmailService service. type EmailServiceServer interface { SendOrderConfirmation(context.Context, *SendOrderConfirmationRequest) (*Empty, error) } func RegisterEmailServiceServer(s *grpc.Server, srv EmailServiceServer) { s.RegisterService(&_EmailService_serviceDesc, srv) } func _EmailService_SendOrderConfirmation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(SendOrderConfirmationRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(EmailServiceServer).SendOrderConfirmation(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.EmailService/SendOrderConfirmation", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(EmailServiceServer).SendOrderConfirmation(ctx, req.(*SendOrderConfirmationRequest)) } return interceptor(ctx, in, info, handler) } var _EmailService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.EmailService", HandlerType: (*EmailServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "SendOrderConfirmation", Handler: _EmailService_SendOrderConfirmation_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // CheckoutServiceClient is the client API for CheckoutService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type CheckoutServiceClient interface { PlaceOrder(ctx context.Context, in *PlaceOrderRequest, opts ...grpc.CallOption) (*PlaceOrderResponse, error) } type checkoutServiceClient struct { cc *grpc.ClientConn } func NewCheckoutServiceClient(cc *grpc.ClientConn) CheckoutServiceClient { return &checkoutServiceClient{cc} } func (c *checkoutServiceClient) PlaceOrder(ctx context.Context, in *PlaceOrderRequest, opts ...grpc.CallOption) (*PlaceOrderResponse, error) { out := new(PlaceOrderResponse) err := c.cc.Invoke(ctx, "/hipstershop.CheckoutService/PlaceOrder", in, out, opts...) if err != nil { return nil, err } return out, nil } // CheckoutServiceServer is the server API for CheckoutService service. type CheckoutServiceServer interface { PlaceOrder(context.Context, *PlaceOrderRequest) (*PlaceOrderResponse, error) } func RegisterCheckoutServiceServer(s *grpc.Server, srv CheckoutServiceServer) { s.RegisterService(&_CheckoutService_serviceDesc, srv) } func _CheckoutService_PlaceOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(PlaceOrderRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CheckoutServiceServer).PlaceOrder(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CheckoutService/PlaceOrder", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CheckoutServiceServer).PlaceOrder(ctx, req.(*PlaceOrderRequest)) } return interceptor(ctx, in, info, handler) } var _CheckoutService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.CheckoutService", HandlerType: (*CheckoutServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "PlaceOrder", Handler: _CheckoutService_PlaceOrder_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // AdServiceClient is the client API for AdService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type AdServiceClient interface { GetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error) } type adServiceClient struct { cc *grpc.ClientConn } func NewAdServiceClient(cc *grpc.ClientConn) AdServiceClient { return &adServiceClient{cc} } func (c *adServiceClient) GetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error) { out := new(AdResponse) err := c.cc.Invoke(ctx, "/hipstershop.AdService/GetAds", in, out, opts...) if err != nil { return nil, err } return out, nil } // AdServiceServer is the server API for AdService service. type AdServiceServer interface { GetAds(context.Context, *AdRequest) (*AdResponse, error) } func RegisterAdServiceServer(s *grpc.Server, srv AdServiceServer) { s.RegisterService(&_AdService_serviceDesc, srv) } func _AdService_GetAds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AdRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(AdServiceServer).GetAds(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.AdService/GetAds", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(AdServiceServer).GetAds(ctx, req.(*AdRequest)) } return interceptor(ctx, in, info, handler) } var _AdService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.AdService", HandlerType: (*AdServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "GetAds", Handler: _AdService_GetAds_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } func init() { proto.RegisterFile("demo.proto", fileDescriptor_ca53982754088a9d) } var fileDescriptor_ca53982754088a9d = []byte{ // 1500 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xef, 0x72, 0x13, 0xb7, 0x16, 0xcf, 0x26, 0xb1, 0x1d, 0x1f, 0xc7, 0x4e, 0xa2, 0x9b, 0x04, 0xb3, 0x81, 0x10, 0x94, 0x81, 0x0b, 0x17, 0x08, 0x4c, 0xee, 0x9d, 0xe1, 0x03, 0xdc, 0xd2, 0x8c, 0xc9, 0x18, 0x4f, 0xa1, 0xd0, 0x0d, 0xe9, 0xd0, 0xa1, 0x53, 0xcf, 0xb2, 0x12, 0xf1, 0x96, 0xec, 0x6a, 0x91, 0xb4, 0x19, 0xcc, 0xc7, 0xf6, 0x01, 0xfa, 0x1e, 0x7d, 0x81, 0xce, 0xf4, 0x11, 0xfa, 0xbd, 0xaf, 0xd0, 0xe7, 0xe8, 0x48, 0xbb, 0xda, 0x7f, 0xb1, 0x13, 0xf8, 0xd2, 0x6f, 0xab, 0xa3, 0x9f, 0xce, 0xf9, 0xe9, 0xe8, 0xfc, 0xb3, 0x01, 0x08, 0x0d, 0xd8, 0x4e, 0xc4, 0x99, 0x64, 0xa8, 0x35, 0xf2, 0x23, 0x21, 0x29, 0x17, 0x23, 0x16, 0xe1, 0x7d, 0x58, 0xe8, 0xb9, 0x5c, 0x0e, 0x24, 0x0d, 0xd0, 0x65, 0x80, 0x88, 0x33, 0x12, 0x7b, 0x72, 0xe8, 0x93, 0xae, 0xb5, 0x65, 0xdd, 0x68, 0x3a, 0xcd, 0x54, 0x32, 0x20, 0xc8, 0x86, 0x85, 0xf7, 0xb1, 0x1b, 0x4a, 0x5f, 0x8e, 0xbb, 0xb3, 0x5b, 0xd6, 0x8d, 0x9a, 0x93, 0xad, 0xf1, 0x4b, 0xe8, 0xec, 0x11, 0xa2, 0xb4, 0x38, 0xf4, 0x7d, 0x4c, 0x85, 0x44, 0x17, 0xa0, 0x11, 0x0b, 0xca, 0x73, 0x4d, 0x75, 0xb5, 0x1c, 0x10, 0x74, 0x13, 0xe6, 0x7d, 0x49, 0x03, 0xad, 0xa2, 0xb5, 0xbb, 0xb6, 0x53, 0x60, 0xb3, 0x63, 0xa8, 0x38, 0x1a, 0x82, 0x6f, 0xc1, 0xf2, 0x7e, 0x10, 0xc9, 0xb1, 0x12, 0x9f, 0xa7, 0x17, 0xdf, 0x84, 0x4e, 0x9f, 0xca, 0x4f, 0x82, 0x3e, 0x85, 0x79, 0x85, 0x9b, 0xce, 0xf1, 0x16, 0xd4, 0x14, 0x01, 0xd1, 0x9d, 0xdd, 0x9a, 0x9b, 0x4e, 0x32, 0xc1, 0xe0, 0x06, 0xd4, 0x34, 0x4b, 0xfc, 0x2d, 0xd8, 0x4f, 0x7d, 0x21, 0x1d, 0xea, 0xb1, 0x20, 0xa0, 0x21, 0x71, 0xa5, 0xcf, 0x42, 0x71, 0xae, 0x43, 0xae, 0x40, 0x2b, 0x77, 0x7b, 0x62, 0xb2, 0xe9, 0x40, 0xe6, 0x77, 0x81, 0xbf, 0x80, 0x8d, 0x89, 0x7a, 0x45, 0xc4, 0x42, 0x41, 0xab, 0xe7, 0xad, 0x53, 0xe7, 0x7f, 0xb7, 0xa0, 0xf1, 0x22, 0x59, 0xa2, 0x0e, 0xcc, 0x66, 0x04, 0x66, 0x7d, 0x82, 0x10, 0xcc, 0x87, 0x6e, 0x40, 0xf5, 0x6b, 0x34, 0x1d, 0xfd, 0x8d, 0xb6, 0xa0, 0x45, 0xa8, 0xf0, 0xb8, 0x1f, 0x29, 0x43, 0xdd, 0x39, 0xbd, 0x55, 0x14, 0xa1, 0x2e, 0x34, 0x22, 0xdf, 0x93, 0x31, 0xa7, 0xdd, 0x79, 0xbd, 0x6b, 0x96, 0xe8, 0x2e, 0x34, 0x23, 0xee, 0x7b, 0x74, 0x18, 0x0b, 0xd2, 0xad, 0xe9, 0x27, 0x46, 0x25, 0xef, 0x3d, 0x63, 0x21, 0x1d, 0x3b, 0x0b, 0x1a, 0x74, 0x28, 0x08, 0xda, 0x04, 0xf0, 0x5c, 0x49, 0x8f, 0x18, 0xf7, 0xa9, 0xe8, 0xd6, 0x13, 0xf2, 0xb9, 0x04, 0x3f, 0x81, 0x55, 0x75, 0xf9, 0x94, 0x7f, 0x7e, 0xeb, 0x7b, 0xb0, 0x90, 0x5e, 0x31, 0xb9, 0x72, 0x6b, 0x77, 0xb5, 0x64, 0x27, 0x3d, 0xe0, 0x64, 0x28, 0xbc, 0x0d, 0x2b, 0x7d, 0x6a, 0x14, 0x99, 0x57, 0xa9, 0xf8, 0x03, 0xdf, 0x81, 0xb5, 0x03, 0xea, 0x72, 0x6f, 0x94, 0x1b, 0x4c, 0x80, 0xab, 0x50, 0x7b, 0x1f, 0x53, 0x3e, 0x4e, 0xb1, 0xc9, 0x02, 0x3f, 0x81, 0xf5, 0x2a, 0x3c, 0xe5, 0xb7, 0x03, 0x0d, 0x4e, 0x45, 0x7c, 0x7c, 0x0e, 0x3d, 0x03, 0xc2, 0x21, 0x2c, 0xf5, 0xa9, 0xfc, 0x26, 0x66, 0x92, 0x1a, 0x93, 0x3b, 0xd0, 0x70, 0x09, 0xe1, 0x54, 0x08, 0x6d, 0xb4, 0xaa, 0x62, 0x2f, 0xd9, 0x73, 0x0c, 0xe8, 0xf3, 0xa2, 0x76, 0x0f, 0x96, 0x73, 0x7b, 0x29, 0xe7, 0x3b, 0xb0, 0xe0, 0x31, 0x21, 0xf5, 0xdb, 0x59, 0x53, 0xdf, 0xae, 0xa1, 0x30, 0x87, 0x82, 0x60, 0x06, 0xcb, 0x07, 0x23, 0x3f, 0x7a, 0xce, 0x09, 0xe5, 0xff, 0x08, 0xe7, 0xff, 0xc1, 0x4a, 0xc1, 0x60, 0x1e, 0xfe, 0x92, 0xbb, 0xde, 0x3b, 0x3f, 0x3c, 0xca, 0x73, 0x0b, 0x8c, 0x68, 0x40, 0xf0, 0x2f, 0x16, 0x34, 0x52, 0xbb, 0xe8, 0x1a, 0x74, 0x84, 0xe4, 0x94, 0xca, 0x61, 0x91, 0x65, 0xd3, 0x69, 0x27, 0x52, 0x03, 0x43, 0x30, 0xef, 0x99, 0x32, 0xd7, 0x74, 0xf4, 0xb7, 0x0a, 0x00, 0x21, 0x5d, 0x49, 0xd3, 0x7c, 0x48, 0x16, 0x2a, 0x13, 0x3c, 0x16, 0x87, 0x92, 0x8f, 0x4d, 0x26, 0xa4, 0x4b, 0x74, 0x11, 0x16, 0x3e, 0xfa, 0xd1, 0xd0, 0x63, 0x84, 0xea, 0x44, 0xa8, 0x39, 0x8d, 0x8f, 0x7e, 0xd4, 0x63, 0x84, 0xe2, 0x57, 0x50, 0xd3, 0xae, 0x44, 0xdb, 0xd0, 0xf6, 0x62, 0xce, 0x69, 0xe8, 0x8d, 0x13, 0x60, 0xc2, 0x66, 0xd1, 0x08, 0x15, 0x5a, 0x19, 0x8e, 0x43, 0x5f, 0x0a, 0xcd, 0x66, 0xce, 0x49, 0x16, 0x4a, 0x1a, 0xba, 0x21, 0x13, 0x9a, 0x4e, 0xcd, 0x49, 0x16, 0xb8, 0x0f, 0x9b, 0x7d, 0x2a, 0x0f, 0xe2, 0x28, 0x62, 0x5c, 0x52, 0xd2, 0x4b, 0xf4, 0xf8, 0x34, 0x8f, 0xcb, 0x6b, 0xd0, 0x29, 0x99, 0x34, 0x05, 0xa3, 0x5d, 0xb4, 0x29, 0xf0, 0xf7, 0x70, 0xb1, 0x97, 0x09, 0xc2, 0x13, 0xca, 0x85, 0xcf, 0x42, 0xf3, 0xc8, 0xd7, 0x61, 0xfe, 0x2d, 0x67, 0xc1, 0x19, 0x31, 0xa2, 0xf7, 0x55, 0xc9, 0x93, 0x2c, 0xb9, 0x58, 0xe2, 0xc9, 0xba, 0x64, 0xda, 0x01, 0x7f, 0x59, 0xd0, 0xe9, 0x71, 0x4a, 0x7c, 0x55, 0xaf, 0xc9, 0x20, 0x7c, 0xcb, 0xd0, 0x6d, 0x40, 0x9e, 0x96, 0x0c, 0x3d, 0x97, 0x93, 0x61, 0x18, 0x07, 0x6f, 0x28, 0x4f, 0xfd, 0xb1, 0xec, 0x65, 0xd8, 0xaf, 0xb5, 0x1c, 0x5d, 0x87, 0xa5, 0x22, 0xda, 0x3b, 0x39, 0x49, 0x5b, 0x52, 0x3b, 0x87, 0xf6, 0x4e, 0x4e, 0xd0, 0xff, 0x61, 0xa3, 0x88, 0xa3, 0x1f, 0x22, 0x9f, 0xeb, 0xf2, 0x39, 0x1c, 0x53, 0x97, 0xa7, 0xbe, 0xeb, 0xe6, 0x67, 0xf6, 0x33, 0xc0, 0x77, 0xd4, 0xe5, 0xe8, 0x11, 0x5c, 0x9a, 0x72, 0x3c, 0x60, 0xa1, 0x1c, 0xe9, 0x27, 0xaf, 0x39, 0x17, 0x27, 0x9d, 0x7f, 0xa6, 0x00, 0x78, 0x0c, 0xed, 0xde, 0xc8, 0xe5, 0x47, 0x59, 0x4e, 0xff, 0x07, 0xea, 0x6e, 0xa0, 0x22, 0xe4, 0x0c, 0xe7, 0xa5, 0x08, 0xf4, 0x10, 0x5a, 0x05, 0xeb, 0x69, 0xc3, 0xdc, 0x28, 0x67, 0x48, 0xc9, 0x89, 0x0e, 0xe4, 0x4c, 0xf0, 0x7d, 0xe8, 0x18, 0xd3, 0xf9, 0xd3, 0x4b, 0xee, 0x86, 0xc2, 0xf5, 0xf4, 0x15, 0xb2, 0x64, 0x69, 0x17, 0xa4, 0x03, 0x82, 0x7f, 0x80, 0xa6, 0xce, 0x30, 0x3d, 0x13, 0x98, 0x6e, 0x6d, 0x9d, 0xdb, 0xad, 0x55, 0x54, 0xa8, 0xca, 0x90, 0xf2, 0x9c, 0x18, 0x15, 0x6a, 0x1f, 0xff, 0x34, 0x0b, 0x2d, 0x93, 0xc2, 0xf1, 0xb1, 0x54, 0x89, 0xc2, 0xd4, 0x32, 0x27, 0xd4, 0xd0, 0xeb, 0x01, 0x41, 0xf7, 0x60, 0x55, 0x8c, 0xfc, 0x28, 0x52, 0xb9, 0x5d, 0x4c, 0xf2, 0x24, 0x9a, 0x90, 0xd9, 0x7b, 0x99, 0x25, 0x3b, 0xba, 0x0f, 0xed, 0xec, 0x84, 0x66, 0x33, 0x37, 0x95, 0xcd, 0xa2, 0x01, 0xf6, 0x98, 0x90, 0xe8, 0x11, 0x2c, 0x67, 0x07, 0x4d, 0x6d, 0x98, 0x3f, 0xa3, 0x82, 0x2d, 0x19, 0xb4, 0xa9, 0x19, 0xb7, 0x4d, 0x25, 0xab, 0xe9, 0x4a, 0xb6, 0x5e, 0x3a, 0x95, 0x39, 0xd4, 0x94, 0x32, 0x02, 0x97, 0x0e, 0x68, 0x48, 0xb4, 0xbc, 0xc7, 0xc2, 0xb7, 0x3e, 0x0f, 0x74, 0xd8, 0x14, 0xda, 0x0d, 0x0d, 0x5c, 0xff, 0xd8, 0xb4, 0x1b, 0xbd, 0x40, 0x3b, 0x50, 0xd3, 0xae, 0x49, 0x7d, 0xdc, 0x3d, 0x6d, 0x23, 0xf1, 0xa9, 0x93, 0xc0, 0xf0, 0x9f, 0x16, 0xac, 0xbc, 0x38, 0x76, 0x3d, 0x5a, 0xaa, 0xd1, 0x53, 0x27, 0x91, 0x6d, 0x68, 0xeb, 0x0d, 0x53, 0x0a, 0x52, 0x3f, 0x2f, 0x2a, 0xa1, 0xa9, 0x06, 0xc5, 0x0a, 0x3f, 0xf7, 0x29, 0x15, 0x3e, 0xbb, 0x49, 0xad, 0x78, 0x93, 0x4a, 0x6c, 0xd7, 0x3f, 0x2f, 0xb6, 0x1f, 0x03, 0x2a, 0x5e, 0x2b, 0x6b, 0xb9, 0xa9, 0x77, 0xac, 0x4f, 0xf3, 0xce, 0x0e, 0x34, 0xf7, 0x88, 0x71, 0xca, 0x55, 0x58, 0xf4, 0x58, 0x28, 0xe9, 0x07, 0x39, 0x7c, 0x47, 0xc7, 0xa6, 0x2a, 0xb6, 0x52, 0xd9, 0x57, 0x74, 0x2c, 0xf0, 0x5d, 0x00, 0x85, 0x4f, 0xad, 0x5d, 0x85, 0x39, 0x97, 0x98, 0xe6, 0xbe, 0x54, 0xf1, 0x81, 0xa3, 0xf6, 0xf0, 0x03, 0x98, 0xdd, 0x23, 0x4a, 0xb3, 0x62, 0xce, 0xa9, 0x27, 0x87, 0x31, 0x37, 0x2f, 0xda, 0x32, 0xb2, 0x43, 0x7e, 0xac, 0xfa, 0x8d, 0xb2, 0x62, 0xfa, 0x8d, 0xfa, 0xde, 0xfd, 0xc3, 0x82, 0x96, 0xca, 0xb0, 0x03, 0xca, 0x4f, 0x7c, 0x8f, 0xa2, 0x87, 0xba, 0x8b, 0xe9, 0xa4, 0xdc, 0xa8, 0x7a, 0xbc, 0x30, 0x78, 0xdb, 0xe5, 0x50, 0x4f, 0x26, 0xd3, 0x19, 0xf4, 0x00, 0x1a, 0xe9, 0x74, 0x5c, 0x39, 0x5d, 0x9e, 0x99, 0xed, 0x95, 0x53, 0x19, 0x8e, 0x67, 0xd0, 0x97, 0xd0, 0xcc, 0xe6, 0x70, 0x74, 0xf9, 0xb4, 0xfe, 0xa2, 0x82, 0x89, 0xe6, 0x77, 0x7f, 0xb6, 0x60, 0xad, 0x3c, 0xbf, 0x9a, 0x6b, 0xfd, 0x08, 0xff, 0x9a, 0x30, 0xdc, 0xa2, 0x7f, 0x97, 0xd4, 0x4c, 0x1f, 0xab, 0xed, 0x1b, 0xe7, 0x03, 0x93, 0x07, 0x53, 0x2c, 0x66, 0x61, 0x2d, 0x1d, 0xbc, 0x7a, 0xae, 0x74, 0x8f, 0xd9, 0x91, 0x61, 0xd1, 0x87, 0xc5, 0xe2, 0x94, 0x89, 0x26, 0xdc, 0xc2, 0xbe, 0x7a, 0xca, 0x52, 0x75, 0xe8, 0xc3, 0x33, 0xe8, 0x31, 0x40, 0x3e, 0x64, 0xa2, 0xcd, 0xaa, 0xab, 0xcb, 0xd3, 0xa7, 0x3d, 0x71, 0x26, 0xc4, 0x33, 0xe8, 0x35, 0x74, 0xca, 0x63, 0x25, 0xc2, 0x25, 0xe4, 0xc4, 0x11, 0xd5, 0xde, 0x3e, 0x13, 0x93, 0x79, 0xe1, 0x57, 0x0b, 0x96, 0x0e, 0xd2, 0xe2, 0x65, 0xee, 0x3f, 0x80, 0x05, 0x33, 0x0d, 0xa2, 0x4b, 0x55, 0xd2, 0xc5, 0xa1, 0xd4, 0xbe, 0x3c, 0x65, 0x37, 0xf3, 0xc0, 0x53, 0x68, 0x66, 0x43, 0x5a, 0x25, 0x58, 0xaa, 0xd3, 0xa2, 0xbd, 0x39, 0x6d, 0x3b, 0x23, 0xfb, 0x9b, 0x05, 0x4b, 0xa6, 0xf4, 0x18, 0xb2, 0xaf, 0x61, 0x7d, 0xf2, 0x90, 0x33, 0xf1, 0xd9, 0x6e, 0x55, 0x09, 0x9f, 0x31, 0x1d, 0xe1, 0x19, 0xd4, 0x87, 0x46, 0x32, 0xf0, 0x48, 0x74, 0xbd, 0x9c, 0x0b, 0xd3, 0xc6, 0x21, 0x7b, 0x42, 0x73, 0xc1, 0x33, 0xbb, 0x87, 0xd0, 0x79, 0xe1, 0x8e, 0x03, 0x1a, 0x66, 0x19, 0xdc, 0x83, 0x7a, 0xd2, 0x91, 0x91, 0x5d, 0xd6, 0x5c, 0x9c, 0x10, 0xec, 0x8d, 0x89, 0x7b, 0x99, 0x43, 0x46, 0xb0, 0xb8, 0xaf, 0x2a, 0xa8, 0x51, 0xfa, 0x4a, 0xfd, 0x60, 0x99, 0xd0, 0x48, 0xd0, 0xcd, 0x4a, 0x34, 0x4c, 0x6f, 0x36, 0x53, 0x72, 0xf6, 0x0d, 0x2c, 0xf5, 0x46, 0xd4, 0x7b, 0xc7, 0xe2, 0xec, 0x06, 0xcf, 0x01, 0xf2, 0xba, 0x5b, 0x89, 0xee, 0x53, 0x7d, 0xc6, 0xbe, 0x32, 0x75, 0x3f, 0xbb, 0xcd, 0x13, 0x55, 0x82, 0x8d, 0xf6, 0x07, 0x50, 0xef, 0xab, 0x19, 0x5c, 0xa0, 0xf5, 0x6a, 0x39, 0x4d, 0x35, 0x5e, 0x38, 0x25, 0x37, 0x9a, 0xde, 0xd4, 0xf5, 0x9f, 0x1b, 0xff, 0xfd, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xb2, 0xa0, 0x6e, 0x6c, 0xea, 0x10, 0x00, 0x00, } ================================================ FILE: microservices-demo/src/checkoutservice/genproto.sh ================================================ #!/bin/bash -eu # # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # [START gke_checkoutservice_genproto] PATH=$PATH:$GOPATH/bin protodir=../../pb protoc --go_out=plugins=grpc:genproto -I $protodir $protodir/demo.proto # [END gke_checkoutservice_genproto] ================================================ FILE: microservices-demo/src/checkoutservice/go.mod ================================================ module github.com/GoogleCloudPlatform/microservices-demo/src/checkoutservice go 1.18 require ( cloud.google.com/go/profiler v0.3.0 contrib.go.opencensus.io/exporter/jaeger v0.2.1 contrib.go.opencensus.io/exporter/stackdriver v0.13.12 github.com/golang/protobuf v1.5.2 github.com/google/uuid v1.3.0 github.com/sirupsen/logrus v1.8.1 go.opencensus.io v0.23.0 golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b google.golang.org/grpc v1.48.0 ) require ( cloud.google.com/go v0.100.2 // indirect cloud.google.com/go/compute v1.6.1 // indirect cloud.google.com/go/monitoring v1.1.0 // indirect cloud.google.com/go/trace v1.0.0 // indirect github.com/aws/aws-sdk-go v1.43.31 // indirect github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 // indirect github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 // indirect github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 // indirect github.com/envoyproxy/protoc-gen-validate v0.1.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/go-cmp v0.5.8 // indirect github.com/google/pprof v0.0.0-20220412212628-83db2b799d1f // indirect github.com/googleapis/gax-go/v2 v2.4.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/prometheus/prometheus v2.5.0+incompatible // indirect github.com/uber/jaeger-client-go v2.25.0+incompatible // indirect golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect golang.org/x/text v0.3.7 // indirect google.golang.org/api v0.78.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335 // indirect google.golang.org/protobuf v1.28.0 // indirect ) ================================================ FILE: microservices-demo/src/checkoutservice/go.sum ================================================ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go v0.99.0 h1:y/cM2iqGgGi5D5DQZl6D9STN/3dR/Vx5Mp8s752oJTY= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= cloud.google.com/go/compute v1.5.0 h1:b1zWmYuuHz7gO9kDcM/EpHGr06UgsYNRpNJzI2kFiLM= cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= cloud.google.com/go/compute v1.6.1 h1:2sMmt8prCn7DPaG4Pmh0N3Inmc8cT8ae5k1M6VJ9Wqc= cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/monitoring v1.1.0 h1:ZnyNdf/XRcynMmKzRSNTOdOyYPs6G7do1l2D2hIvIKo= cloud.google.com/go/monitoring v1.1.0/go.mod h1:L81pzz7HKn14QCMaCs6NTQkdBnE87TElyanS95vIcl4= cloud.google.com/go/profiler v0.1.1 h1:seMHZtcgOwZXAOKDZuW2sN3u1yKjYG19dUkElb4mbcQ= cloud.google.com/go/profiler v0.1.1/go.mod h1:zG22vSCuJKJMvIlLpX3FhNjOsifaoLdPAYc4yLw5Iw4= cloud.google.com/go/profiler v0.3.0 h1:R6y/xAeifaUXxd2x6w+jIwKxoKl8Cv5HJvcvASTPWJo= cloud.google.com/go/profiler v0.3.0/go.mod h1:9wYk9eY4iZHsev8TQb61kh3wiOiSyz/xOYixWPzweCU= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= cloud.google.com/go/trace v1.0.0 h1:laKx2y7IWMjguCe5zZx6n7qLtREk4kyE69SXVC0VSN8= cloud.google.com/go/trace v1.0.0/go.mod h1:4iErSByzxkyHWzzlAj63/Gmjz0NH1ASqhJguHpGcr6A= contrib.go.opencensus.io/exporter/jaeger v0.2.1 h1:yGBYzYMewVL0yO9qqJv3Z5+IRhPdU7e9o/2oKpX4YvI= contrib.go.opencensus.io/exporter/jaeger v0.2.1/go.mod h1:Y8IsLgdxqh1QxYxPC5IgXVmBaeLUeQFfBeBi9PbeZd0= contrib.go.opencensus.io/exporter/stackdriver v0.13.10 h1:a9+GZPUe+ONKUwULjlEOucMMG0qfSCCenlji0Nhqbys= contrib.go.opencensus.io/exporter/stackdriver v0.13.10/go.mod h1:I5htMbyta491eUxufwwZPQdcKvvgzMB4O9ni41YnIM8= contrib.go.opencensus.io/exporter/stackdriver v0.13.12 h1:bjBKzIf7/TAkxd7L2utGaLM78bmUWlCval5K9UeElbY= contrib.go.opencensus.io/exporter/stackdriver v0.13.12/go.mod h1:mmxnWlrvrFdpiOHOhxBaVi1rkc0WOqhgfknj4Yg0SeQ= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/aws/aws-sdk-go v1.37.0 h1:GzFnhOIsrGyQ69s7VgqtrG2BG8v7X7vwB3Xpbd/DBBk= github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.43.31 h1:yJZIr8nMV1hXjAvvOLUFqZRJcHV7udPQBfhJqawDzI0= github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403 h1:cqQfy1jclcSy/FwLjemeg3SR1yaINm74aQyupQ0Bl8M= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed h1:OZmjad4L3H8ncOIR8rnb5MREYqG8ixi5+WbeUsquF0c= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0 h1:dulLQAYQFYtG5MTplgNGHWuV2D+OBD+Z8lmDBmbLg+s= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 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.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= 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/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20211008130755-947d60d73cc0 h1:zHs+jv3LO743/zFGcByu2KmpbliCU2AhjcGgrdTwSG4= github.com/google/pprof v0.0.0-20211008130755-947d60d73cc0/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= github.com/google/pprof v0.0.0-20220412212628-83db2b799d1f h1:VrKTY4lquiy1oJzVZgXrauku9Jx9P+POv/gTLakG4Wk= github.com/google/pprof v0.0.0-20220412212628-83db2b799d1f/go.mod h1:Pt31oes+eGImORns3McJn8zHefuQl2rG8l6xQjGYB4U= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= github.com/googleapis/gax-go/v2 v2.2.0 h1:s7jOdKSaksJVOxE0Y/S32otcfiP+UQ0cL8/GTKaONwE= github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= github.com/googleapis/gax-go/v2 v2.4.0 h1:dS9eYAjhrE2RjmzYw2XAPvcXfmcQLtFEQWn0CR82awk= github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/prometheus v2.5.0+incompatible h1:7QPitgO2kOFG8ecuRn9O/4L9+10He72rVRJvMXrE9Hg= github.com/prometheus/prometheus v2.5.0+incompatible/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/uber/jaeger-client-go v2.25.0+incompatible h1:IxcNZ7WRY1Y3G4poYlx24szfsn/3LvK9QHCq9oQw8+U= github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 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.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220403103023-749bd193bc2b h1:vI32FkLJNAWtGD4BwkThwEy6XS7ZLLMHkSkYfF8M0W0= golang.org/x/net v0.0.0-20220403103023-749bd193bc2b/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220420153159-1850ba15e1be h1:yx80W7nvY5ySWpaU8UWaj5o9e23YgO9BRhQol7Lc+JI= golang.org/x/net v0.0.0-20220420153159-1850ba15e1be/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b h1:3ogNYyK4oIQdIKzTu68hQrr4iuVxF3AxKl9Aj/eDrw0= golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220805013720-a33c5aa5df48 h1:N9Vc/rorQUDes6B9CNdIxAn5jODGj2wzfrei2x4wNj4= golang.org/x/net v0.0.0-20220805013720-a33c5aa5df48/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220809012201-f428fae20770 h1:dIi4qVdvjZEjiMDv7vhokAZNGnz3kepwuXqFKYDdDMs= golang.org/x/net v0.0.0-20220809012201-f428fae20770/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220809184613-07c6da5e1ced h1:3dYNDff0VT5xj+mbj2XucFst9WKk6PdGOrb9n+SbIvw= golang.org/x/net v0.0.0-20220809184613-07c6da5e1ced/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E= golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/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-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886 h1:eJv7u3ksNXoLbGSKuv2s/SIO4tJVxc/A+MTpzxDgz/Q= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba h1:AyHWHCBVlIYI5rgEM3o+1PLd0sLPcIAoaUckGQMaWtw= golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E= google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= google.golang.org/api v0.61.0 h1:TXXKS1slM3b2bZNJwD5DV/Tp6/M2cLzLOLh9PjDhrw8= google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= google.golang.org/api v0.74.0 h1:ExR2D+5TYIrMphWgs5JCgwRhEDlPDXXrLwHHMgPHTXE= google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= google.golang.org/api v0.78.0 h1:5ewPyCwP43C3i8B6C2Kb+eVAevbnke2xR8VbcSWjS4I= google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210921142501-181ce0d877f6/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211018162055-cf77aa76bad2/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0 h1:c7yRRmuQiVMo+YppNj5MUREXUyc2lPo3DrtYMwaWQ28= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb h1:0m9wktIpOxGw+SSKmydXWB3Z3GTfcPP6+q75HCQa6HI= google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335 h1:2D0OT6tPVdrQTOnVe1VQjfJPTED6EZ7fdJ/f6Db6OsY= google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.46.0 h1:oCjezcn6g6A75TGoKYBPgKmVBLexhYLM6MebdrPApP8= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= ================================================ FILE: microservices-demo/src/checkoutservice/main.go ================================================ // Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "context" "fmt" "net" "os" "time" "cloud.google.com/go/profiler" "contrib.go.opencensus.io/exporter/jaeger" "contrib.go.opencensus.io/exporter/stackdriver" "github.com/google/uuid" "github.com/sirupsen/logrus" "go.opencensus.io/plugin/ocgrpc" "go.opencensus.io/stats/view" "go.opencensus.io/trace" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" pb "github.com/GoogleCloudPlatform/microservices-demo/src/checkoutservice/genproto" money "github.com/GoogleCloudPlatform/microservices-demo/src/checkoutservice/money" healthpb "google.golang.org/grpc/health/grpc_health_v1" ) const ( listenPort = "5050" usdCurrency = "USD" ) var log *logrus.Logger func init() { log = logrus.New() log.Level = logrus.DebugLevel log.Formatter = &logrus.JSONFormatter{ FieldMap: logrus.FieldMap{ logrus.FieldKeyTime: "timestamp", logrus.FieldKeyLevel: "severity", logrus.FieldKeyMsg: "message", }, TimestampFormat: time.RFC3339Nano, } log.Out = os.Stdout } type checkoutService struct { productCatalogSvcAddr string cartSvcAddr string currencySvcAddr string shippingSvcAddr string emailSvcAddr string paymentSvcAddr string } func main() { if os.Getenv("DISABLE_TRACING") == "" { log.Info("Tracing enabled.") go initTracing() } else { log.Info("Tracing disabled.") } if os.Getenv("DISABLE_PROFILER") == "" { log.Info("Profiling enabled.") go initProfiling("checkoutservice", "1.0.0") } else { log.Info("Profiling disabled.") } port := listenPort if os.Getenv("PORT") != "" { port = os.Getenv("PORT") } svc := new(checkoutService) mustMapEnv(&svc.shippingSvcAddr, "SHIPPING_SERVICE_ADDR") mustMapEnv(&svc.productCatalogSvcAddr, "PRODUCT_CATALOG_SERVICE_ADDR") mustMapEnv(&svc.cartSvcAddr, "CART_SERVICE_ADDR") mustMapEnv(&svc.currencySvcAddr, "CURRENCY_SERVICE_ADDR") mustMapEnv(&svc.emailSvcAddr, "EMAIL_SERVICE_ADDR") mustMapEnv(&svc.paymentSvcAddr, "PAYMENT_SERVICE_ADDR") log.Infof("service config: %+v", svc) lis, err := net.Listen("tcp", fmt.Sprintf(":%s", port)) if err != nil { log.Fatal(err) } var srv *grpc.Server if os.Getenv("DISABLE_STATS") == "" { log.Info("Stats enabled.") srv = grpc.NewServer(grpc.StatsHandler(&ocgrpc.ServerHandler{})) } else { log.Info("Stats disabled.") srv = grpc.NewServer() } pb.RegisterCheckoutServiceServer(srv, svc) healthpb.RegisterHealthServer(srv, svc) log.Infof("starting to listen on tcp: %q", lis.Addr().String()) err = srv.Serve(lis) log.Fatal(err) } func initJaegerTracing() { svcAddr := os.Getenv("JAEGER_SERVICE_ADDR") if svcAddr == "" { log.Info("jaeger initialization disabled.") return } // Register the Jaeger exporter to be able to retrieve // the collected spans. exporter, err := jaeger.NewExporter(jaeger.Options{ Endpoint: fmt.Sprintf("http://%s", svcAddr), Process: jaeger.Process{ ServiceName: "checkoutservice", }, }) if err != nil { log.Fatal(err) } trace.RegisterExporter(exporter) log.Info("jaeger initialization completed.") } func initStats(exporter *stackdriver.Exporter) { view.SetReportingPeriod(60 * time.Second) view.RegisterExporter(exporter) if err := view.Register(ocgrpc.DefaultServerViews...); err != nil { log.Warn("Error registering default server views") } else { log.Info("Registered default server views") } } func initStackdriverTracing() { // TODO(ahmetb) this method is duplicated in other microservices using Go // since they are not sharing packages. for i := 1; i <= 3; i++ { exporter, err := stackdriver.NewExporter(stackdriver.Options{}) if err != nil { log.Infof("failed to initialize stackdriver exporter: %+v", err) } else { trace.RegisterExporter(exporter) log.Info("registered Stackdriver tracing") // Register the views to collect server stats. initStats(exporter) return } d := time.Second * 10 * time.Duration(i) log.Infof("sleeping %v to retry initializing Stackdriver exporter", d) time.Sleep(d) } log.Warn("could not initialize Stackdriver exporter after retrying, giving up") } func initTracing() { initJaegerTracing() initStackdriverTracing() } func initProfiling(service, version string) { // TODO(ahmetb) this method is duplicated in other microservices using Go // since they are not sharing packages. for i := 1; i <= 3; i++ { if err := profiler.Start(profiler.Config{ Service: service, ServiceVersion: version, // ProjectID must be set if not running on GCP. // ProjectID: "my-project", }); err != nil { log.Warnf("failed to start profiler: %+v", err) } else { log.Info("started Stackdriver profiler") return } d := time.Second * 10 * time.Duration(i) log.Infof("sleeping %v to retry initializing Stackdriver profiler", d) time.Sleep(d) } log.Warn("could not initialize Stackdriver profiler after retrying, giving up") } func mustMapEnv(target *string, envKey string) { v := os.Getenv(envKey) if v == "" { panic(fmt.Sprintf("environment variable %q not set", envKey)) } *target = v } func (cs *checkoutService) Check(ctx context.Context, req *healthpb.HealthCheckRequest) (*healthpb.HealthCheckResponse, error) { return &healthpb.HealthCheckResponse{Status: healthpb.HealthCheckResponse_SERVING}, nil } func (cs *checkoutService) Watch(req *healthpb.HealthCheckRequest, ws healthpb.Health_WatchServer) error { return status.Errorf(codes.Unimplemented, "health check via Watch not implemented") } func (cs *checkoutService) PlaceOrder(ctx context.Context, req *pb.PlaceOrderRequest) (*pb.PlaceOrderResponse, error) { log.Infof("[PlaceOrder] user_id=%q user_currency=%q", req.UserId, req.UserCurrency) orderID, err := uuid.NewUUID() if err != nil { return nil, status.Errorf(codes.Internal, "failed to generate order uuid") } prep, err := cs.prepareOrderItemsAndShippingQuoteFromCart(ctx, req.UserId, req.UserCurrency, req.Address) if err != nil { return nil, status.Errorf(codes.Internal, err.Error()) } total := pb.Money{CurrencyCode: req.UserCurrency, Units: 0, Nanos: 0} total = money.Must(money.Sum(total, *prep.shippingCostLocalized)) for _, it := range prep.orderItems { multPrice := money.MultiplySlow(*it.Cost, uint32(it.GetItem().GetQuantity())) total = money.Must(money.Sum(total, multPrice)) } txID, err := cs.chargeCard(ctx, &total, req.CreditCard) if err != nil { return nil, status.Errorf(codes.Internal, "failed to charge card: %+v", err) } log.Infof("payment went through (transaction_id: %s)", txID) shippingTrackingID, err := cs.shipOrder(ctx, req.Address, prep.cartItems) if err != nil { return nil, status.Errorf(codes.Unavailable, "shipping error: %+v", err) } _ = cs.emptyUserCart(ctx, req.UserId) orderResult := &pb.OrderResult{ OrderId: orderID.String(), ShippingTrackingId: shippingTrackingID, ShippingCost: prep.shippingCostLocalized, ShippingAddress: req.Address, Items: prep.orderItems, } if err := cs.sendOrderConfirmation(ctx, req.Email, orderResult); err != nil { log.Warnf("failed to send order confirmation to %q: %+v", req.Email, err) } else { log.Infof("order confirmation email sent to %q", req.Email) } resp := &pb.PlaceOrderResponse{Order: orderResult} return resp, nil } type orderPrep struct { orderItems []*pb.OrderItem cartItems []*pb.CartItem shippingCostLocalized *pb.Money } func (cs *checkoutService) prepareOrderItemsAndShippingQuoteFromCart(ctx context.Context, userID, userCurrency string, address *pb.Address) (orderPrep, error) { var out orderPrep cartItems, err := cs.getUserCart(ctx, userID) if err != nil { return out, fmt.Errorf("cart failure: %+v", err) } orderItems, err := cs.prepOrderItems(ctx, cartItems, userCurrency) if err != nil { return out, fmt.Errorf("failed to prepare order: %+v", err) } shippingUSD, err := cs.quoteShipping(ctx, address, cartItems) if err != nil { return out, fmt.Errorf("shipping quote failure: %+v", err) } shippingPrice, err := cs.convertCurrency(ctx, shippingUSD, userCurrency) if err != nil { return out, fmt.Errorf("failed to convert shipping cost to currency: %+v", err) } out.shippingCostLocalized = shippingPrice out.cartItems = cartItems out.orderItems = orderItems return out, nil } func (cs *checkoutService) quoteShipping(ctx context.Context, address *pb.Address, items []*pb.CartItem) (*pb.Money, error) { conn, err := grpc.DialContext(ctx, cs.shippingSvcAddr, grpc.WithInsecure(), grpc.WithStatsHandler(&ocgrpc.ClientHandler{})) if err != nil { return nil, fmt.Errorf("could not connect shipping service: %+v", err) } defer conn.Close() shippingQuote, err := pb.NewShippingServiceClient(conn). GetQuote(ctx, &pb.GetQuoteRequest{ Address: address, Items: items}) if err != nil { return nil, fmt.Errorf("failed to get shipping quote: %+v", err) } return shippingQuote.GetCostUsd(), nil } func (cs *checkoutService) getUserCart(ctx context.Context, userID string) ([]*pb.CartItem, error) { conn, err := grpc.DialContext(ctx, cs.cartSvcAddr, grpc.WithInsecure(), grpc.WithStatsHandler(&ocgrpc.ClientHandler{})) if err != nil { return nil, fmt.Errorf("could not connect cart service: %+v", err) } defer conn.Close() cart, err := pb.NewCartServiceClient(conn).GetCart(ctx, &pb.GetCartRequest{UserId: userID}) if err != nil { return nil, fmt.Errorf("failed to get user cart during checkout: %+v", err) } return cart.GetItems(), nil } func (cs *checkoutService) emptyUserCart(ctx context.Context, userID string) error { conn, err := grpc.DialContext(ctx, cs.cartSvcAddr, grpc.WithInsecure(), grpc.WithStatsHandler(&ocgrpc.ClientHandler{})) if err != nil { return fmt.Errorf("could not connect cart service: %+v", err) } defer conn.Close() if _, err = pb.NewCartServiceClient(conn).EmptyCart(ctx, &pb.EmptyCartRequest{UserId: userID}); err != nil { return fmt.Errorf("failed to empty user cart during checkout: %+v", err) } return nil } func (cs *checkoutService) prepOrderItems(ctx context.Context, items []*pb.CartItem, userCurrency string) ([]*pb.OrderItem, error) { out := make([]*pb.OrderItem, len(items)) conn, err := grpc.DialContext(ctx, cs.productCatalogSvcAddr, grpc.WithInsecure(), grpc.WithStatsHandler(&ocgrpc.ClientHandler{})) if err != nil { return nil, fmt.Errorf("could not connect product catalog service: %+v", err) } defer conn.Close() cl := pb.NewProductCatalogServiceClient(conn) for i, item := range items { product, err := cl.GetProduct(ctx, &pb.GetProductRequest{Id: item.GetProductId()}) if err != nil { return nil, fmt.Errorf("failed to get product #%q", item.GetProductId()) } price, err := cs.convertCurrency(ctx, product.GetPriceUsd(), userCurrency) if err != nil { return nil, fmt.Errorf("failed to convert price of %q to %s", item.GetProductId(), userCurrency) } out[i] = &pb.OrderItem{ Item: item, Cost: price} } return out, nil } func (cs *checkoutService) convertCurrency(ctx context.Context, from *pb.Money, toCurrency string) (*pb.Money, error) { conn, err := grpc.DialContext(ctx, cs.currencySvcAddr, grpc.WithInsecure(), grpc.WithStatsHandler(&ocgrpc.ClientHandler{})) if err != nil { return nil, fmt.Errorf("could not connect currency service: %+v", err) } defer conn.Close() result, err := pb.NewCurrencyServiceClient(conn).Convert(context.TODO(), &pb.CurrencyConversionRequest{ From: from, ToCode: toCurrency}) if err != nil { return nil, fmt.Errorf("failed to convert currency: %+v", err) } return result, err } func (cs *checkoutService) chargeCard(ctx context.Context, amount *pb.Money, paymentInfo *pb.CreditCardInfo) (string, error) { conn, err := grpc.DialContext(ctx, cs.paymentSvcAddr, grpc.WithInsecure(), grpc.WithStatsHandler(&ocgrpc.ClientHandler{})) if err != nil { return "", fmt.Errorf("failed to connect payment service: %+v", err) } defer conn.Close() paymentResp, err := pb.NewPaymentServiceClient(conn).Charge(ctx, &pb.ChargeRequest{ Amount: amount, CreditCard: paymentInfo}) if err != nil { return "", fmt.Errorf("could not charge the card: %+v", err) } return paymentResp.GetTransactionId(), nil } func (cs *checkoutService) sendOrderConfirmation(ctx context.Context, email string, order *pb.OrderResult) error { conn, err := grpc.DialContext(ctx, cs.emailSvcAddr, grpc.WithInsecure(), grpc.WithStatsHandler(&ocgrpc.ClientHandler{})) if err != nil { return fmt.Errorf("failed to connect email service: %+v", err) } defer conn.Close() _, err = pb.NewEmailServiceClient(conn).SendOrderConfirmation(ctx, &pb.SendOrderConfirmationRequest{ Email: email, Order: order}) return err } func (cs *checkoutService) shipOrder(ctx context.Context, address *pb.Address, items []*pb.CartItem) (string, error) { conn, err := grpc.DialContext(ctx, cs.shippingSvcAddr, grpc.WithInsecure(), grpc.WithStatsHandler(&ocgrpc.ClientHandler{})) if err != nil { return "", fmt.Errorf("failed to connect email service: %+v", err) } defer conn.Close() resp, err := pb.NewShippingServiceClient(conn).ShipOrder(ctx, &pb.ShipOrderRequest{ Address: address, Items: items}) if err != nil { return "", fmt.Errorf("shipment failed: %+v", err) } return resp.GetTrackingId(), nil } // TODO: Dial and create client once, reuse. ================================================ FILE: microservices-demo/src/checkoutservice/money/money.go ================================================ // Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package money import ( "errors" pb "github.com/GoogleCloudPlatform/microservices-demo/src/checkoutservice/genproto" ) const ( nanosMin = -999999999 nanosMax = +999999999 nanosMod = 1000000000 ) var ( ErrInvalidValue = errors.New("one of the specified money values is invalid") ErrMismatchingCurrency = errors.New("mismatching currency codes") ) // IsValid checks if specified value has a valid units/nanos signs and ranges. func IsValid(m pb.Money) bool { return signMatches(m) && validNanos(m.GetNanos()) } func signMatches(m pb.Money) bool { return m.GetNanos() == 0 || m.GetUnits() == 0 || (m.GetNanos() < 0) == (m.GetUnits() < 0) } func validNanos(nanos int32) bool { return nanosMin <= nanos && nanos <= nanosMax } // IsZero returns true if the specified money value is equal to zero. func IsZero(m pb.Money) bool { return m.GetUnits() == 0 && m.GetNanos() == 0 } // IsPositive returns true if the specified money value is valid and is // positive. func IsPositive(m pb.Money) bool { return IsValid(m) && m.GetUnits() > 0 || (m.GetUnits() == 0 && m.GetNanos() > 0) } // IsNegative returns true if the specified money value is valid and is // negative. func IsNegative(m pb.Money) bool { return IsValid(m) && m.GetUnits() < 0 || (m.GetUnits() == 0 && m.GetNanos() < 0) } // AreSameCurrency returns true if values l and r have a currency code and // they are the same values. func AreSameCurrency(l, r pb.Money) bool { return l.GetCurrencyCode() == r.GetCurrencyCode() && l.GetCurrencyCode() != "" } // AreEquals returns true if values l and r are the equal, including the // currency. This does not check validity of the provided values. func AreEquals(l, r pb.Money) bool { return l.GetCurrencyCode() == r.GetCurrencyCode() && l.GetUnits() == r.GetUnits() && l.GetNanos() == r.GetNanos() } // Negate returns the same amount with the sign negated. func Negate(m pb.Money) pb.Money { return pb.Money{ Units: -m.GetUnits(), Nanos: -m.GetNanos(), CurrencyCode: m.GetCurrencyCode()} } // Must panics if the given error is not nil. This can be used with other // functions like: "m := Must(Sum(a,b))". func Must(v pb.Money, err error) pb.Money { if err != nil { panic(err) } return v } // Sum adds two values. Returns an error if one of the values are invalid or // currency codes are not matching (unless currency code is unspecified for // both). func Sum(l, r pb.Money) (pb.Money, error) { if !IsValid(l) || !IsValid(r) { return pb.Money{}, ErrInvalidValue } else if l.GetCurrencyCode() != r.GetCurrencyCode() { return pb.Money{}, ErrMismatchingCurrency } units := l.GetUnits() + r.GetUnits() nanos := l.GetNanos() + r.GetNanos() if (units == 0 && nanos == 0) || (units > 0 && nanos >= 0) || (units < 0 && nanos <= 0) { // same sign units += int64(nanos / nanosMod) nanos = nanos % nanosMod } else { // different sign. nanos guaranteed to not to go over the limit if units > 0 { units-- nanos += nanosMod } else { units++ nanos -= nanosMod } } return pb.Money{ Units: units, Nanos: nanos, CurrencyCode: l.GetCurrencyCode()}, nil } // MultiplySlow is a slow multiplication operation done through adding the value // to itself n-1 times. func MultiplySlow(m pb.Money, n uint32) pb.Money { out := m for n > 1 { out = Must(Sum(out, m)) n-- } return out } ================================================ FILE: microservices-demo/src/checkoutservice/money/money_test.go ================================================ // Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package money import ( "fmt" "reflect" "testing" pb "github.com/GoogleCloudPlatform/microservices-demo/src/checkoutservice/genproto" ) func mmc(u int64, n int32, c string) pb.Money { return pb.Money{Units: u, Nanos: n, CurrencyCode: c} } func mm(u int64, n int32) pb.Money { return mmc(u, n, "") } func TestIsValid(t *testing.T) { tests := []struct { name string in pb.Money want bool }{ {"valid -/-", mm(-981273891273, -999999999), true}, {"invalid -/+", mm(-981273891273, +999999999), false}, {"valid +/+", mm(981273891273, 999999999), true}, {"invalid +/-", mm(981273891273, -999999999), false}, {"invalid +/+overflow", mm(3, 1000000000), false}, {"invalid +/-overflow", mm(3, -1000000000), false}, {"invalid -/+overflow", mm(-3, 1000000000), false}, {"invalid -/-overflow", mm(-3, -1000000000), false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := IsValid(tt.in); got != tt.want { t.Errorf("IsValid(%v) = %v, want %v", tt.in, got, tt.want) } }) } } func TestIsZero(t *testing.T) { tests := []struct { name string in pb.Money want bool }{ {"zero", mm(0, 0), true}, {"not-zero (-/+)", mm(-1, +1), false}, {"not-zero (-/-)", mm(-1, -1), false}, {"not-zero (+/+)", mm(+1, +1), false}, {"not-zero (+/-)", mm(+1, -1), false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := IsZero(tt.in); got != tt.want { t.Errorf("IsZero(%v) = %v, want %v", tt.in, got, tt.want) } }) } } func TestIsPositive(t *testing.T) { tests := []struct { name string in pb.Money want bool }{ {"zero", mm(0, 0), false}, {"positive (+/+)", mm(+1, +1), true}, {"invalid (-/+)", mm(-1, +1), false}, {"negative (-/-)", mm(-1, -1), false}, {"invalid (+/-)", mm(+1, -1), false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := IsPositive(tt.in); got != tt.want { t.Errorf("IsPositive(%v) = %v, want %v", tt.in, got, tt.want) } }) } } func TestIsNegative(t *testing.T) { tests := []struct { name string in pb.Money want bool }{ {"zero", mm(0, 0), false}, {"positive (+/+)", mm(+1, +1), false}, {"invalid (-/+)", mm(-1, +1), false}, {"negative (-/-)", mm(-1, -1), true}, {"invalid (+/-)", mm(+1, -1), false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := IsNegative(tt.in); got != tt.want { t.Errorf("IsNegative(%v) = %v, want %v", tt.in, got, tt.want) } }) } } func TestAreSameCurrency(t *testing.T) { type args struct { l pb.Money r pb.Money } tests := []struct { name string args args want bool }{ {"both empty currency", args{mmc(1, 0, ""), mmc(2, 0, "")}, false}, {"left empty currency", args{mmc(1, 0, ""), mmc(2, 0, "USD")}, false}, {"right empty currency", args{mmc(1, 0, "USD"), mmc(2, 0, "")}, false}, {"mismatching", args{mmc(1, 0, "USD"), mmc(2, 0, "CAD")}, false}, {"matching", args{mmc(1, 0, "USD"), mmc(2, 0, "USD")}, true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := AreSameCurrency(tt.args.l, tt.args.r); got != tt.want { t.Errorf("AreSameCurrency([%v],[%v]) = %v, want %v", tt.args.l, tt.args.r, got, tt.want) } }) } } func TestAreEquals(t *testing.T) { type args struct { l pb.Money r pb.Money } tests := []struct { name string args args want bool }{ {"equals", args{mmc(1, 2, "USD"), mmc(1, 2, "USD")}, true}, {"mismatching currency", args{mmc(1, 2, "USD"), mmc(1, 2, "CAD")}, false}, {"mismatching units", args{mmc(10, 20, "USD"), mmc(1, 20, "USD")}, false}, {"mismatching nanos", args{mmc(1, 2, "USD"), mmc(1, 20, "USD")}, false}, {"negated", args{mmc(1, 2, "USD"), mmc(-1, -2, "USD")}, false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := AreEquals(tt.args.l, tt.args.r); got != tt.want { t.Errorf("AreEquals([%v],[%v]) = %v, want %v", tt.args.l, tt.args.r, got, tt.want) } }) } } func TestNegate(t *testing.T) { tests := []struct { name string in pb.Money want pb.Money }{ {"zero", mm(0, 0), mm(0, 0)}, {"negative", mm(-1, -200), mm(1, 200)}, {"positive", mm(1, 200), mm(-1, -200)}, {"carries currency code", mmc(0, 0, "XXX"), mmc(0, 0, "XXX")}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := Negate(tt.in); !AreEquals(got, tt.want) { t.Errorf("Negate([%v]) = %v, want %v", tt.in, got, tt.want) } }) } } func TestMust_pass(t *testing.T) { v := Must(mm(2, 3), nil) if !AreEquals(v, mm(2, 3)) { t.Errorf("returned the wrong value: %v", v) } } func TestMust_panic(t *testing.T) { defer func() { if r := recover(); r != nil { t.Logf("panic captured: %v", r) } }() Must(mm(2, 3), fmt.Errorf("some error")) t.Fatal("this should not have executed due to the panic above") } func TestSum(t *testing.T) { type args struct { l pb.Money r pb.Money } tests := []struct { name string args args want pb.Money wantErr error }{ {"0+0=0", args{mm(0, 0), mm(0, 0)}, mm(0, 0), nil}, {"Error: currency code on left", args{mmc(0, 0, "XXX"), mm(0, 0)}, mm(0, 0), ErrMismatchingCurrency}, {"Error: currency code on right", args{mm(0, 0), mmc(0, 0, "YYY")}, mm(0, 0), ErrMismatchingCurrency}, {"Error: currency code mismatch", args{mmc(0, 0, "AAA"), mmc(0, 0, "BBB")}, mm(0, 0), ErrMismatchingCurrency}, {"Error: invalid +/-", args{mm(+1, -1), mm(0, 0)}, mm(0, 0), ErrInvalidValue}, {"Error: invalid -/+", args{mm(0, 0), mm(-1, +2)}, mm(0, 0), ErrInvalidValue}, {"Error: invalid nanos", args{mm(0, 1000000000), mm(1, 0)}, mm(0, 0), ErrInvalidValue}, {"both positive (no carry)", args{mm(2, 200000000), mm(2, 200000000)}, mm(4, 400000000), nil}, {"both positive (nanos=max)", args{mm(2, 111111111), mm(2, 888888888)}, mm(4, 999999999), nil}, {"both positive (carry)", args{mm(2, 200000000), mm(2, 900000000)}, mm(5, 100000000), nil}, {"both negative (no carry)", args{mm(-2, -200000000), mm(-2, -200000000)}, mm(-4, -400000000), nil}, {"both negative (carry)", args{mm(-2, -200000000), mm(-2, -900000000)}, mm(-5, -100000000), nil}, {"mixed (larger positive, just decimals)", args{mm(11, 0), mm(-2, 0)}, mm(9, 0), nil}, {"mixed (larger negative, just decimals)", args{mm(-11, 0), mm(2, 0)}, mm(-9, 0), nil}, {"mixed (larger positive, no borrow)", args{mm(11, 100000000), mm(-2, -100000000)}, mm(9, 0), nil}, {"mixed (larger positive, with borrow)", args{mm(11, 100000000), mm(-2, -9000000 /*.09*/)}, mm(9, 91000000 /*.091*/), nil}, {"mixed (larger negative, no borrow)", args{mm(-11, -100000000), mm(2, 100000000)}, mm(-9, 0), nil}, {"mixed (larger negative, with borrow)", args{mm(-11, -100000000), mm(2, 9000000 /*.09*/)}, mm(-9, -91000000 /*.091*/), nil}, {"0+negative", args{mm(0, 0), mm(-2, -100000000)}, mm(-2, -100000000), nil}, {"negative+0", args{mm(-2, -100000000), mm(0, 0)}, mm(-2, -100000000), nil}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := Sum(tt.args.l, tt.args.r) if err != tt.wantErr { t.Errorf("Sum([%v],[%v]): expected err=\"%v\" got=\"%v\"", tt.args.l, tt.args.r, tt.wantErr, err) } if !reflect.DeepEqual(got, tt.want) { t.Errorf("Sum([%v],[%v]) = %v, want %v", tt.args.l, tt.args.r, got, tt.want) } }) } } ================================================ FILE: microservices-demo/src/currencyservice/.dockerignore ================================================ client.js node_modules/ ================================================ FILE: microservices-demo/src/currencyservice/.gitignore ================================================ node_modules/ ================================================ FILE: microservices-demo/src/currencyservice/Dockerfile ================================================ # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. FROM node:18-alpine as base FROM base as builder # Some packages (e.g. @google-cloud/profiler) require additional # deps for post-install scripts RUN apk add --update --no-cache \ python3 \ make \ g++ WORKDIR /usr/src/app COPY package*.json ./ RUN npm install --only=production FROM base RUN GRPC_HEALTH_PROBE_VERSION=v0.4.11 && \ wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \ chmod +x /bin/grpc_health_probe WORKDIR /usr/src/app COPY --from=builder /usr/src/app/node_modules ./node_modules COPY . . EXPOSE 7000 ENTRYPOINT [ "node", "server.js" ] ================================================ FILE: microservices-demo/src/currencyservice/client.js ================================================ /* * * Copyright 2015 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ require('@google-cloud/trace-agent').start(); const path = require('path'); const grpc = require('grpc'); const leftPad = require('left-pad'); const pino = require('pino'); const PROTO_PATH = path.join(__dirname, './proto/demo.proto'); const PORT = 7000; const shopProto = grpc.load(PROTO_PATH).hipstershop; const client = new shopProto.CurrencyService(`localhost:${PORT}`, grpc.credentials.createInsecure()); const logger = pino({ name: 'currencyservice-client', messageKey: 'message', changeLevelName: 'severity', useLevelLabels: true }); const request = { from: { currency_code: 'CHF', units: 300, nanos: 0 }, to_code: 'EUR' }; function _moneyToString (m) { return `${m.units}.${m.nanos.toString().padStart(9,'0')} ${m.currency_code}`; } client.getSupportedCurrencies({}, (err, response) => { if (err) { logger.error(`Error in getSupportedCurrencies: ${err}`); } else { logger.info(`Currency codes: ${response.currency_codes}`); } }); client.convert(request, (err, response) => { if (err) { logger.error(`Error in convert: ${err}`); } else { logger.log(`Convert: ${_moneyToString(request.from)} to ${_moneyToString(response)}`); } }); ================================================ FILE: microservices-demo/src/currencyservice/data/currency_conversion.json ================================================ { "EUR": "1.0", "USD": "1.1305", "JPY": "126.40", "BGN": "1.9558", "CZK": "25.592", "DKK": "7.4609", "GBP": "0.85970", "HUF": "315.51", "PLN": "4.2996", "RON": "4.7463", "SEK": "10.5375", "CHF": "1.1360", "ISK": "136.80", "NOK": "9.8040", "HRK": "7.4210", "RUB": "74.4208", "TRY": "6.1247", "AUD": "1.6072", "BRL": "4.2682", "CAD": "1.5128", "CNY": "7.5857", "HKD": "8.8743", "IDR": "15999.40", "ILS": "4.0875", "INR": "79.4320", "KRW": "1275.05", "MXN": "21.7999", "MYR": "4.6289", "NZD": "1.6679", "PHP": "59.083", "SGD": "1.5349", "THB": "36.012", "ZAR": "16.0583" } ================================================ FILE: microservices-demo/src/currencyservice/genproto.sh ================================================ #!/bin/bash -eu # # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # [START gke_currencyservice_genproto] # protos are loaded dynamically for node, simply copies over the proto. mkdir -p proto cp -r ../../pb/* ./proto # [END gke_currencyservice_genproto] ================================================ FILE: microservices-demo/src/currencyservice/package.json ================================================ { "name": "grpc-currency-service", "version": "0.1.0", "description": "A gRPC currency conversion microservice", "repository": "https://github.com/GoogleCloudPlatform/microservices-demo", "scripts": { "test": "echo \"Warn: no test specified\" && exit 0", "lint": "semistandard *.js" }, "license": "Apache-2.0", "dependencies": { "@google-cloud/debug-agent": "5.2.9", "@google-cloud/profiler": "4.2.0", "@google-cloud/trace-agent": "5.1.6", "@grpc/grpc-js": "1.6.11", "@grpc/proto-loader": "0.6.13", "async": "3.2.4", "google-protobuf": "3.20.1", "pino": "5.17.0", "request": "2.88.2", "xml2js": "0.4.23" }, "devDependencies": { "semistandard": "16.0.1" } } ================================================ FILE: microservices-demo/src/currencyservice/proto/demo.proto ================================================ // Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. syntax = "proto3"; package hipstershop; // -----------------Cart service----------------- service CartService { rpc AddItem(AddItemRequest) returns (Empty) {} rpc GetCart(GetCartRequest) returns (Cart) {} rpc EmptyCart(EmptyCartRequest) returns (Empty) {} } message CartItem { string product_id = 1; int32 quantity = 2; } message AddItemRequest { string user_id = 1; CartItem item = 2; } message EmptyCartRequest { string user_id = 1; } message GetCartRequest { string user_id = 1; } message Cart { string user_id = 1; repeated CartItem items = 2; } message Empty {} // ---------------Recommendation service---------- service RecommendationService { rpc ListRecommendations(ListRecommendationsRequest) returns (ListRecommendationsResponse){} } message ListRecommendationsRequest { string user_id = 1; repeated string product_ids = 2; } message ListRecommendationsResponse { repeated string product_ids = 1; } // ---------------Product Catalog---------------- service ProductCatalogService { rpc ListProducts(Empty) returns (ListProductsResponse) {} rpc GetProduct(GetProductRequest) returns (Product) {} rpc SearchProducts(SearchProductsRequest) returns (SearchProductsResponse) {} } message Product { string id = 1; string name = 2; string description = 3; string picture = 4; Money price_usd = 5; // Categories such as "clothing" or "kitchen" that can be used to look up // other related products. repeated string categories = 6; } message ListProductsResponse { repeated Product products = 1; } message GetProductRequest { string id = 1; } message SearchProductsRequest { string query = 1; } message SearchProductsResponse { repeated Product results = 1; } // ---------------Shipping Service---------- service ShippingService { rpc GetQuote(GetQuoteRequest) returns (GetQuoteResponse) {} rpc ShipOrder(ShipOrderRequest) returns (ShipOrderResponse) {} } message GetQuoteRequest { Address address = 1; repeated CartItem items = 2; } message GetQuoteResponse { Money cost_usd = 1; } message ShipOrderRequest { Address address = 1; repeated CartItem items = 2; } message ShipOrderResponse { string tracking_id = 1; } message Address { string street_address = 1; string city = 2; string state = 3; string country = 4; int32 zip_code = 5; } // -----------------Currency service----------------- service CurrencyService { rpc GetSupportedCurrencies(Empty) returns (GetSupportedCurrenciesResponse) {} rpc Convert(CurrencyConversionRequest) returns (Money) {} } // Represents an amount of money with its currency type. message Money { // The 3-letter currency code defined in ISO 4217. string currency_code = 1; // The whole units of the amount. // For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar. int64 units = 2; // Number of nano (10^-9) units of the amount. // The value must be between -999,999,999 and +999,999,999 inclusive. // If `units` is positive, `nanos` must be positive or zero. // If `units` is zero, `nanos` can be positive, zero, or negative. // If `units` is negative, `nanos` must be negative or zero. // For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000. int32 nanos = 3; } message GetSupportedCurrenciesResponse { // The 3-letter currency code defined in ISO 4217. repeated string currency_codes = 1; } message CurrencyConversionRequest { Money from = 1; // The 3-letter currency code defined in ISO 4217. string to_code = 2; } // -------------Payment service----------------- service PaymentService { rpc Charge(ChargeRequest) returns (ChargeResponse) {} } message CreditCardInfo { string credit_card_number = 1; int32 credit_card_cvv = 2; int32 credit_card_expiration_year = 3; int32 credit_card_expiration_month = 4; } message ChargeRequest { Money amount = 1; CreditCardInfo credit_card = 2; } message ChargeResponse { string transaction_id = 1; } // -------------Email service----------------- service EmailService { rpc SendOrderConfirmation(SendOrderConfirmationRequest) returns (Empty) {} } message OrderItem { CartItem item = 1; Money cost = 2; } message OrderResult { string order_id = 1; string shipping_tracking_id = 2; Money shipping_cost = 3; Address shipping_address = 4; repeated OrderItem items = 5; } message SendOrderConfirmationRequest { string email = 1; OrderResult order = 2; } // -------------Checkout service----------------- service CheckoutService { rpc PlaceOrder(PlaceOrderRequest) returns (PlaceOrderResponse) {} } message PlaceOrderRequest { string user_id = 1; string user_currency = 2; Address address = 3; string email = 5; CreditCardInfo credit_card = 6; } message PlaceOrderResponse { OrderResult order = 1; } // ------------Ad service------------------ service AdService { rpc GetAds(AdRequest) returns (AdResponse) {} } message AdRequest { // List of important key words from the current page describing the context. repeated string context_keys = 1; } message AdResponse { repeated Ad ads = 1; } message Ad { // url to redirect to when an ad is clicked. string redirect_url = 1; // short advertisement text to display. string text = 2; } ================================================ FILE: microservices-demo/src/currencyservice/proto/grpc/health/v1/health.proto ================================================ // Copyright 2015 The gRPC Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // The canonical version of this proto can be found at // https://github.com/grpc/grpc-proto/blob/master/grpc/health/v1/health.proto syntax = "proto3"; package grpc.health.v1; option csharp_namespace = "Grpc.Health.V1"; option go_package = "google.golang.org/grpc/health/grpc_health_v1"; option java_multiple_files = true; option java_outer_classname = "HealthProto"; option java_package = "io.grpc.health.v1"; message HealthCheckRequest { string service = 1; } message HealthCheckResponse { enum ServingStatus { UNKNOWN = 0; SERVING = 1; NOT_SERVING = 2; } ServingStatus status = 1; } service Health { rpc Check(HealthCheckRequest) returns (HealthCheckResponse); } ================================================ FILE: microservices-demo/src/currencyservice/server.js ================================================ /* * Copyright 2018 Google LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ if(process.env.DISABLE_PROFILER) { console.log("Profiler disabled.") } else { console.log("Profiler enabled.") require('@google-cloud/profiler').start({ serviceContext: { service: 'currencyservice', version: '1.0.0' } }); } if(process.env.DISABLE_TRACING) { console.log("Tracing disabled.") } else { console.log("Tracing enabled.") require('@google-cloud/trace-agent').start(); } if(process.env.DISABLE_DEBUGGER) { console.log("Debugger disabled.") } else { console.log("Debugger enabled.") require('@google-cloud/debug-agent').start({ serviceContext: { service: 'currencyservice', version: 'VERSION' } }); } const path = require('path'); const grpc = require('@grpc/grpc-js'); const pino = require('pino'); const protoLoader = require('@grpc/proto-loader'); const MAIN_PROTO_PATH = path.join(__dirname, './proto/demo.proto'); const HEALTH_PROTO_PATH = path.join(__dirname, './proto/grpc/health/v1/health.proto'); const PORT = process.env.PORT; const shopProto = _loadProto(MAIN_PROTO_PATH).hipstershop; const healthProto = _loadProto(HEALTH_PROTO_PATH).grpc.health.v1; const logger = pino({ name: 'currencyservice-server', messageKey: 'message', changeLevelName: 'severity', useLevelLabels: true }); /** * Helper function that loads a protobuf file. */ function _loadProto (path) { const packageDefinition = protoLoader.loadSync( path, { keepCase: true, longs: String, enums: String, defaults: true, oneofs: true } ); return grpc.loadPackageDefinition(packageDefinition); } /** * Helper function that gets currency data from a stored JSON file * Uses public data from European Central Bank */ function _getCurrencyData (callback) { const data = require('./data/currency_conversion.json'); callback(data); } /** * Helper function that handles decimal/fractional carrying */ function _carry (amount) { const fractionSize = Math.pow(10, 9); amount.nanos += (amount.units % 1) * fractionSize; amount.units = Math.floor(amount.units) + Math.floor(amount.nanos / fractionSize); amount.nanos = amount.nanos % fractionSize; return amount; } /** * Lists the supported currencies */ function getSupportedCurrencies (call, callback) { logger.info('Getting supported currencies...'); _getCurrencyData((data) => { callback(null, {currency_codes: Object.keys(data)}); }); } /** * Converts between currencies */ function convert (call, callback) { try { _getCurrencyData((data) => { const request = call.request; // Convert: from_currency --> EUR const from = request.from; const euros = _carry({ units: from.units / data[from.currency_code], nanos: from.nanos / data[from.currency_code] }); euros.nanos = Math.round(euros.nanos); // Convert: EUR --> to_currency const result = _carry({ units: euros.units * data[request.to_code], nanos: euros.nanos * data[request.to_code] }); result.units = Math.floor(result.units); result.nanos = Math.floor(result.nanos); result.currency_code = request.to_code; logger.info(`conversion request successful`); callback(null, result); }); } catch (err) { logger.error(`conversion request failed: ${err}`); callback(err.message); } } /** * Endpoint for health checks */ function check (call, callback) { callback(null, { status: 'SERVING' }); } /** * Starts an RPC server that receives requests for the * CurrencyConverter service at the sample server port */ function main () { logger.info(`Starting gRPC server on port ${PORT}...`); const server = new grpc.Server(); server.addService(shopProto.CurrencyService.service, {getSupportedCurrencies, convert}); server.addService(healthProto.Health.service, {check}); server.bindAsync( `0.0.0.0:${PORT}`, grpc.ServerCredentials.createInsecure(), function() { logger.info(`CurrencyService gRPC server started on port ${PORT}`); server.start(); }, ); } main(); ================================================ FILE: microservices-demo/src/emailservice/.python-version ================================================ 3.7 ================================================ FILE: microservices-demo/src/emailservice/Dockerfile ================================================ # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. FROM python:3.7-slim as base FROM base as builder RUN apt-get -qq update \ && apt-get install -y --no-install-recommends \ g++ \ && rm -rf /var/lib/apt/lists/* # get packages COPY requirements.txt . RUN pip install -r requirements.txt FROM base as final # Enable unbuffered logging ENV PYTHONUNBUFFERED=1 # Enable Profiler ENV ENABLE_PROFILER=1 RUN apt-get -qq update \ && apt-get install -y --no-install-recommends \ wget # Download the grpc health probe RUN GRPC_HEALTH_PROBE_VERSION=v0.4.11 && \ wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \ chmod +x /bin/grpc_health_probe WORKDIR /email_server # Grab packages from builder COPY --from=builder /usr/local/lib/python3.7/ /usr/local/lib/python3.7/ # Add the application COPY . . EXPOSE 8080 ENTRYPOINT [ "python", "email_server.py" ] ================================================ FILE: microservices-demo/src/emailservice/Procfile ================================================ web: python email_server.py ================================================ FILE: microservices-demo/src/emailservice/demo_pb2.py ================================================ #!/usr/bin/python # # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Generated by the protocol buffer compiler. DO NOT EDIT! # source: demo.proto import sys _b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from google.protobuf import reflection as _reflection from google.protobuf import symbol_database as _symbol_database from google.protobuf import descriptor_pb2 # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() DESCRIPTOR = _descriptor.FileDescriptor( name='demo.proto', package='hipstershop', syntax='proto3', serialized_pb=_b('\n\ndemo.proto\x12\x0bhipstershop\"0\n\x08\x43\x61rtItem\x12\x12\n\nproduct_id\x18\x01 \x01(\t\x12\x10\n\x08quantity\x18\x02 \x01(\x05\"F\n\x0e\x41\x64\x64ItemRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12#\n\x04item\x18\x02 \x01(\x0b\x32\x15.hipstershop.CartItem\"#\n\x10\x45mptyCartRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\"!\n\x0eGetCartRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\"=\n\x04\x43\x61rt\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12$\n\x05items\x18\x02 \x03(\x0b\x32\x15.hipstershop.CartItem\"\x07\n\x05\x45mpty\"B\n\x1aListRecommendationsRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12\x13\n\x0bproduct_ids\x18\x02 \x03(\t\"2\n\x1bListRecommendationsResponse\x12\x13\n\x0bproduct_ids\x18\x01 \x03(\t\"p\n\x07Product\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x0f\n\x07picture\x18\x04 \x01(\t\x12%\n\tprice_usd\x18\x05 \x01(\x0b\x32\x12.hipstershop.Money\">\n\x14ListProductsResponse\x12&\n\x08products\x18\x01 \x03(\x0b\x32\x14.hipstershop.Product\"\x1f\n\x11GetProductRequest\x12\n\n\x02id\x18\x01 \x01(\t\"&\n\x15SearchProductsRequest\x12\r\n\x05query\x18\x01 \x01(\t\"?\n\x16SearchProductsResponse\x12%\n\x07results\x18\x01 \x03(\x0b\x32\x14.hipstershop.Product\"^\n\x0fGetQuoteRequest\x12%\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x14.hipstershop.Address\x12$\n\x05items\x18\x02 \x03(\x0b\x32\x15.hipstershop.CartItem\"8\n\x10GetQuoteResponse\x12$\n\x08\x63ost_usd\x18\x01 \x01(\x0b\x32\x12.hipstershop.Money\"_\n\x10ShipOrderRequest\x12%\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x14.hipstershop.Address\x12$\n\x05items\x18\x02 \x03(\x0b\x32\x15.hipstershop.CartItem\"(\n\x11ShipOrderResponse\x12\x13\n\x0btracking_id\x18\x01 \x01(\t\"n\n\x07\x41\x64\x64ress\x12\x18\n\x10street_address_1\x18\x01 \x01(\t\x12\x18\n\x10street_address_2\x18\x02 \x01(\t\x12\x0c\n\x04\x63ity\x18\x03 \x01(\t\x12\x0f\n\x07\x63ountry\x18\x04 \x01(\t\x12\x10\n\x08zip_code\x18\x05 \x01(\x05\"<\n\x05Money\x12\x15\n\rcurrency_code\x18\x01 \x01(\t\x12\r\n\x05units\x18\x02 \x01(\x03\x12\r\n\x05nanos\x18\x03 \x01(\x05\"8\n\x1eGetSupportedCurrenciesResponse\x12\x16\n\x0e\x63urrency_codes\x18\x01 \x03(\t\"N\n\x19\x43urrencyConversionRequest\x12 \n\x04\x66rom\x18\x01 \x01(\x0b\x32\x12.hipstershop.Money\x12\x0f\n\x07to_code\x18\x02 \x01(\t\"\x90\x01\n\x0e\x43reditCardInfo\x12\x1a\n\x12\x63redit_card_number\x18\x01 \x01(\t\x12\x17\n\x0f\x63redit_card_cvv\x18\x02 \x01(\x05\x12#\n\x1b\x63redit_card_expiration_year\x18\x03 \x01(\x05\x12$\n\x1c\x63redit_card_expiration_month\x18\x04 \x01(\x05\"e\n\rChargeRequest\x12\"\n\x06\x61mount\x18\x01 \x01(\x0b\x32\x12.hipstershop.Money\x12\x30\n\x0b\x63redit_card\x18\x02 \x01(\x0b\x32\x1b.hipstershop.CreditCardInfo\"(\n\x0e\x43hargeResponse\x12\x16\n\x0etransaction_id\x18\x01 \x01(\t\"R\n\tOrderItem\x12#\n\x04item\x18\x01 \x01(\x0b\x32\x15.hipstershop.CartItem\x12 \n\x04\x63ost\x18\x02 \x01(\x0b\x32\x12.hipstershop.Money\"\xbf\x01\n\x0bOrderResult\x12\x10\n\x08order_id\x18\x01 \x01(\t\x12\x1c\n\x14shipping_tracking_id\x18\x02 \x01(\t\x12)\n\rshipping_cost\x18\x03 \x01(\x0b\x32\x12.hipstershop.Money\x12.\n\x10shipping_address\x18\x04 \x01(\x0b\x32\x14.hipstershop.Address\x12%\n\x05items\x18\x05 \x03(\x0b\x32\x16.hipstershop.OrderItem\"V\n\x1cSendOrderConfirmationRequest\x12\r\n\x05\x65mail\x18\x01 \x01(\t\x12\'\n\x05order\x18\x02 \x01(\x0b\x32\x18.hipstershop.OrderResult\"c\n\x12\x43reateOrderRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12\x15\n\ruser_currency\x18\x02 \x01(\t\x12%\n\x07\x61\x64\x64ress\x18\x03 \x01(\x0b\x32\x14.hipstershop.Address\"g\n\x13\x43reateOrderResponse\x12%\n\x05items\x18\x01 \x03(\x0b\x32\x16.hipstershop.OrderItem\x12)\n\rshipping_cost\x18\x02 \x01(\x0b\x32\x12.hipstershop.Money\"\xa3\x01\n\x11PlaceOrderRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12\x15\n\ruser_currency\x18\x02 \x01(\t\x12%\n\x07\x61\x64\x64ress\x18\x03 \x01(\x0b\x32\x14.hipstershop.Address\x12\r\n\x05\x65mail\x18\x05 \x01(\t\x12\x30\n\x0b\x63redit_card\x18\x06 \x01(\x0b\x32\x1b.hipstershop.CreditCardInfo\"=\n\x12PlaceOrderResponse\x12\'\n\x05order\x18\x01 \x01(\x0b\x32\x18.hipstershop.OrderResult2\xca\x01\n\x0b\x43\x61rtService\x12<\n\x07\x41\x64\x64Item\x12\x1b.hipstershop.AddItemRequest\x1a\x12.hipstershop.Empty\"\x00\x12;\n\x07GetCart\x12\x1b.hipstershop.GetCartRequest\x1a\x11.hipstershop.Cart\"\x00\x12@\n\tEmptyCart\x12\x1d.hipstershop.EmptyCartRequest\x1a\x12.hipstershop.Empty\"\x00\x32\x83\x01\n\x15RecommendationService\x12j\n\x13ListRecommendations\x12\'.hipstershop.ListRecommendationsRequest\x1a(.hipstershop.ListRecommendationsResponse\"\x00\x32\x83\x02\n\x15ProductCatalogService\x12G\n\x0cListProducts\x12\x12.hipstershop.Empty\x1a!.hipstershop.ListProductsResponse\"\x00\x12\x44\n\nGetProduct\x12\x1e.hipstershop.GetProductRequest\x1a\x14.hipstershop.Product\"\x00\x12[\n\x0eSearchProducts\x12\".hipstershop.SearchProductsRequest\x1a#.hipstershop.SearchProductsResponse\"\x00\x32\xaa\x01\n\x0fShippingService\x12I\n\x08GetQuote\x12\x1c.hipstershop.GetQuoteRequest\x1a\x1d.hipstershop.GetQuoteResponse\"\x00\x12L\n\tShipOrder\x12\x1d.hipstershop.ShipOrderRequest\x1a\x1e.hipstershop.ShipOrderResponse\"\x00\x32\xb7\x01\n\x0f\x43urrencyService\x12[\n\x16GetSupportedCurrencies\x12\x12.hipstershop.Empty\x1a+.hipstershop.GetSupportedCurrenciesResponse\"\x00\x12G\n\x07\x43onvert\x12&.hipstershop.CurrencyConversionRequest\x1a\x12.hipstershop.Money\"\x00\x32U\n\x0ePaymentService\x12\x43\n\x06\x43harge\x12\x1a.hipstershop.ChargeRequest\x1a\x1b.hipstershop.ChargeResponse\"\x00\x32h\n\x0c\x45mailService\x12X\n\x15SendOrderConfirmation\x12).hipstershop.SendOrderConfirmationRequest\x1a\x12.hipstershop.Empty\"\x00\x32\xb6\x01\n\x0f\x43heckoutService\x12R\n\x0b\x43reateOrder\x12\x1f.hipstershop.CreateOrderRequest\x1a .hipstershop.CreateOrderResponse\"\x00\x12O\n\nPlaceOrder\x12\x1e.hipstershop.PlaceOrderRequest\x1a\x1f.hipstershop.PlaceOrderResponse\"\x00\x62\x06proto3') ) _CARTITEM = _descriptor.Descriptor( name='CartItem', full_name='hipstershop.CartItem', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='product_id', full_name='hipstershop.CartItem.product_id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='quantity', full_name='hipstershop.CartItem.quantity', index=1, number=2, type=5, cpp_type=1, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=27, serialized_end=75, ) _ADDITEMREQUEST = _descriptor.Descriptor( name='AddItemRequest', full_name='hipstershop.AddItemRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='user_id', full_name='hipstershop.AddItemRequest.user_id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='item', full_name='hipstershop.AddItemRequest.item', index=1, number=2, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=77, serialized_end=147, ) _EMPTYCARTREQUEST = _descriptor.Descriptor( name='EmptyCartRequest', full_name='hipstershop.EmptyCartRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='user_id', full_name='hipstershop.EmptyCartRequest.user_id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=149, serialized_end=184, ) _GETCARTREQUEST = _descriptor.Descriptor( name='GetCartRequest', full_name='hipstershop.GetCartRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='user_id', full_name='hipstershop.GetCartRequest.user_id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=186, serialized_end=219, ) _CART = _descriptor.Descriptor( name='Cart', full_name='hipstershop.Cart', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='user_id', full_name='hipstershop.Cart.user_id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='items', full_name='hipstershop.Cart.items', index=1, number=2, type=11, cpp_type=10, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=221, serialized_end=282, ) _EMPTY = _descriptor.Descriptor( name='Empty', full_name='hipstershop.Empty', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=284, serialized_end=291, ) _LISTRECOMMENDATIONSREQUEST = _descriptor.Descriptor( name='ListRecommendationsRequest', full_name='hipstershop.ListRecommendationsRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='user_id', full_name='hipstershop.ListRecommendationsRequest.user_id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='product_ids', full_name='hipstershop.ListRecommendationsRequest.product_ids', index=1, number=2, type=9, cpp_type=9, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=293, serialized_end=359, ) _LISTRECOMMENDATIONSRESPONSE = _descriptor.Descriptor( name='ListRecommendationsResponse', full_name='hipstershop.ListRecommendationsResponse', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='product_ids', full_name='hipstershop.ListRecommendationsResponse.product_ids', index=0, number=1, type=9, cpp_type=9, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=361, serialized_end=411, ) _PRODUCT = _descriptor.Descriptor( name='Product', full_name='hipstershop.Product', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='id', full_name='hipstershop.Product.id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='name', full_name='hipstershop.Product.name', index=1, number=2, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='description', full_name='hipstershop.Product.description', index=2, number=3, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='picture', full_name='hipstershop.Product.picture', index=3, number=4, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='price_usd', full_name='hipstershop.Product.price_usd', index=4, number=5, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=413, serialized_end=525, ) _LISTPRODUCTSRESPONSE = _descriptor.Descriptor( name='ListProductsResponse', full_name='hipstershop.ListProductsResponse', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='products', full_name='hipstershop.ListProductsResponse.products', index=0, number=1, type=11, cpp_type=10, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=527, serialized_end=589, ) _GETPRODUCTREQUEST = _descriptor.Descriptor( name='GetProductRequest', full_name='hipstershop.GetProductRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='id', full_name='hipstershop.GetProductRequest.id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=591, serialized_end=622, ) _SEARCHPRODUCTSREQUEST = _descriptor.Descriptor( name='SearchProductsRequest', full_name='hipstershop.SearchProductsRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='query', full_name='hipstershop.SearchProductsRequest.query', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=624, serialized_end=662, ) _SEARCHPRODUCTSRESPONSE = _descriptor.Descriptor( name='SearchProductsResponse', full_name='hipstershop.SearchProductsResponse', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='results', full_name='hipstershop.SearchProductsResponse.results', index=0, number=1, type=11, cpp_type=10, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=664, serialized_end=727, ) _GETQUOTEREQUEST = _descriptor.Descriptor( name='GetQuoteRequest', full_name='hipstershop.GetQuoteRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='address', full_name='hipstershop.GetQuoteRequest.address', index=0, number=1, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='items', full_name='hipstershop.GetQuoteRequest.items', index=1, number=2, type=11, cpp_type=10, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=729, serialized_end=823, ) _GETQUOTERESPONSE = _descriptor.Descriptor( name='GetQuoteResponse', full_name='hipstershop.GetQuoteResponse', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='cost_usd', full_name='hipstershop.GetQuoteResponse.cost_usd', index=0, number=1, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=825, serialized_end=881, ) _SHIPORDERREQUEST = _descriptor.Descriptor( name='ShipOrderRequest', full_name='hipstershop.ShipOrderRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='address', full_name='hipstershop.ShipOrderRequest.address', index=0, number=1, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='items', full_name='hipstershop.ShipOrderRequest.items', index=1, number=2, type=11, cpp_type=10, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=883, serialized_end=978, ) _SHIPORDERRESPONSE = _descriptor.Descriptor( name='ShipOrderResponse', full_name='hipstershop.ShipOrderResponse', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='tracking_id', full_name='hipstershop.ShipOrderResponse.tracking_id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=980, serialized_end=1020, ) _ADDRESS = _descriptor.Descriptor( name='Address', full_name='hipstershop.Address', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='street_address_1', full_name='hipstershop.Address.street_address_1', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='street_address_2', full_name='hipstershop.Address.street_address_2', index=1, number=2, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='city', full_name='hipstershop.Address.city', index=2, number=3, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='country', full_name='hipstershop.Address.country', index=3, number=4, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='zip_code', full_name='hipstershop.Address.zip_code', index=4, number=5, type=5, cpp_type=1, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=1022, serialized_end=1132, ) _MONEY = _descriptor.Descriptor( name='Money', full_name='hipstershop.Money', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='currency_code', full_name='hipstershop.Money.currency_code', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='units', full_name='hipstershop.Money.units', index=1, number=2, type=3, cpp_type=2, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='nanos', full_name='hipstershop.Money.nanos', index=2, number=3, type=5, cpp_type=1, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=1134, serialized_end=1194, ) _GETSUPPORTEDCURRENCIESRESPONSE = _descriptor.Descriptor( name='GetSupportedCurrenciesResponse', full_name='hipstershop.GetSupportedCurrenciesResponse', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='currency_codes', full_name='hipstershop.GetSupportedCurrenciesResponse.currency_codes', index=0, number=1, type=9, cpp_type=9, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=1196, serialized_end=1252, ) _CURRENCYCONVERSIONREQUEST = _descriptor.Descriptor( name='CurrencyConversionRequest', full_name='hipstershop.CurrencyConversionRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='from', full_name='hipstershop.CurrencyConversionRequest.from', index=0, number=1, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='to_code', full_name='hipstershop.CurrencyConversionRequest.to_code', index=1, number=2, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=1254, serialized_end=1332, ) _CREDITCARDINFO = _descriptor.Descriptor( name='CreditCardInfo', full_name='hipstershop.CreditCardInfo', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='credit_card_number', full_name='hipstershop.CreditCardInfo.credit_card_number', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='credit_card_cvv', full_name='hipstershop.CreditCardInfo.credit_card_cvv', index=1, number=2, type=5, cpp_type=1, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='credit_card_expiration_year', full_name='hipstershop.CreditCardInfo.credit_card_expiration_year', index=2, number=3, type=5, cpp_type=1, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='credit_card_expiration_month', full_name='hipstershop.CreditCardInfo.credit_card_expiration_month', index=3, number=4, type=5, cpp_type=1, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=1335, serialized_end=1479, ) _CHARGEREQUEST = _descriptor.Descriptor( name='ChargeRequest', full_name='hipstershop.ChargeRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='amount', full_name='hipstershop.ChargeRequest.amount', index=0, number=1, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='credit_card', full_name='hipstershop.ChargeRequest.credit_card', index=1, number=2, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=1481, serialized_end=1582, ) _CHARGERESPONSE = _descriptor.Descriptor( name='ChargeResponse', full_name='hipstershop.ChargeResponse', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='transaction_id', full_name='hipstershop.ChargeResponse.transaction_id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=1584, serialized_end=1624, ) _ORDERITEM = _descriptor.Descriptor( name='OrderItem', full_name='hipstershop.OrderItem', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='item', full_name='hipstershop.OrderItem.item', index=0, number=1, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='cost', full_name='hipstershop.OrderItem.cost', index=1, number=2, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=1626, serialized_end=1708, ) _ORDERRESULT = _descriptor.Descriptor( name='OrderResult', full_name='hipstershop.OrderResult', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='order_id', full_name='hipstershop.OrderResult.order_id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='shipping_tracking_id', full_name='hipstershop.OrderResult.shipping_tracking_id', index=1, number=2, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='shipping_cost', full_name='hipstershop.OrderResult.shipping_cost', index=2, number=3, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='shipping_address', full_name='hipstershop.OrderResult.shipping_address', index=3, number=4, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='items', full_name='hipstershop.OrderResult.items', index=4, number=5, type=11, cpp_type=10, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=1711, serialized_end=1902, ) _SENDORDERCONFIRMATIONREQUEST = _descriptor.Descriptor( name='SendOrderConfirmationRequest', full_name='hipstershop.SendOrderConfirmationRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='email', full_name='hipstershop.SendOrderConfirmationRequest.email', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='order', full_name='hipstershop.SendOrderConfirmationRequest.order', index=1, number=2, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=1904, serialized_end=1990, ) _CREATEORDERREQUEST = _descriptor.Descriptor( name='CreateOrderRequest', full_name='hipstershop.CreateOrderRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='user_id', full_name='hipstershop.CreateOrderRequest.user_id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='user_currency', full_name='hipstershop.CreateOrderRequest.user_currency', index=1, number=2, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='address', full_name='hipstershop.CreateOrderRequest.address', index=2, number=3, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=1992, serialized_end=2091, ) _CREATEORDERRESPONSE = _descriptor.Descriptor( name='CreateOrderResponse', full_name='hipstershop.CreateOrderResponse', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='items', full_name='hipstershop.CreateOrderResponse.items', index=0, number=1, type=11, cpp_type=10, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='shipping_cost', full_name='hipstershop.CreateOrderResponse.shipping_cost', index=1, number=2, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=2093, serialized_end=2196, ) _PLACEORDERREQUEST = _descriptor.Descriptor( name='PlaceOrderRequest', full_name='hipstershop.PlaceOrderRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='user_id', full_name='hipstershop.PlaceOrderRequest.user_id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='user_currency', full_name='hipstershop.PlaceOrderRequest.user_currency', index=1, number=2, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='address', full_name='hipstershop.PlaceOrderRequest.address', index=2, number=3, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='email', full_name='hipstershop.PlaceOrderRequest.email', index=3, number=5, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='credit_card', full_name='hipstershop.PlaceOrderRequest.credit_card', index=4, number=6, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=2199, serialized_end=2362, ) _PLACEORDERRESPONSE = _descriptor.Descriptor( name='PlaceOrderResponse', full_name='hipstershop.PlaceOrderResponse', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='order', full_name='hipstershop.PlaceOrderResponse.order', index=0, number=1, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=2364, serialized_end=2425, ) _ADDITEMREQUEST.fields_by_name['item'].message_type = _CARTITEM _CART.fields_by_name['items'].message_type = _CARTITEM _PRODUCT.fields_by_name['price_usd'].message_type = _MONEY _LISTPRODUCTSRESPONSE.fields_by_name['products'].message_type = _PRODUCT _SEARCHPRODUCTSRESPONSE.fields_by_name['results'].message_type = _PRODUCT _GETQUOTEREQUEST.fields_by_name['address'].message_type = _ADDRESS _GETQUOTEREQUEST.fields_by_name['items'].message_type = _CARTITEM _GETQUOTERESPONSE.fields_by_name['cost_usd'].message_type = _MONEY _SHIPORDERREQUEST.fields_by_name['address'].message_type = _ADDRESS _SHIPORDERREQUEST.fields_by_name['items'].message_type = _CARTITEM _CURRENCYCONVERSIONREQUEST.fields_by_name['from'].message_type = _MONEY _CHARGEREQUEST.fields_by_name['amount'].message_type = _MONEY _CHARGEREQUEST.fields_by_name['credit_card'].message_type = _CREDITCARDINFO _ORDERITEM.fields_by_name['item'].message_type = _CARTITEM _ORDERITEM.fields_by_name['cost'].message_type = _MONEY _ORDERRESULT.fields_by_name['shipping_cost'].message_type = _MONEY _ORDERRESULT.fields_by_name['shipping_address'].message_type = _ADDRESS _ORDERRESULT.fields_by_name['items'].message_type = _ORDERITEM _SENDORDERCONFIRMATIONREQUEST.fields_by_name['order'].message_type = _ORDERRESULT _CREATEORDERREQUEST.fields_by_name['address'].message_type = _ADDRESS _CREATEORDERRESPONSE.fields_by_name['items'].message_type = _ORDERITEM _CREATEORDERRESPONSE.fields_by_name['shipping_cost'].message_type = _MONEY _PLACEORDERREQUEST.fields_by_name['address'].message_type = _ADDRESS _PLACEORDERREQUEST.fields_by_name['credit_card'].message_type = _CREDITCARDINFO _PLACEORDERRESPONSE.fields_by_name['order'].message_type = _ORDERRESULT DESCRIPTOR.message_types_by_name['CartItem'] = _CARTITEM DESCRIPTOR.message_types_by_name['AddItemRequest'] = _ADDITEMREQUEST DESCRIPTOR.message_types_by_name['EmptyCartRequest'] = _EMPTYCARTREQUEST DESCRIPTOR.message_types_by_name['GetCartRequest'] = _GETCARTREQUEST DESCRIPTOR.message_types_by_name['Cart'] = _CART DESCRIPTOR.message_types_by_name['Empty'] = _EMPTY DESCRIPTOR.message_types_by_name['ListRecommendationsRequest'] = _LISTRECOMMENDATIONSREQUEST DESCRIPTOR.message_types_by_name['ListRecommendationsResponse'] = _LISTRECOMMENDATIONSRESPONSE DESCRIPTOR.message_types_by_name['Product'] = _PRODUCT DESCRIPTOR.message_types_by_name['ListProductsResponse'] = _LISTPRODUCTSRESPONSE DESCRIPTOR.message_types_by_name['GetProductRequest'] = _GETPRODUCTREQUEST DESCRIPTOR.message_types_by_name['SearchProductsRequest'] = _SEARCHPRODUCTSREQUEST DESCRIPTOR.message_types_by_name['SearchProductsResponse'] = _SEARCHPRODUCTSRESPONSE DESCRIPTOR.message_types_by_name['GetQuoteRequest'] = _GETQUOTEREQUEST DESCRIPTOR.message_types_by_name['GetQuoteResponse'] = _GETQUOTERESPONSE DESCRIPTOR.message_types_by_name['ShipOrderRequest'] = _SHIPORDERREQUEST DESCRIPTOR.message_types_by_name['ShipOrderResponse'] = _SHIPORDERRESPONSE DESCRIPTOR.message_types_by_name['Address'] = _ADDRESS DESCRIPTOR.message_types_by_name['Money'] = _MONEY DESCRIPTOR.message_types_by_name['GetSupportedCurrenciesResponse'] = _GETSUPPORTEDCURRENCIESRESPONSE DESCRIPTOR.message_types_by_name['CurrencyConversionRequest'] = _CURRENCYCONVERSIONREQUEST DESCRIPTOR.message_types_by_name['CreditCardInfo'] = _CREDITCARDINFO DESCRIPTOR.message_types_by_name['ChargeRequest'] = _CHARGEREQUEST DESCRIPTOR.message_types_by_name['ChargeResponse'] = _CHARGERESPONSE DESCRIPTOR.message_types_by_name['OrderItem'] = _ORDERITEM DESCRIPTOR.message_types_by_name['OrderResult'] = _ORDERRESULT DESCRIPTOR.message_types_by_name['SendOrderConfirmationRequest'] = _SENDORDERCONFIRMATIONREQUEST DESCRIPTOR.message_types_by_name['CreateOrderRequest'] = _CREATEORDERREQUEST DESCRIPTOR.message_types_by_name['CreateOrderResponse'] = _CREATEORDERRESPONSE DESCRIPTOR.message_types_by_name['PlaceOrderRequest'] = _PLACEORDERREQUEST DESCRIPTOR.message_types_by_name['PlaceOrderResponse'] = _PLACEORDERRESPONSE _sym_db.RegisterFileDescriptor(DESCRIPTOR) CartItem = _reflection.GeneratedProtocolMessageType('CartItem', (_message.Message,), dict( DESCRIPTOR = _CARTITEM, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.CartItem) )) _sym_db.RegisterMessage(CartItem) AddItemRequest = _reflection.GeneratedProtocolMessageType('AddItemRequest', (_message.Message,), dict( DESCRIPTOR = _ADDITEMREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.AddItemRequest) )) _sym_db.RegisterMessage(AddItemRequest) EmptyCartRequest = _reflection.GeneratedProtocolMessageType('EmptyCartRequest', (_message.Message,), dict( DESCRIPTOR = _EMPTYCARTREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.EmptyCartRequest) )) _sym_db.RegisterMessage(EmptyCartRequest) GetCartRequest = _reflection.GeneratedProtocolMessageType('GetCartRequest', (_message.Message,), dict( DESCRIPTOR = _GETCARTREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.GetCartRequest) )) _sym_db.RegisterMessage(GetCartRequest) Cart = _reflection.GeneratedProtocolMessageType('Cart', (_message.Message,), dict( DESCRIPTOR = _CART, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.Cart) )) _sym_db.RegisterMessage(Cart) Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), dict( DESCRIPTOR = _EMPTY, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.Empty) )) _sym_db.RegisterMessage(Empty) ListRecommendationsRequest = _reflection.GeneratedProtocolMessageType('ListRecommendationsRequest', (_message.Message,), dict( DESCRIPTOR = _LISTRECOMMENDATIONSREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.ListRecommendationsRequest) )) _sym_db.RegisterMessage(ListRecommendationsRequest) ListRecommendationsResponse = _reflection.GeneratedProtocolMessageType('ListRecommendationsResponse', (_message.Message,), dict( DESCRIPTOR = _LISTRECOMMENDATIONSRESPONSE, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.ListRecommendationsResponse) )) _sym_db.RegisterMessage(ListRecommendationsResponse) Product = _reflection.GeneratedProtocolMessageType('Product', (_message.Message,), dict( DESCRIPTOR = _PRODUCT, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.Product) )) _sym_db.RegisterMessage(Product) ListProductsResponse = _reflection.GeneratedProtocolMessageType('ListProductsResponse', (_message.Message,), dict( DESCRIPTOR = _LISTPRODUCTSRESPONSE, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.ListProductsResponse) )) _sym_db.RegisterMessage(ListProductsResponse) GetProductRequest = _reflection.GeneratedProtocolMessageType('GetProductRequest', (_message.Message,), dict( DESCRIPTOR = _GETPRODUCTREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.GetProductRequest) )) _sym_db.RegisterMessage(GetProductRequest) SearchProductsRequest = _reflection.GeneratedProtocolMessageType('SearchProductsRequest', (_message.Message,), dict( DESCRIPTOR = _SEARCHPRODUCTSREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.SearchProductsRequest) )) _sym_db.RegisterMessage(SearchProductsRequest) SearchProductsResponse = _reflection.GeneratedProtocolMessageType('SearchProductsResponse', (_message.Message,), dict( DESCRIPTOR = _SEARCHPRODUCTSRESPONSE, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.SearchProductsResponse) )) _sym_db.RegisterMessage(SearchProductsResponse) GetQuoteRequest = _reflection.GeneratedProtocolMessageType('GetQuoteRequest', (_message.Message,), dict( DESCRIPTOR = _GETQUOTEREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.GetQuoteRequest) )) _sym_db.RegisterMessage(GetQuoteRequest) GetQuoteResponse = _reflection.GeneratedProtocolMessageType('GetQuoteResponse', (_message.Message,), dict( DESCRIPTOR = _GETQUOTERESPONSE, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.GetQuoteResponse) )) _sym_db.RegisterMessage(GetQuoteResponse) ShipOrderRequest = _reflection.GeneratedProtocolMessageType('ShipOrderRequest', (_message.Message,), dict( DESCRIPTOR = _SHIPORDERREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.ShipOrderRequest) )) _sym_db.RegisterMessage(ShipOrderRequest) ShipOrderResponse = _reflection.GeneratedProtocolMessageType('ShipOrderResponse', (_message.Message,), dict( DESCRIPTOR = _SHIPORDERRESPONSE, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.ShipOrderResponse) )) _sym_db.RegisterMessage(ShipOrderResponse) Address = _reflection.GeneratedProtocolMessageType('Address', (_message.Message,), dict( DESCRIPTOR = _ADDRESS, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.Address) )) _sym_db.RegisterMessage(Address) Money = _reflection.GeneratedProtocolMessageType('Money', (_message.Message,), dict( DESCRIPTOR = _MONEY, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.Money) )) _sym_db.RegisterMessage(Money) GetSupportedCurrenciesResponse = _reflection.GeneratedProtocolMessageType('GetSupportedCurrenciesResponse', (_message.Message,), dict( DESCRIPTOR = _GETSUPPORTEDCURRENCIESRESPONSE, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.GetSupportedCurrenciesResponse) )) _sym_db.RegisterMessage(GetSupportedCurrenciesResponse) CurrencyConversionRequest = _reflection.GeneratedProtocolMessageType('CurrencyConversionRequest', (_message.Message,), dict( DESCRIPTOR = _CURRENCYCONVERSIONREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.CurrencyConversionRequest) )) _sym_db.RegisterMessage(CurrencyConversionRequest) CreditCardInfo = _reflection.GeneratedProtocolMessageType('CreditCardInfo', (_message.Message,), dict( DESCRIPTOR = _CREDITCARDINFO, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.CreditCardInfo) )) _sym_db.RegisterMessage(CreditCardInfo) ChargeRequest = _reflection.GeneratedProtocolMessageType('ChargeRequest', (_message.Message,), dict( DESCRIPTOR = _CHARGEREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.ChargeRequest) )) _sym_db.RegisterMessage(ChargeRequest) ChargeResponse = _reflection.GeneratedProtocolMessageType('ChargeResponse', (_message.Message,), dict( DESCRIPTOR = _CHARGERESPONSE, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.ChargeResponse) )) _sym_db.RegisterMessage(ChargeResponse) OrderItem = _reflection.GeneratedProtocolMessageType('OrderItem', (_message.Message,), dict( DESCRIPTOR = _ORDERITEM, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.OrderItem) )) _sym_db.RegisterMessage(OrderItem) OrderResult = _reflection.GeneratedProtocolMessageType('OrderResult', (_message.Message,), dict( DESCRIPTOR = _ORDERRESULT, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.OrderResult) )) _sym_db.RegisterMessage(OrderResult) SendOrderConfirmationRequest = _reflection.GeneratedProtocolMessageType('SendOrderConfirmationRequest', (_message.Message,), dict( DESCRIPTOR = _SENDORDERCONFIRMATIONREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.SendOrderConfirmationRequest) )) _sym_db.RegisterMessage(SendOrderConfirmationRequest) CreateOrderRequest = _reflection.GeneratedProtocolMessageType('CreateOrderRequest', (_message.Message,), dict( DESCRIPTOR = _CREATEORDERREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.CreateOrderRequest) )) _sym_db.RegisterMessage(CreateOrderRequest) CreateOrderResponse = _reflection.GeneratedProtocolMessageType('CreateOrderResponse', (_message.Message,), dict( DESCRIPTOR = _CREATEORDERRESPONSE, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.CreateOrderResponse) )) _sym_db.RegisterMessage(CreateOrderResponse) PlaceOrderRequest = _reflection.GeneratedProtocolMessageType('PlaceOrderRequest', (_message.Message,), dict( DESCRIPTOR = _PLACEORDERREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.PlaceOrderRequest) )) _sym_db.RegisterMessage(PlaceOrderRequest) PlaceOrderResponse = _reflection.GeneratedProtocolMessageType('PlaceOrderResponse', (_message.Message,), dict( DESCRIPTOR = _PLACEORDERRESPONSE, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.PlaceOrderResponse) )) _sym_db.RegisterMessage(PlaceOrderResponse) _CARTSERVICE = _descriptor.ServiceDescriptor( name='CartService', full_name='hipstershop.CartService', file=DESCRIPTOR, index=0, options=None, serialized_start=2428, serialized_end=2630, methods=[ _descriptor.MethodDescriptor( name='AddItem', full_name='hipstershop.CartService.AddItem', index=0, containing_service=None, input_type=_ADDITEMREQUEST, output_type=_EMPTY, options=None, ), _descriptor.MethodDescriptor( name='GetCart', full_name='hipstershop.CartService.GetCart', index=1, containing_service=None, input_type=_GETCARTREQUEST, output_type=_CART, options=None, ), _descriptor.MethodDescriptor( name='EmptyCart', full_name='hipstershop.CartService.EmptyCart', index=2, containing_service=None, input_type=_EMPTYCARTREQUEST, output_type=_EMPTY, options=None, ), ]) _sym_db.RegisterServiceDescriptor(_CARTSERVICE) DESCRIPTOR.services_by_name['CartService'] = _CARTSERVICE _RECOMMENDATIONSERVICE = _descriptor.ServiceDescriptor( name='RecommendationService', full_name='hipstershop.RecommendationService', file=DESCRIPTOR, index=1, options=None, serialized_start=2633, serialized_end=2764, methods=[ _descriptor.MethodDescriptor( name='ListRecommendations', full_name='hipstershop.RecommendationService.ListRecommendations', index=0, containing_service=None, input_type=_LISTRECOMMENDATIONSREQUEST, output_type=_LISTRECOMMENDATIONSRESPONSE, options=None, ), ]) _sym_db.RegisterServiceDescriptor(_RECOMMENDATIONSERVICE) DESCRIPTOR.services_by_name['RecommendationService'] = _RECOMMENDATIONSERVICE _PRODUCTCATALOGSERVICE = _descriptor.ServiceDescriptor( name='ProductCatalogService', full_name='hipstershop.ProductCatalogService', file=DESCRIPTOR, index=2, options=None, serialized_start=2767, serialized_end=3026, methods=[ _descriptor.MethodDescriptor( name='ListProducts', full_name='hipstershop.ProductCatalogService.ListProducts', index=0, containing_service=None, input_type=_EMPTY, output_type=_LISTPRODUCTSRESPONSE, options=None, ), _descriptor.MethodDescriptor( name='GetProduct', full_name='hipstershop.ProductCatalogService.GetProduct', index=1, containing_service=None, input_type=_GETPRODUCTREQUEST, output_type=_PRODUCT, options=None, ), _descriptor.MethodDescriptor( name='SearchProducts', full_name='hipstershop.ProductCatalogService.SearchProducts', index=2, containing_service=None, input_type=_SEARCHPRODUCTSREQUEST, output_type=_SEARCHPRODUCTSRESPONSE, options=None, ), ]) _sym_db.RegisterServiceDescriptor(_PRODUCTCATALOGSERVICE) DESCRIPTOR.services_by_name['ProductCatalogService'] = _PRODUCTCATALOGSERVICE _SHIPPINGSERVICE = _descriptor.ServiceDescriptor( name='ShippingService', full_name='hipstershop.ShippingService', file=DESCRIPTOR, index=3, options=None, serialized_start=3029, serialized_end=3199, methods=[ _descriptor.MethodDescriptor( name='GetQuote', full_name='hipstershop.ShippingService.GetQuote', index=0, containing_service=None, input_type=_GETQUOTEREQUEST, output_type=_GETQUOTERESPONSE, options=None, ), _descriptor.MethodDescriptor( name='ShipOrder', full_name='hipstershop.ShippingService.ShipOrder', index=1, containing_service=None, input_type=_SHIPORDERREQUEST, output_type=_SHIPORDERRESPONSE, options=None, ), ]) _sym_db.RegisterServiceDescriptor(_SHIPPINGSERVICE) DESCRIPTOR.services_by_name['ShippingService'] = _SHIPPINGSERVICE _CURRENCYSERVICE = _descriptor.ServiceDescriptor( name='CurrencyService', full_name='hipstershop.CurrencyService', file=DESCRIPTOR, index=4, options=None, serialized_start=3202, serialized_end=3385, methods=[ _descriptor.MethodDescriptor( name='GetSupportedCurrencies', full_name='hipstershop.CurrencyService.GetSupportedCurrencies', index=0, containing_service=None, input_type=_EMPTY, output_type=_GETSUPPORTEDCURRENCIESRESPONSE, options=None, ), _descriptor.MethodDescriptor( name='Convert', full_name='hipstershop.CurrencyService.Convert', index=1, containing_service=None, input_type=_CURRENCYCONVERSIONREQUEST, output_type=_MONEY, options=None, ), ]) _sym_db.RegisterServiceDescriptor(_CURRENCYSERVICE) DESCRIPTOR.services_by_name['CurrencyService'] = _CURRENCYSERVICE _PAYMENTSERVICE = _descriptor.ServiceDescriptor( name='PaymentService', full_name='hipstershop.PaymentService', file=DESCRIPTOR, index=5, options=None, serialized_start=3387, serialized_end=3472, methods=[ _descriptor.MethodDescriptor( name='Charge', full_name='hipstershop.PaymentService.Charge', index=0, containing_service=None, input_type=_CHARGEREQUEST, output_type=_CHARGERESPONSE, options=None, ), ]) _sym_db.RegisterServiceDescriptor(_PAYMENTSERVICE) DESCRIPTOR.services_by_name['PaymentService'] = _PAYMENTSERVICE _EMAILSERVICE = _descriptor.ServiceDescriptor( name='EmailService', full_name='hipstershop.EmailService', file=DESCRIPTOR, index=6, options=None, serialized_start=3474, serialized_end=3578, methods=[ _descriptor.MethodDescriptor( name='SendOrderConfirmation', full_name='hipstershop.EmailService.SendOrderConfirmation', index=0, containing_service=None, input_type=_SENDORDERCONFIRMATIONREQUEST, output_type=_EMPTY, options=None, ), ]) _sym_db.RegisterServiceDescriptor(_EMAILSERVICE) DESCRIPTOR.services_by_name['EmailService'] = _EMAILSERVICE _CHECKOUTSERVICE = _descriptor.ServiceDescriptor( name='CheckoutService', full_name='hipstershop.CheckoutService', file=DESCRIPTOR, index=7, options=None, serialized_start=3581, serialized_end=3763, methods=[ _descriptor.MethodDescriptor( name='CreateOrder', full_name='hipstershop.CheckoutService.CreateOrder', index=0, containing_service=None, input_type=_CREATEORDERREQUEST, output_type=_CREATEORDERRESPONSE, options=None, ), _descriptor.MethodDescriptor( name='PlaceOrder', full_name='hipstershop.CheckoutService.PlaceOrder', index=1, containing_service=None, input_type=_PLACEORDERREQUEST, output_type=_PLACEORDERRESPONSE, options=None, ), ]) _sym_db.RegisterServiceDescriptor(_CHECKOUTSERVICE) DESCRIPTOR.services_by_name['CheckoutService'] = _CHECKOUTSERVICE # @@protoc_insertion_point(module_scope) ================================================ FILE: microservices-demo/src/emailservice/demo_pb2_grpc.py ================================================ #!/usr/bin/python # # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! import grpc import demo_pb2 as demo__pb2 class CartServiceStub(object): """-----------------Cart service----------------- """ def __init__(self, channel): """Constructor. Args: channel: A grpc.Channel. """ self.AddItem = channel.unary_unary( '/hipstershop.CartService/AddItem', request_serializer=demo__pb2.AddItemRequest.SerializeToString, response_deserializer=demo__pb2.Empty.FromString, ) self.GetCart = channel.unary_unary( '/hipstershop.CartService/GetCart', request_serializer=demo__pb2.GetCartRequest.SerializeToString, response_deserializer=demo__pb2.Cart.FromString, ) self.EmptyCart = channel.unary_unary( '/hipstershop.CartService/EmptyCart', request_serializer=demo__pb2.EmptyCartRequest.SerializeToString, response_deserializer=demo__pb2.Empty.FromString, ) class CartServiceServicer(object): """-----------------Cart service----------------- """ def AddItem(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def GetCart(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def EmptyCart(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def add_CartServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'AddItem': grpc.unary_unary_rpc_method_handler( servicer.AddItem, request_deserializer=demo__pb2.AddItemRequest.FromString, response_serializer=demo__pb2.Empty.SerializeToString, ), 'GetCart': grpc.unary_unary_rpc_method_handler( servicer.GetCart, request_deserializer=demo__pb2.GetCartRequest.FromString, response_serializer=demo__pb2.Cart.SerializeToString, ), 'EmptyCart': grpc.unary_unary_rpc_method_handler( servicer.EmptyCart, request_deserializer=demo__pb2.EmptyCartRequest.FromString, response_serializer=demo__pb2.Empty.SerializeToString, ), } generic_handler = grpc.method_handlers_generic_handler( 'hipstershop.CartService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) class RecommendationServiceStub(object): """---------------Recommendation service---------- """ def __init__(self, channel): """Constructor. Args: channel: A grpc.Channel. """ self.ListRecommendations = channel.unary_unary( '/hipstershop.RecommendationService/ListRecommendations', request_serializer=demo__pb2.ListRecommendationsRequest.SerializeToString, response_deserializer=demo__pb2.ListRecommendationsResponse.FromString, ) class RecommendationServiceServicer(object): """---------------Recommendation service---------- """ def ListRecommendations(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def add_RecommendationServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'ListRecommendations': grpc.unary_unary_rpc_method_handler( servicer.ListRecommendations, request_deserializer=demo__pb2.ListRecommendationsRequest.FromString, response_serializer=demo__pb2.ListRecommendationsResponse.SerializeToString, ), } generic_handler = grpc.method_handlers_generic_handler( 'hipstershop.RecommendationService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) class ProductCatalogServiceStub(object): """---------------Product Catalog---------------- """ def __init__(self, channel): """Constructor. Args: channel: A grpc.Channel. """ self.ListProducts = channel.unary_unary( '/hipstershop.ProductCatalogService/ListProducts', request_serializer=demo__pb2.Empty.SerializeToString, response_deserializer=demo__pb2.ListProductsResponse.FromString, ) self.GetProduct = channel.unary_unary( '/hipstershop.ProductCatalogService/GetProduct', request_serializer=demo__pb2.GetProductRequest.SerializeToString, response_deserializer=demo__pb2.Product.FromString, ) self.SearchProducts = channel.unary_unary( '/hipstershop.ProductCatalogService/SearchProducts', request_serializer=demo__pb2.SearchProductsRequest.SerializeToString, response_deserializer=demo__pb2.SearchProductsResponse.FromString, ) class ProductCatalogServiceServicer(object): """---------------Product Catalog---------------- """ def ListProducts(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def GetProduct(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def SearchProducts(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def add_ProductCatalogServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'ListProducts': grpc.unary_unary_rpc_method_handler( servicer.ListProducts, request_deserializer=demo__pb2.Empty.FromString, response_serializer=demo__pb2.ListProductsResponse.SerializeToString, ), 'GetProduct': grpc.unary_unary_rpc_method_handler( servicer.GetProduct, request_deserializer=demo__pb2.GetProductRequest.FromString, response_serializer=demo__pb2.Product.SerializeToString, ), 'SearchProducts': grpc.unary_unary_rpc_method_handler( servicer.SearchProducts, request_deserializer=demo__pb2.SearchProductsRequest.FromString, response_serializer=demo__pb2.SearchProductsResponse.SerializeToString, ), } generic_handler = grpc.method_handlers_generic_handler( 'hipstershop.ProductCatalogService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) class ShippingServiceStub(object): """---------------Shipping Service---------- """ def __init__(self, channel): """Constructor. Args: channel: A grpc.Channel. """ self.GetQuote = channel.unary_unary( '/hipstershop.ShippingService/GetQuote', request_serializer=demo__pb2.GetQuoteRequest.SerializeToString, response_deserializer=demo__pb2.GetQuoteResponse.FromString, ) self.ShipOrder = channel.unary_unary( '/hipstershop.ShippingService/ShipOrder', request_serializer=demo__pb2.ShipOrderRequest.SerializeToString, response_deserializer=demo__pb2.ShipOrderResponse.FromString, ) class ShippingServiceServicer(object): """---------------Shipping Service---------- """ def GetQuote(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def ShipOrder(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def add_ShippingServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'GetQuote': grpc.unary_unary_rpc_method_handler( servicer.GetQuote, request_deserializer=demo__pb2.GetQuoteRequest.FromString, response_serializer=demo__pb2.GetQuoteResponse.SerializeToString, ), 'ShipOrder': grpc.unary_unary_rpc_method_handler( servicer.ShipOrder, request_deserializer=demo__pb2.ShipOrderRequest.FromString, response_serializer=demo__pb2.ShipOrderResponse.SerializeToString, ), } generic_handler = grpc.method_handlers_generic_handler( 'hipstershop.ShippingService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) class CurrencyServiceStub(object): """-----------------Currency service----------------- """ def __init__(self, channel): """Constructor. Args: channel: A grpc.Channel. """ self.GetSupportedCurrencies = channel.unary_unary( '/hipstershop.CurrencyService/GetSupportedCurrencies', request_serializer=demo__pb2.Empty.SerializeToString, response_deserializer=demo__pb2.GetSupportedCurrenciesResponse.FromString, ) self.Convert = channel.unary_unary( '/hipstershop.CurrencyService/Convert', request_serializer=demo__pb2.CurrencyConversionRequest.SerializeToString, response_deserializer=demo__pb2.Money.FromString, ) class CurrencyServiceServicer(object): """-----------------Currency service----------------- """ def GetSupportedCurrencies(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def Convert(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def add_CurrencyServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'GetSupportedCurrencies': grpc.unary_unary_rpc_method_handler( servicer.GetSupportedCurrencies, request_deserializer=demo__pb2.Empty.FromString, response_serializer=demo__pb2.GetSupportedCurrenciesResponse.SerializeToString, ), 'Convert': grpc.unary_unary_rpc_method_handler( servicer.Convert, request_deserializer=demo__pb2.CurrencyConversionRequest.FromString, response_serializer=demo__pb2.Money.SerializeToString, ), } generic_handler = grpc.method_handlers_generic_handler( 'hipstershop.CurrencyService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) class PaymentServiceStub(object): """-------------Payment service----------------- """ def __init__(self, channel): """Constructor. Args: channel: A grpc.Channel. """ self.Charge = channel.unary_unary( '/hipstershop.PaymentService/Charge', request_serializer=demo__pb2.ChargeRequest.SerializeToString, response_deserializer=demo__pb2.ChargeResponse.FromString, ) class PaymentServiceServicer(object): """-------------Payment service----------------- """ def Charge(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def add_PaymentServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'Charge': grpc.unary_unary_rpc_method_handler( servicer.Charge, request_deserializer=demo__pb2.ChargeRequest.FromString, response_serializer=demo__pb2.ChargeResponse.SerializeToString, ), } generic_handler = grpc.method_handlers_generic_handler( 'hipstershop.PaymentService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) class EmailServiceStub(object): """-------------Email service----------------- """ def __init__(self, channel): """Constructor. Args: channel: A grpc.Channel. """ self.SendOrderConfirmation = channel.unary_unary( '/hipstershop.EmailService/SendOrderConfirmation', request_serializer=demo__pb2.SendOrderConfirmationRequest.SerializeToString, response_deserializer=demo__pb2.Empty.FromString, ) class EmailServiceServicer(object): """-------------Email service----------------- """ def SendOrderConfirmation(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def add_EmailServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'SendOrderConfirmation': grpc.unary_unary_rpc_method_handler( servicer.SendOrderConfirmation, request_deserializer=demo__pb2.SendOrderConfirmationRequest.FromString, response_serializer=demo__pb2.Empty.SerializeToString, ), } generic_handler = grpc.method_handlers_generic_handler( 'hipstershop.EmailService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) class CheckoutServiceStub(object): """-------------Checkout service----------------- """ def __init__(self, channel): """Constructor. Args: channel: A grpc.Channel. """ self.CreateOrder = channel.unary_unary( '/hipstershop.CheckoutService/CreateOrder', request_serializer=demo__pb2.CreateOrderRequest.SerializeToString, response_deserializer=demo__pb2.CreateOrderResponse.FromString, ) self.PlaceOrder = channel.unary_unary( '/hipstershop.CheckoutService/PlaceOrder', request_serializer=demo__pb2.PlaceOrderRequest.SerializeToString, response_deserializer=demo__pb2.PlaceOrderResponse.FromString, ) class CheckoutServiceServicer(object): """-------------Checkout service----------------- """ def CreateOrder(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def PlaceOrder(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def add_CheckoutServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'CreateOrder': grpc.unary_unary_rpc_method_handler( servicer.CreateOrder, request_deserializer=demo__pb2.CreateOrderRequest.FromString, response_serializer=demo__pb2.CreateOrderResponse.SerializeToString, ), 'PlaceOrder': grpc.unary_unary_rpc_method_handler( servicer.PlaceOrder, request_deserializer=demo__pb2.PlaceOrderRequest.FromString, response_serializer=demo__pb2.PlaceOrderResponse.SerializeToString, ), } generic_handler = grpc.method_handlers_generic_handler( 'hipstershop.CheckoutService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) ================================================ FILE: microservices-demo/src/emailservice/email_client.py ================================================ #!/usr/bin/python # # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import grpc import demo_pb2 import demo_pb2_grpc from logger import getJSONLogger logger = getJSONLogger('emailservice-client') from opencensus.trace.tracer import Tracer from opencensus.trace.exporters import stackdriver_exporter from opencensus.trace.ext.grpc import client_interceptor try: exporter = stackdriver_exporter.StackdriverExporter() tracer = Tracer(exporter=exporter) tracer_interceptor = client_interceptor.OpenCensusClientInterceptor(tracer, host_port='0.0.0.0:8080') except: tracer_interceptor = client_interceptor.OpenCensusClientInterceptor() def send_confirmation_email(email, order): channel = grpc.insecure_channel('0.0.0.0:8080') channel = grpc.intercept_channel(channel, tracer_interceptor) stub = demo_pb2_grpc.EmailServiceStub(channel) try: response = stub.SendOrderConfirmation(demo_pb2.SendOrderConfirmationRequest( email = email, order = order )) logger.info('Request sent.') except grpc.RpcError as err: logger.error(err.details()) logger.error('{}, {}'.format(err.code().name, err.code().value)) if __name__ == '__main__': logger.info('Client for email service.') ================================================ FILE: microservices-demo/src/emailservice/email_server.py ================================================ #!/usr/bin/python # # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from concurrent import futures import argparse import os import sys import time import grpc import traceback from jinja2 import Environment, FileSystemLoader, select_autoescape, TemplateError from google.api_core.exceptions import GoogleAPICallError from google.auth.exceptions import DefaultCredentialsError import demo_pb2 import demo_pb2_grpc from grpc_health.v1 import health_pb2 from grpc_health.v1 import health_pb2_grpc from opencensus.ext.stackdriver import trace_exporter as stackdriver_exporter from opencensus.ext.grpc import server_interceptor from opencensus.common.transports.async_ import AsyncTransport from opencensus.trace import samplers # import googleclouddebugger import googlecloudprofiler from logger import getJSONLogger logger = getJSONLogger('emailservice-server') # try: # googleclouddebugger.enable( # module='emailserver', # version='1.0.0' # ) # except: # pass # Loads confirmation email template from file env = Environment( loader=FileSystemLoader('templates'), autoescape=select_autoescape(['html', 'xml']) ) template = env.get_template('confirmation.html') class BaseEmailService(demo_pb2_grpc.EmailServiceServicer): def Check(self, request, context): return health_pb2.HealthCheckResponse( status=health_pb2.HealthCheckResponse.SERVING) def Watch(self, request, context): return health_pb2.HealthCheckResponse( status=health_pb2.HealthCheckResponse.UNIMPLEMENTED) class EmailService(BaseEmailService): def __init__(self): raise Exception('cloud mail client not implemented') super().__init__() @staticmethod def send_email(client, email_address, content): response = client.send_message( sender = client.sender_path(project_id, region, sender_id), envelope_from_authority = '', header_from_authority = '', envelope_from_address = from_address, simple_message = { "from": { "address_spec": from_address, }, "to": [{ "address_spec": email_address }], "subject": "Your Confirmation Email", "html_body": content } ) logger.info("Message sent: {}".format(response.rfc822_message_id)) def SendOrderConfirmation(self, request, context): email = request.email order = request.order try: confirmation = template.render(order = order) except TemplateError as err: context.set_details("An error occurred when preparing the confirmation mail.") logger.error(err.message) context.set_code(grpc.StatusCode.INTERNAL) return demo_pb2.Empty() try: EmailService.send_email(self.client, email, confirmation) except GoogleAPICallError as err: context.set_details("An error occurred when sending the email.") print(err.message) context.set_code(grpc.StatusCode.INTERNAL) return demo_pb2.Empty() return demo_pb2.Empty() class DummyEmailService(BaseEmailService): def SendOrderConfirmation(self, request, context): logger.info('A request to send order confirmation email to {} has been received.'.format(request.email)) return demo_pb2.Empty() class HealthCheck(): def Check(self, request, context): return health_pb2.HealthCheckResponse( status=health_pb2.HealthCheckResponse.SERVING) def start(dummy_mode): server = grpc.server(futures.ThreadPoolExecutor(max_workers=10), interceptors=(tracer_interceptor,)) service = None if dummy_mode: service = DummyEmailService() else: raise Exception('non-dummy mode not implemented yet') demo_pb2_grpc.add_EmailServiceServicer_to_server(service, server) health_pb2_grpc.add_HealthServicer_to_server(service, server) port = os.environ.get('PORT', "8080") logger.info("listening on port: "+port) server.add_insecure_port('[::]:'+port) server.start() try: while True: time.sleep(3600) except KeyboardInterrupt: server.stop(0) def initStackdriverProfiling(): project_id = None try: project_id = os.environ["GCP_PROJECT_ID"] except KeyError: # Environment variable not set pass for retry in range(1,4): try: if project_id: googlecloudprofiler.start(service='email_server', service_version='1.0.0', verbose=0, project_id=project_id) else: googlecloudprofiler.start(service='email_server', service_version='1.0.0', verbose=0) logger.info("Successfully started Stackdriver Profiler.") return except (BaseException) as exc: logger.info("Unable to start Stackdriver Profiler Python agent. " + str(exc)) if (retry < 4): logger.info("Sleeping %d to retry initializing Stackdriver Profiler"%(retry*10)) time.sleep (1) else: logger.warning("Could not initialize Stackdriver Profiler after retrying, giving up") return if __name__ == '__main__': logger.info('starting the email service in dummy mode.') # Profiler try: if "DISABLE_PROFILER" in os.environ: raise KeyError() else: logger.info("Profiler enabled.") initStackdriverProfiling() except KeyError: logger.info("Profiler disabled.") # Tracing try: if "DISABLE_TRACING" in os.environ: raise KeyError() else: logger.info("Tracing enabled.") sampler = samplers.AlwaysOnSampler() exporter = stackdriver_exporter.StackdriverExporter( project_id=os.environ.get('GCP_PROJECT_ID'), transport=AsyncTransport) tracer_interceptor = server_interceptor.OpenCensusServerInterceptor(sampler, exporter) except (KeyError, DefaultCredentialsError): logger.info("Tracing disabled.") tracer_interceptor = server_interceptor.OpenCensusServerInterceptor() except Exception as e: logger.warn(f"Exception on Cloud Trace setup: {traceback.format_exc()}, tracing disabled.") tracer_interceptor = server_interceptor.OpenCensusServerInterceptor() start(dummy_mode = True) ================================================ FILE: microservices-demo/src/emailservice/genproto.sh ================================================ #!/bin/bash -eu # # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # [START gke_emailservice_genproto] python -m grpc_tools.protoc -I../../pb --python_out=. --grpc_python_out=. ../../pb/demo.proto # [END gke_emailservice_genproto] ================================================ FILE: microservices-demo/src/emailservice/logger.py ================================================ #!/usr/bin/python # # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import logging import sys from pythonjsonlogger import jsonlogger # TODO(yoshifumi) this class is duplicated since other Python services are # not sharing the modules for logging. class CustomJsonFormatter(jsonlogger.JsonFormatter): def add_fields(self, log_record, record, message_dict): super(CustomJsonFormatter, self).add_fields(log_record, record, message_dict) if not log_record.get('timestamp'): log_record['timestamp'] = record.created if log_record.get('severity'): log_record['severity'] = log_record['severity'].upper() else: log_record['severity'] = record.levelname def getJSONLogger(name): logger = logging.getLogger(name) handler = logging.StreamHandler(sys.stdout) formatter = CustomJsonFormatter('(timestamp) (severity) (name) (message)') handler.setFormatter(formatter) logger.addHandler(handler) logger.setLevel(logging.INFO) logger.propagate = False return logger ================================================ FILE: microservices-demo/src/emailservice/pytest.ini ================================================ [pytest] testpaths = tests console_output_style = classic ================================================ FILE: microservices-demo/src/emailservice/requirements.in ================================================ google-api-core==2.8.2 grpcio-health-checking==1.47.0 grpcio==1.47.0 jinja2==3.1.2 opencensus==0.9.0 opencensus-ext-stackdriver==0.8.0 opencensus-ext-grpc==0.7.2 python-json-logger==2.0.4 google-cloud-profiler==4.0.0 google-cloud-trace==0.24.2 requests==2.28.1 protobuf==3.20.1 # transitive dependency, move when google-api is bumped safely pytest==7.1.3 ================================================ FILE: microservices-demo/src/emailservice/requirements.txt ================================================ # # This file is autogenerated by pip-compile with python 3.10 # To update, run: # # pip-compile --output-file=requirements.txt requirements.in # attrs==22.1.0 # via pytest cachetools==5.2.0 # via google-auth certifi==2022.6.15 # via requests charset-normalizer==2.1.1 # via requests google-api-core[grpc]==2.8.2 # via # -r requirements.in # google-api-python-client # google-cloud-core # google-cloud-monitoring # google-cloud-trace # opencensus google-api-python-client==2.58.0 # via google-cloud-profiler google-auth==2.11.0 # via # google-api-core # google-api-python-client # google-auth-httplib2 # google-cloud-core # google-cloud-profiler google-auth-httplib2==0.1.0 # via # google-api-python-client # google-cloud-profiler google-cloud-core==2.3.2 # via google-cloud-trace google-cloud-monitoring==2.11.1 # via opencensus-ext-stackdriver google-cloud-profiler==4.0.0 # via -r requirements.in google-cloud-trace==0.24.2 # via # -r requirements.in # opencensus-ext-stackdriver googleapis-common-protos==1.56.4 # via # google-api-core # grpcio-status grpcio==1.47.0 # via # -r requirements.in # google-api-core # grpcio-health-checking # grpcio-status # opencensus-ext-grpc grpcio-health-checking==1.47.0 # via -r requirements.in grpcio-status==1.47.0 # via google-api-core httplib2==0.20.4 # via # google-api-python-client # google-auth-httplib2 idna==2.10 # via requests iniconfig==1.1.1 # via pytest jinja2==3.1.2 # via -r requirements.in markupsafe==2.1.1 # via jinja2 opencensus==0.9.0 # via # -r requirements.in # opencensus-ext-grpc # opencensus-ext-stackdriver opencensus-context==0.1.3 # via opencensus opencensus-ext-grpc==0.7.2 # via -r requirements.in opencensus-ext-stackdriver==0.8.0 # via -r requirements.in packaging==21.3 # via pytest pluggy==1.0.0 # via pytest proto-plus==1.22.1 # via google-cloud-monitoring protobuf==3.20.1 # via # -r requirements.in # google-api-core # google-cloud-monitoring # google-cloud-profiler # google-cloud-trace # googleapis-common-protos # grpcio-health-checking # grpcio-status # proto-plus py==1.11.0 # via pytest pyasn1==0.4.8 # via # pyasn1-modules # rsa pyasn1-modules==0.2.8 # via google-auth pyparsing==2.4.7 # via # httplib2 # packaging pytest==7.1.3 # via -r requirements.in python-json-logger==2.0.4 # via -r requirements.in requests==2.28.1 # via # -r requirements.in # google-api-core # google-cloud-profiler rsa==4.8 # via google-auth six==1.16.0 # via # google-auth # google-auth-httplib2 # grpcio tomli==2.0.1 # via pytest uritemplate==3.0.1 # via google-api-python-client urllib3==1.26.12 # via requests ================================================ FILE: microservices-demo/src/emailservice/templates/confirmation.html ================================================ Your Order Confirmation

Your Order Confirmation

Thanks for shopping with us!

Order ID

#{{ order.order_id }}

Shipping

#{{ order.shipping_tracking_id }}

{{ order.shipping_cost.units }}. {{ "%02d" | format(order.shipping_cost.nanos // 10000000) }} {{ order.shipping_cost.currency_code }}

{{ order.shipping_address.street_address_1 }}, {{order.shipping_address.street_address_2}}, {{order.shipping_address.city}}, {{order.shipping_address.country}} {{order.shipping_address.zip_code}}

Items

{% for item in order.items %} {% endfor %}
Item No. Quantity Price
#{{ item.item.product_id }} {{ item.item.quantity }} {{ item.cost.units }}.{{ "%02d" | format(item.cost.nanos // 10000000) }} {{ item.cost.currency_code }}
================================================ FILE: microservices-demo/src/emailservice/tests/test_sample.py ================================================ def func(x): return x + 1 def test_answer(): assert func(3) == 4 ================================================ FILE: microservices-demo/src/frontend/.dockerignore ================================================ vendor/ ================================================ FILE: microservices-demo/src/frontend/.gitkeep ================================================ ================================================ FILE: microservices-demo/src/frontend/Dockerfile ================================================ # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. FROM golang:1.18.4-alpine as builder RUN apk add --no-cache ca-certificates git RUN apk add build-base WORKDIR /src # restore dependencies COPY go.mod go.sum ./ RUN go mod download COPY . . # Skaffold passes in debug-oriented compiler flags ARG SKAFFOLD_GO_GCFLAGS RUN go build -gcflags="${SKAFFOLD_GO_GCFLAGS}" -o /go/bin/frontend . FROM alpine as release RUN apk add --no-cache ca-certificates \ busybox-extras net-tools bind-tools WORKDIR /src COPY --from=builder /go/bin/frontend /src/server COPY ./templates ./templates COPY ./static ./static # Definition of this variable is used by 'skaffold debug' to identify a golang binary. # Default behavior - a failure prints a stack trace for the current goroutine. # See https://golang.org/pkg/runtime/ ENV GOTRACEBACK=single EXPOSE 8080 ENTRYPOINT ["/src/server"] ================================================ FILE: microservices-demo/src/frontend/README.md ================================================ # frontend Run the following command to restore dependencies to `vendor/` directory: dep ensure --vendor-only ================================================ FILE: microservices-demo/src/frontend/deployment_details.go ================================================ package main import ( "net/http" "os" "time" "cloud.google.com/go/compute/metadata" "github.com/sirupsen/logrus" ) var deploymentDetailsMap map[string]string var log *logrus.Logger func init() { initializeLogger() // Use a goroutine to ensure loadDeploymentDetails()'s GCP API // calls don't block non-GCP deployments. See issue #685. go loadDeploymentDetails() } func initializeLogger() { log = logrus.New() log.Level = logrus.DebugLevel log.Formatter = &logrus.JSONFormatter{ FieldMap: logrus.FieldMap{ logrus.FieldKeyTime: "timestamp", logrus.FieldKeyLevel: "severity", logrus.FieldKeyMsg: "message", }, TimestampFormat: time.RFC3339Nano, } log.Out = os.Stdout } func loadDeploymentDetails() { deploymentDetailsMap = make(map[string]string) var metaServerClient = metadata.NewClient(&http.Client{}) podHostname, err := os.Hostname() if err != nil { log.Error("Failed to fetch the hostname for the Pod", err) } podCluster, err := metaServerClient.InstanceAttributeValue("cluster-name") if err != nil { log.Error("Failed to fetch the name of the cluster in which the pod is running", err) } podZone, err := metaServerClient.Zone() if err != nil { log.Error("Failed to fetch the Zone of the node where the pod is scheduled", err) } deploymentDetailsMap["HOSTNAME"] = podHostname deploymentDetailsMap["CLUSTERNAME"] = podCluster deploymentDetailsMap["ZONE"] = podZone log.WithFields(logrus.Fields{ "cluster": podCluster, "zone": podZone, "hostname": podHostname, }).Debug("Loaded deployment details") } ================================================ FILE: microservices-demo/src/frontend/genproto/demo.pb.go ================================================ // Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go. DO NOT EDIT. // source: demo.proto package hipstershop import ( fmt "fmt" proto "github.com/golang/protobuf/proto" math "math" ) import ( context "golang.org/x/net/context" grpc "google.golang.org/grpc" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package type CartItem struct { ProductId string `protobuf:"bytes,1,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` Quantity int32 `protobuf:"varint,2,opt,name=quantity,proto3" json:"quantity,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *CartItem) Reset() { *m = CartItem{} } func (m *CartItem) String() string { return proto.CompactTextString(m) } func (*CartItem) ProtoMessage() {} func (*CartItem) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{0} } func (m *CartItem) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CartItem.Unmarshal(m, b) } func (m *CartItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CartItem.Marshal(b, m, deterministic) } func (m *CartItem) XXX_Merge(src proto.Message) { xxx_messageInfo_CartItem.Merge(m, src) } func (m *CartItem) XXX_Size() int { return xxx_messageInfo_CartItem.Size(m) } func (m *CartItem) XXX_DiscardUnknown() { xxx_messageInfo_CartItem.DiscardUnknown(m) } var xxx_messageInfo_CartItem proto.InternalMessageInfo func (m *CartItem) GetProductId() string { if m != nil { return m.ProductId } return "" } func (m *CartItem) GetQuantity() int32 { if m != nil { return m.Quantity } return 0 } type AddItemRequest struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` Item *CartItem `protobuf:"bytes,2,opt,name=item,proto3" json:"item,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *AddItemRequest) Reset() { *m = AddItemRequest{} } func (m *AddItemRequest) String() string { return proto.CompactTextString(m) } func (*AddItemRequest) ProtoMessage() {} func (*AddItemRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{1} } func (m *AddItemRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AddItemRequest.Unmarshal(m, b) } func (m *AddItemRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_AddItemRequest.Marshal(b, m, deterministic) } func (m *AddItemRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_AddItemRequest.Merge(m, src) } func (m *AddItemRequest) XXX_Size() int { return xxx_messageInfo_AddItemRequest.Size(m) } func (m *AddItemRequest) XXX_DiscardUnknown() { xxx_messageInfo_AddItemRequest.DiscardUnknown(m) } var xxx_messageInfo_AddItemRequest proto.InternalMessageInfo func (m *AddItemRequest) GetUserId() string { if m != nil { return m.UserId } return "" } func (m *AddItemRequest) GetItem() *CartItem { if m != nil { return m.Item } return nil } type EmptyCartRequest struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *EmptyCartRequest) Reset() { *m = EmptyCartRequest{} } func (m *EmptyCartRequest) String() string { return proto.CompactTextString(m) } func (*EmptyCartRequest) ProtoMessage() {} func (*EmptyCartRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{2} } func (m *EmptyCartRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_EmptyCartRequest.Unmarshal(m, b) } func (m *EmptyCartRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_EmptyCartRequest.Marshal(b, m, deterministic) } func (m *EmptyCartRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_EmptyCartRequest.Merge(m, src) } func (m *EmptyCartRequest) XXX_Size() int { return xxx_messageInfo_EmptyCartRequest.Size(m) } func (m *EmptyCartRequest) XXX_DiscardUnknown() { xxx_messageInfo_EmptyCartRequest.DiscardUnknown(m) } var xxx_messageInfo_EmptyCartRequest proto.InternalMessageInfo func (m *EmptyCartRequest) GetUserId() string { if m != nil { return m.UserId } return "" } type GetCartRequest struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *GetCartRequest) Reset() { *m = GetCartRequest{} } func (m *GetCartRequest) String() string { return proto.CompactTextString(m) } func (*GetCartRequest) ProtoMessage() {} func (*GetCartRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{3} } func (m *GetCartRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetCartRequest.Unmarshal(m, b) } func (m *GetCartRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetCartRequest.Marshal(b, m, deterministic) } func (m *GetCartRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_GetCartRequest.Merge(m, src) } func (m *GetCartRequest) XXX_Size() int { return xxx_messageInfo_GetCartRequest.Size(m) } func (m *GetCartRequest) XXX_DiscardUnknown() { xxx_messageInfo_GetCartRequest.DiscardUnknown(m) } var xxx_messageInfo_GetCartRequest proto.InternalMessageInfo func (m *GetCartRequest) GetUserId() string { if m != nil { return m.UserId } return "" } type Cart struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Cart) Reset() { *m = Cart{} } func (m *Cart) String() string { return proto.CompactTextString(m) } func (*Cart) ProtoMessage() {} func (*Cart) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{4} } func (m *Cart) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Cart.Unmarshal(m, b) } func (m *Cart) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Cart.Marshal(b, m, deterministic) } func (m *Cart) XXX_Merge(src proto.Message) { xxx_messageInfo_Cart.Merge(m, src) } func (m *Cart) XXX_Size() int { return xxx_messageInfo_Cart.Size(m) } func (m *Cart) XXX_DiscardUnknown() { xxx_messageInfo_Cart.DiscardUnknown(m) } var xxx_messageInfo_Cart proto.InternalMessageInfo func (m *Cart) GetUserId() string { if m != nil { return m.UserId } return "" } func (m *Cart) GetItems() []*CartItem { if m != nil { return m.Items } return nil } type Empty struct { XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Empty) Reset() { *m = Empty{} } func (m *Empty) String() string { return proto.CompactTextString(m) } func (*Empty) ProtoMessage() {} func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{5} } func (m *Empty) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Empty.Unmarshal(m, b) } func (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Empty.Marshal(b, m, deterministic) } func (m *Empty) XXX_Merge(src proto.Message) { xxx_messageInfo_Empty.Merge(m, src) } func (m *Empty) XXX_Size() int { return xxx_messageInfo_Empty.Size(m) } func (m *Empty) XXX_DiscardUnknown() { xxx_messageInfo_Empty.DiscardUnknown(m) } var xxx_messageInfo_Empty proto.InternalMessageInfo type ListRecommendationsRequest struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` ProductIds []string `protobuf:"bytes,2,rep,name=product_ids,json=productIds,proto3" json:"product_ids,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ListRecommendationsRequest) Reset() { *m = ListRecommendationsRequest{} } func (m *ListRecommendationsRequest) String() string { return proto.CompactTextString(m) } func (*ListRecommendationsRequest) ProtoMessage() {} func (*ListRecommendationsRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{6} } func (m *ListRecommendationsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ListRecommendationsRequest.Unmarshal(m, b) } func (m *ListRecommendationsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ListRecommendationsRequest.Marshal(b, m, deterministic) } func (m *ListRecommendationsRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_ListRecommendationsRequest.Merge(m, src) } func (m *ListRecommendationsRequest) XXX_Size() int { return xxx_messageInfo_ListRecommendationsRequest.Size(m) } func (m *ListRecommendationsRequest) XXX_DiscardUnknown() { xxx_messageInfo_ListRecommendationsRequest.DiscardUnknown(m) } var xxx_messageInfo_ListRecommendationsRequest proto.InternalMessageInfo func (m *ListRecommendationsRequest) GetUserId() string { if m != nil { return m.UserId } return "" } func (m *ListRecommendationsRequest) GetProductIds() []string { if m != nil { return m.ProductIds } return nil } type ListRecommendationsResponse struct { ProductIds []string `protobuf:"bytes,1,rep,name=product_ids,json=productIds,proto3" json:"product_ids,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ListRecommendationsResponse) Reset() { *m = ListRecommendationsResponse{} } func (m *ListRecommendationsResponse) String() string { return proto.CompactTextString(m) } func (*ListRecommendationsResponse) ProtoMessage() {} func (*ListRecommendationsResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{7} } func (m *ListRecommendationsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ListRecommendationsResponse.Unmarshal(m, b) } func (m *ListRecommendationsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ListRecommendationsResponse.Marshal(b, m, deterministic) } func (m *ListRecommendationsResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_ListRecommendationsResponse.Merge(m, src) } func (m *ListRecommendationsResponse) XXX_Size() int { return xxx_messageInfo_ListRecommendationsResponse.Size(m) } func (m *ListRecommendationsResponse) XXX_DiscardUnknown() { xxx_messageInfo_ListRecommendationsResponse.DiscardUnknown(m) } var xxx_messageInfo_ListRecommendationsResponse proto.InternalMessageInfo func (m *ListRecommendationsResponse) GetProductIds() []string { if m != nil { return m.ProductIds } return nil } type Product struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` Picture string `protobuf:"bytes,4,opt,name=picture,proto3" json:"picture,omitempty"` PriceUsd *Money `protobuf:"bytes,5,opt,name=price_usd,json=priceUsd,proto3" json:"price_usd,omitempty"` // Categories such as "clothing" or "kitchen" that can be used to look up // other related products. Categories []string `protobuf:"bytes,6,rep,name=categories,proto3" json:"categories,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Product) Reset() { *m = Product{} } func (m *Product) String() string { return proto.CompactTextString(m) } func (*Product) ProtoMessage() {} func (*Product) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{8} } func (m *Product) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Product.Unmarshal(m, b) } func (m *Product) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Product.Marshal(b, m, deterministic) } func (m *Product) XXX_Merge(src proto.Message) { xxx_messageInfo_Product.Merge(m, src) } func (m *Product) XXX_Size() int { return xxx_messageInfo_Product.Size(m) } func (m *Product) XXX_DiscardUnknown() { xxx_messageInfo_Product.DiscardUnknown(m) } var xxx_messageInfo_Product proto.InternalMessageInfo func (m *Product) GetId() string { if m != nil { return m.Id } return "" } func (m *Product) GetName() string { if m != nil { return m.Name } return "" } func (m *Product) GetDescription() string { if m != nil { return m.Description } return "" } func (m *Product) GetPicture() string { if m != nil { return m.Picture } return "" } func (m *Product) GetPriceUsd() *Money { if m != nil { return m.PriceUsd } return nil } func (m *Product) GetCategories() []string { if m != nil { return m.Categories } return nil } type ListProductsResponse struct { Products []*Product `protobuf:"bytes,1,rep,name=products,proto3" json:"products,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ListProductsResponse) Reset() { *m = ListProductsResponse{} } func (m *ListProductsResponse) String() string { return proto.CompactTextString(m) } func (*ListProductsResponse) ProtoMessage() {} func (*ListProductsResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{9} } func (m *ListProductsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ListProductsResponse.Unmarshal(m, b) } func (m *ListProductsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ListProductsResponse.Marshal(b, m, deterministic) } func (m *ListProductsResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_ListProductsResponse.Merge(m, src) } func (m *ListProductsResponse) XXX_Size() int { return xxx_messageInfo_ListProductsResponse.Size(m) } func (m *ListProductsResponse) XXX_DiscardUnknown() { xxx_messageInfo_ListProductsResponse.DiscardUnknown(m) } var xxx_messageInfo_ListProductsResponse proto.InternalMessageInfo func (m *ListProductsResponse) GetProducts() []*Product { if m != nil { return m.Products } return nil } type GetProductRequest struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *GetProductRequest) Reset() { *m = GetProductRequest{} } func (m *GetProductRequest) String() string { return proto.CompactTextString(m) } func (*GetProductRequest) ProtoMessage() {} func (*GetProductRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{10} } func (m *GetProductRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetProductRequest.Unmarshal(m, b) } func (m *GetProductRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetProductRequest.Marshal(b, m, deterministic) } func (m *GetProductRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_GetProductRequest.Merge(m, src) } func (m *GetProductRequest) XXX_Size() int { return xxx_messageInfo_GetProductRequest.Size(m) } func (m *GetProductRequest) XXX_DiscardUnknown() { xxx_messageInfo_GetProductRequest.DiscardUnknown(m) } var xxx_messageInfo_GetProductRequest proto.InternalMessageInfo func (m *GetProductRequest) GetId() string { if m != nil { return m.Id } return "" } type SearchProductsRequest struct { Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *SearchProductsRequest) Reset() { *m = SearchProductsRequest{} } func (m *SearchProductsRequest) String() string { return proto.CompactTextString(m) } func (*SearchProductsRequest) ProtoMessage() {} func (*SearchProductsRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{11} } func (m *SearchProductsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SearchProductsRequest.Unmarshal(m, b) } func (m *SearchProductsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SearchProductsRequest.Marshal(b, m, deterministic) } func (m *SearchProductsRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_SearchProductsRequest.Merge(m, src) } func (m *SearchProductsRequest) XXX_Size() int { return xxx_messageInfo_SearchProductsRequest.Size(m) } func (m *SearchProductsRequest) XXX_DiscardUnknown() { xxx_messageInfo_SearchProductsRequest.DiscardUnknown(m) } var xxx_messageInfo_SearchProductsRequest proto.InternalMessageInfo func (m *SearchProductsRequest) GetQuery() string { if m != nil { return m.Query } return "" } type SearchProductsResponse struct { Results []*Product `protobuf:"bytes,1,rep,name=results,proto3" json:"results,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *SearchProductsResponse) Reset() { *m = SearchProductsResponse{} } func (m *SearchProductsResponse) String() string { return proto.CompactTextString(m) } func (*SearchProductsResponse) ProtoMessage() {} func (*SearchProductsResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{12} } func (m *SearchProductsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SearchProductsResponse.Unmarshal(m, b) } func (m *SearchProductsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SearchProductsResponse.Marshal(b, m, deterministic) } func (m *SearchProductsResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_SearchProductsResponse.Merge(m, src) } func (m *SearchProductsResponse) XXX_Size() int { return xxx_messageInfo_SearchProductsResponse.Size(m) } func (m *SearchProductsResponse) XXX_DiscardUnknown() { xxx_messageInfo_SearchProductsResponse.DiscardUnknown(m) } var xxx_messageInfo_SearchProductsResponse proto.InternalMessageInfo func (m *SearchProductsResponse) GetResults() []*Product { if m != nil { return m.Results } return nil } type GetQuoteRequest struct { Address *Address `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *GetQuoteRequest) Reset() { *m = GetQuoteRequest{} } func (m *GetQuoteRequest) String() string { return proto.CompactTextString(m) } func (*GetQuoteRequest) ProtoMessage() {} func (*GetQuoteRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{13} } func (m *GetQuoteRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetQuoteRequest.Unmarshal(m, b) } func (m *GetQuoteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetQuoteRequest.Marshal(b, m, deterministic) } func (m *GetQuoteRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_GetQuoteRequest.Merge(m, src) } func (m *GetQuoteRequest) XXX_Size() int { return xxx_messageInfo_GetQuoteRequest.Size(m) } func (m *GetQuoteRequest) XXX_DiscardUnknown() { xxx_messageInfo_GetQuoteRequest.DiscardUnknown(m) } var xxx_messageInfo_GetQuoteRequest proto.InternalMessageInfo func (m *GetQuoteRequest) GetAddress() *Address { if m != nil { return m.Address } return nil } func (m *GetQuoteRequest) GetItems() []*CartItem { if m != nil { return m.Items } return nil } type GetQuoteResponse struct { CostUsd *Money `protobuf:"bytes,1,opt,name=cost_usd,json=costUsd,proto3" json:"cost_usd,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *GetQuoteResponse) Reset() { *m = GetQuoteResponse{} } func (m *GetQuoteResponse) String() string { return proto.CompactTextString(m) } func (*GetQuoteResponse) ProtoMessage() {} func (*GetQuoteResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{14} } func (m *GetQuoteResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetQuoteResponse.Unmarshal(m, b) } func (m *GetQuoteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetQuoteResponse.Marshal(b, m, deterministic) } func (m *GetQuoteResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_GetQuoteResponse.Merge(m, src) } func (m *GetQuoteResponse) XXX_Size() int { return xxx_messageInfo_GetQuoteResponse.Size(m) } func (m *GetQuoteResponse) XXX_DiscardUnknown() { xxx_messageInfo_GetQuoteResponse.DiscardUnknown(m) } var xxx_messageInfo_GetQuoteResponse proto.InternalMessageInfo func (m *GetQuoteResponse) GetCostUsd() *Money { if m != nil { return m.CostUsd } return nil } type ShipOrderRequest struct { Address *Address `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ShipOrderRequest) Reset() { *m = ShipOrderRequest{} } func (m *ShipOrderRequest) String() string { return proto.CompactTextString(m) } func (*ShipOrderRequest) ProtoMessage() {} func (*ShipOrderRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{15} } func (m *ShipOrderRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ShipOrderRequest.Unmarshal(m, b) } func (m *ShipOrderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ShipOrderRequest.Marshal(b, m, deterministic) } func (m *ShipOrderRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_ShipOrderRequest.Merge(m, src) } func (m *ShipOrderRequest) XXX_Size() int { return xxx_messageInfo_ShipOrderRequest.Size(m) } func (m *ShipOrderRequest) XXX_DiscardUnknown() { xxx_messageInfo_ShipOrderRequest.DiscardUnknown(m) } var xxx_messageInfo_ShipOrderRequest proto.InternalMessageInfo func (m *ShipOrderRequest) GetAddress() *Address { if m != nil { return m.Address } return nil } func (m *ShipOrderRequest) GetItems() []*CartItem { if m != nil { return m.Items } return nil } type ShipOrderResponse struct { TrackingId string `protobuf:"bytes,1,opt,name=tracking_id,json=trackingId,proto3" json:"tracking_id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ShipOrderResponse) Reset() { *m = ShipOrderResponse{} } func (m *ShipOrderResponse) String() string { return proto.CompactTextString(m) } func (*ShipOrderResponse) ProtoMessage() {} func (*ShipOrderResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{16} } func (m *ShipOrderResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ShipOrderResponse.Unmarshal(m, b) } func (m *ShipOrderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ShipOrderResponse.Marshal(b, m, deterministic) } func (m *ShipOrderResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_ShipOrderResponse.Merge(m, src) } func (m *ShipOrderResponse) XXX_Size() int { return xxx_messageInfo_ShipOrderResponse.Size(m) } func (m *ShipOrderResponse) XXX_DiscardUnknown() { xxx_messageInfo_ShipOrderResponse.DiscardUnknown(m) } var xxx_messageInfo_ShipOrderResponse proto.InternalMessageInfo func (m *ShipOrderResponse) GetTrackingId() string { if m != nil { return m.TrackingId } return "" } type Address struct { StreetAddress string `protobuf:"bytes,1,opt,name=street_address,json=streetAddress,proto3" json:"street_address,omitempty"` City string `protobuf:"bytes,2,opt,name=city,proto3" json:"city,omitempty"` State string `protobuf:"bytes,3,opt,name=state,proto3" json:"state,omitempty"` Country string `protobuf:"bytes,4,opt,name=country,proto3" json:"country,omitempty"` ZipCode int32 `protobuf:"varint,5,opt,name=zip_code,json=zipCode,proto3" json:"zip_code,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Address) Reset() { *m = Address{} } func (m *Address) String() string { return proto.CompactTextString(m) } func (*Address) ProtoMessage() {} func (*Address) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{17} } func (m *Address) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Address.Unmarshal(m, b) } func (m *Address) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Address.Marshal(b, m, deterministic) } func (m *Address) XXX_Merge(src proto.Message) { xxx_messageInfo_Address.Merge(m, src) } func (m *Address) XXX_Size() int { return xxx_messageInfo_Address.Size(m) } func (m *Address) XXX_DiscardUnknown() { xxx_messageInfo_Address.DiscardUnknown(m) } var xxx_messageInfo_Address proto.InternalMessageInfo func (m *Address) GetStreetAddress() string { if m != nil { return m.StreetAddress } return "" } func (m *Address) GetCity() string { if m != nil { return m.City } return "" } func (m *Address) GetState() string { if m != nil { return m.State } return "" } func (m *Address) GetCountry() string { if m != nil { return m.Country } return "" } func (m *Address) GetZipCode() int32 { if m != nil { return m.ZipCode } return 0 } // Represents an amount of money with its currency type. type Money struct { // The 3-letter currency code defined in ISO 4217. CurrencyCode string `protobuf:"bytes,1,opt,name=currency_code,json=currencyCode,proto3" json:"currency_code,omitempty"` // The whole units of the amount. // For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar. Units int64 `protobuf:"varint,2,opt,name=units,proto3" json:"units,omitempty"` // Number of nano (10^-9) units of the amount. // The value must be between -999,999,999 and +999,999,999 inclusive. // If `units` is positive, `nanos` must be positive or zero. // If `units` is zero, `nanos` can be positive, zero, or negative. // If `units` is negative, `nanos` must be negative or zero. // For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000. Nanos int32 `protobuf:"varint,3,opt,name=nanos,proto3" json:"nanos,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Money) Reset() { *m = Money{} } func (m *Money) String() string { return proto.CompactTextString(m) } func (*Money) ProtoMessage() {} func (*Money) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{18} } func (m *Money) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Money.Unmarshal(m, b) } func (m *Money) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Money.Marshal(b, m, deterministic) } func (m *Money) XXX_Merge(src proto.Message) { xxx_messageInfo_Money.Merge(m, src) } func (m *Money) XXX_Size() int { return xxx_messageInfo_Money.Size(m) } func (m *Money) XXX_DiscardUnknown() { xxx_messageInfo_Money.DiscardUnknown(m) } var xxx_messageInfo_Money proto.InternalMessageInfo func (m *Money) GetCurrencyCode() string { if m != nil { return m.CurrencyCode } return "" } func (m *Money) GetUnits() int64 { if m != nil { return m.Units } return 0 } func (m *Money) GetNanos() int32 { if m != nil { return m.Nanos } return 0 } type GetSupportedCurrenciesResponse struct { // The 3-letter currency code defined in ISO 4217. CurrencyCodes []string `protobuf:"bytes,1,rep,name=currency_codes,json=currencyCodes,proto3" json:"currency_codes,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *GetSupportedCurrenciesResponse) Reset() { *m = GetSupportedCurrenciesResponse{} } func (m *GetSupportedCurrenciesResponse) String() string { return proto.CompactTextString(m) } func (*GetSupportedCurrenciesResponse) ProtoMessage() {} func (*GetSupportedCurrenciesResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{19} } func (m *GetSupportedCurrenciesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSupportedCurrenciesResponse.Unmarshal(m, b) } func (m *GetSupportedCurrenciesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetSupportedCurrenciesResponse.Marshal(b, m, deterministic) } func (m *GetSupportedCurrenciesResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_GetSupportedCurrenciesResponse.Merge(m, src) } func (m *GetSupportedCurrenciesResponse) XXX_Size() int { return xxx_messageInfo_GetSupportedCurrenciesResponse.Size(m) } func (m *GetSupportedCurrenciesResponse) XXX_DiscardUnknown() { xxx_messageInfo_GetSupportedCurrenciesResponse.DiscardUnknown(m) } var xxx_messageInfo_GetSupportedCurrenciesResponse proto.InternalMessageInfo func (m *GetSupportedCurrenciesResponse) GetCurrencyCodes() []string { if m != nil { return m.CurrencyCodes } return nil } type CurrencyConversionRequest struct { From *Money `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"` // The 3-letter currency code defined in ISO 4217. ToCode string `protobuf:"bytes,2,opt,name=to_code,json=toCode,proto3" json:"to_code,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *CurrencyConversionRequest) Reset() { *m = CurrencyConversionRequest{} } func (m *CurrencyConversionRequest) String() string { return proto.CompactTextString(m) } func (*CurrencyConversionRequest) ProtoMessage() {} func (*CurrencyConversionRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{20} } func (m *CurrencyConversionRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CurrencyConversionRequest.Unmarshal(m, b) } func (m *CurrencyConversionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CurrencyConversionRequest.Marshal(b, m, deterministic) } func (m *CurrencyConversionRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_CurrencyConversionRequest.Merge(m, src) } func (m *CurrencyConversionRequest) XXX_Size() int { return xxx_messageInfo_CurrencyConversionRequest.Size(m) } func (m *CurrencyConversionRequest) XXX_DiscardUnknown() { xxx_messageInfo_CurrencyConversionRequest.DiscardUnknown(m) } var xxx_messageInfo_CurrencyConversionRequest proto.InternalMessageInfo func (m *CurrencyConversionRequest) GetFrom() *Money { if m != nil { return m.From } return nil } func (m *CurrencyConversionRequest) GetToCode() string { if m != nil { return m.ToCode } return "" } type CreditCardInfo struct { CreditCardNumber string `protobuf:"bytes,1,opt,name=credit_card_number,json=creditCardNumber,proto3" json:"credit_card_number,omitempty"` CreditCardCvv int32 `protobuf:"varint,2,opt,name=credit_card_cvv,json=creditCardCvv,proto3" json:"credit_card_cvv,omitempty"` CreditCardExpirationYear int32 `protobuf:"varint,3,opt,name=credit_card_expiration_year,json=creditCardExpirationYear,proto3" json:"credit_card_expiration_year,omitempty"` CreditCardExpirationMonth int32 `protobuf:"varint,4,opt,name=credit_card_expiration_month,json=creditCardExpirationMonth,proto3" json:"credit_card_expiration_month,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *CreditCardInfo) Reset() { *m = CreditCardInfo{} } func (m *CreditCardInfo) String() string { return proto.CompactTextString(m) } func (*CreditCardInfo) ProtoMessage() {} func (*CreditCardInfo) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{21} } func (m *CreditCardInfo) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CreditCardInfo.Unmarshal(m, b) } func (m *CreditCardInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CreditCardInfo.Marshal(b, m, deterministic) } func (m *CreditCardInfo) XXX_Merge(src proto.Message) { xxx_messageInfo_CreditCardInfo.Merge(m, src) } func (m *CreditCardInfo) XXX_Size() int { return xxx_messageInfo_CreditCardInfo.Size(m) } func (m *CreditCardInfo) XXX_DiscardUnknown() { xxx_messageInfo_CreditCardInfo.DiscardUnknown(m) } var xxx_messageInfo_CreditCardInfo proto.InternalMessageInfo func (m *CreditCardInfo) GetCreditCardNumber() string { if m != nil { return m.CreditCardNumber } return "" } func (m *CreditCardInfo) GetCreditCardCvv() int32 { if m != nil { return m.CreditCardCvv } return 0 } func (m *CreditCardInfo) GetCreditCardExpirationYear() int32 { if m != nil { return m.CreditCardExpirationYear } return 0 } func (m *CreditCardInfo) GetCreditCardExpirationMonth() int32 { if m != nil { return m.CreditCardExpirationMonth } return 0 } type ChargeRequest struct { Amount *Money `protobuf:"bytes,1,opt,name=amount,proto3" json:"amount,omitempty"` CreditCard *CreditCardInfo `protobuf:"bytes,2,opt,name=credit_card,json=creditCard,proto3" json:"credit_card,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ChargeRequest) Reset() { *m = ChargeRequest{} } func (m *ChargeRequest) String() string { return proto.CompactTextString(m) } func (*ChargeRequest) ProtoMessage() {} func (*ChargeRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{22} } func (m *ChargeRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ChargeRequest.Unmarshal(m, b) } func (m *ChargeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ChargeRequest.Marshal(b, m, deterministic) } func (m *ChargeRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_ChargeRequest.Merge(m, src) } func (m *ChargeRequest) XXX_Size() int { return xxx_messageInfo_ChargeRequest.Size(m) } func (m *ChargeRequest) XXX_DiscardUnknown() { xxx_messageInfo_ChargeRequest.DiscardUnknown(m) } var xxx_messageInfo_ChargeRequest proto.InternalMessageInfo func (m *ChargeRequest) GetAmount() *Money { if m != nil { return m.Amount } return nil } func (m *ChargeRequest) GetCreditCard() *CreditCardInfo { if m != nil { return m.CreditCard } return nil } type ChargeResponse struct { TransactionId string `protobuf:"bytes,1,opt,name=transaction_id,json=transactionId,proto3" json:"transaction_id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ChargeResponse) Reset() { *m = ChargeResponse{} } func (m *ChargeResponse) String() string { return proto.CompactTextString(m) } func (*ChargeResponse) ProtoMessage() {} func (*ChargeResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{23} } func (m *ChargeResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ChargeResponse.Unmarshal(m, b) } func (m *ChargeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ChargeResponse.Marshal(b, m, deterministic) } func (m *ChargeResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_ChargeResponse.Merge(m, src) } func (m *ChargeResponse) XXX_Size() int { return xxx_messageInfo_ChargeResponse.Size(m) } func (m *ChargeResponse) XXX_DiscardUnknown() { xxx_messageInfo_ChargeResponse.DiscardUnknown(m) } var xxx_messageInfo_ChargeResponse proto.InternalMessageInfo func (m *ChargeResponse) GetTransactionId() string { if m != nil { return m.TransactionId } return "" } type OrderItem struct { Item *CartItem `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` Cost *Money `protobuf:"bytes,2,opt,name=cost,proto3" json:"cost,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *OrderItem) Reset() { *m = OrderItem{} } func (m *OrderItem) String() string { return proto.CompactTextString(m) } func (*OrderItem) ProtoMessage() {} func (*OrderItem) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{24} } func (m *OrderItem) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_OrderItem.Unmarshal(m, b) } func (m *OrderItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_OrderItem.Marshal(b, m, deterministic) } func (m *OrderItem) XXX_Merge(src proto.Message) { xxx_messageInfo_OrderItem.Merge(m, src) } func (m *OrderItem) XXX_Size() int { return xxx_messageInfo_OrderItem.Size(m) } func (m *OrderItem) XXX_DiscardUnknown() { xxx_messageInfo_OrderItem.DiscardUnknown(m) } var xxx_messageInfo_OrderItem proto.InternalMessageInfo func (m *OrderItem) GetItem() *CartItem { if m != nil { return m.Item } return nil } func (m *OrderItem) GetCost() *Money { if m != nil { return m.Cost } return nil } type OrderResult struct { OrderId string `protobuf:"bytes,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` ShippingTrackingId string `protobuf:"bytes,2,opt,name=shipping_tracking_id,json=shippingTrackingId,proto3" json:"shipping_tracking_id,omitempty"` ShippingCost *Money `protobuf:"bytes,3,opt,name=shipping_cost,json=shippingCost,proto3" json:"shipping_cost,omitempty"` ShippingAddress *Address `protobuf:"bytes,4,opt,name=shipping_address,json=shippingAddress,proto3" json:"shipping_address,omitempty"` Items []*OrderItem `protobuf:"bytes,5,rep,name=items,proto3" json:"items,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *OrderResult) Reset() { *m = OrderResult{} } func (m *OrderResult) String() string { return proto.CompactTextString(m) } func (*OrderResult) ProtoMessage() {} func (*OrderResult) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{25} } func (m *OrderResult) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_OrderResult.Unmarshal(m, b) } func (m *OrderResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_OrderResult.Marshal(b, m, deterministic) } func (m *OrderResult) XXX_Merge(src proto.Message) { xxx_messageInfo_OrderResult.Merge(m, src) } func (m *OrderResult) XXX_Size() int { return xxx_messageInfo_OrderResult.Size(m) } func (m *OrderResult) XXX_DiscardUnknown() { xxx_messageInfo_OrderResult.DiscardUnknown(m) } var xxx_messageInfo_OrderResult proto.InternalMessageInfo func (m *OrderResult) GetOrderId() string { if m != nil { return m.OrderId } return "" } func (m *OrderResult) GetShippingTrackingId() string { if m != nil { return m.ShippingTrackingId } return "" } func (m *OrderResult) GetShippingCost() *Money { if m != nil { return m.ShippingCost } return nil } func (m *OrderResult) GetShippingAddress() *Address { if m != nil { return m.ShippingAddress } return nil } func (m *OrderResult) GetItems() []*OrderItem { if m != nil { return m.Items } return nil } type SendOrderConfirmationRequest struct { Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` Order *OrderResult `protobuf:"bytes,2,opt,name=order,proto3" json:"order,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *SendOrderConfirmationRequest) Reset() { *m = SendOrderConfirmationRequest{} } func (m *SendOrderConfirmationRequest) String() string { return proto.CompactTextString(m) } func (*SendOrderConfirmationRequest) ProtoMessage() {} func (*SendOrderConfirmationRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{26} } func (m *SendOrderConfirmationRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SendOrderConfirmationRequest.Unmarshal(m, b) } func (m *SendOrderConfirmationRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SendOrderConfirmationRequest.Marshal(b, m, deterministic) } func (m *SendOrderConfirmationRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_SendOrderConfirmationRequest.Merge(m, src) } func (m *SendOrderConfirmationRequest) XXX_Size() int { return xxx_messageInfo_SendOrderConfirmationRequest.Size(m) } func (m *SendOrderConfirmationRequest) XXX_DiscardUnknown() { xxx_messageInfo_SendOrderConfirmationRequest.DiscardUnknown(m) } var xxx_messageInfo_SendOrderConfirmationRequest proto.InternalMessageInfo func (m *SendOrderConfirmationRequest) GetEmail() string { if m != nil { return m.Email } return "" } func (m *SendOrderConfirmationRequest) GetOrder() *OrderResult { if m != nil { return m.Order } return nil } type PlaceOrderRequest struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` UserCurrency string `protobuf:"bytes,2,opt,name=user_currency,json=userCurrency,proto3" json:"user_currency,omitempty"` Address *Address `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"` Email string `protobuf:"bytes,5,opt,name=email,proto3" json:"email,omitempty"` CreditCard *CreditCardInfo `protobuf:"bytes,6,opt,name=credit_card,json=creditCard,proto3" json:"credit_card,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *PlaceOrderRequest) Reset() { *m = PlaceOrderRequest{} } func (m *PlaceOrderRequest) String() string { return proto.CompactTextString(m) } func (*PlaceOrderRequest) ProtoMessage() {} func (*PlaceOrderRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{27} } func (m *PlaceOrderRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PlaceOrderRequest.Unmarshal(m, b) } func (m *PlaceOrderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PlaceOrderRequest.Marshal(b, m, deterministic) } func (m *PlaceOrderRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_PlaceOrderRequest.Merge(m, src) } func (m *PlaceOrderRequest) XXX_Size() int { return xxx_messageInfo_PlaceOrderRequest.Size(m) } func (m *PlaceOrderRequest) XXX_DiscardUnknown() { xxx_messageInfo_PlaceOrderRequest.DiscardUnknown(m) } var xxx_messageInfo_PlaceOrderRequest proto.InternalMessageInfo func (m *PlaceOrderRequest) GetUserId() string { if m != nil { return m.UserId } return "" } func (m *PlaceOrderRequest) GetUserCurrency() string { if m != nil { return m.UserCurrency } return "" } func (m *PlaceOrderRequest) GetAddress() *Address { if m != nil { return m.Address } return nil } func (m *PlaceOrderRequest) GetEmail() string { if m != nil { return m.Email } return "" } func (m *PlaceOrderRequest) GetCreditCard() *CreditCardInfo { if m != nil { return m.CreditCard } return nil } type PlaceOrderResponse struct { Order *OrderResult `protobuf:"bytes,1,opt,name=order,proto3" json:"order,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *PlaceOrderResponse) Reset() { *m = PlaceOrderResponse{} } func (m *PlaceOrderResponse) String() string { return proto.CompactTextString(m) } func (*PlaceOrderResponse) ProtoMessage() {} func (*PlaceOrderResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{28} } func (m *PlaceOrderResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PlaceOrderResponse.Unmarshal(m, b) } func (m *PlaceOrderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PlaceOrderResponse.Marshal(b, m, deterministic) } func (m *PlaceOrderResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_PlaceOrderResponse.Merge(m, src) } func (m *PlaceOrderResponse) XXX_Size() int { return xxx_messageInfo_PlaceOrderResponse.Size(m) } func (m *PlaceOrderResponse) XXX_DiscardUnknown() { xxx_messageInfo_PlaceOrderResponse.DiscardUnknown(m) } var xxx_messageInfo_PlaceOrderResponse proto.InternalMessageInfo func (m *PlaceOrderResponse) GetOrder() *OrderResult { if m != nil { return m.Order } return nil } type AdRequest struct { // List of important key words from the current page describing the context. ContextKeys []string `protobuf:"bytes,1,rep,name=context_keys,json=contextKeys,proto3" json:"context_keys,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *AdRequest) Reset() { *m = AdRequest{} } func (m *AdRequest) String() string { return proto.CompactTextString(m) } func (*AdRequest) ProtoMessage() {} func (*AdRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{29} } func (m *AdRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AdRequest.Unmarshal(m, b) } func (m *AdRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_AdRequest.Marshal(b, m, deterministic) } func (m *AdRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_AdRequest.Merge(m, src) } func (m *AdRequest) XXX_Size() int { return xxx_messageInfo_AdRequest.Size(m) } func (m *AdRequest) XXX_DiscardUnknown() { xxx_messageInfo_AdRequest.DiscardUnknown(m) } var xxx_messageInfo_AdRequest proto.InternalMessageInfo func (m *AdRequest) GetContextKeys() []string { if m != nil { return m.ContextKeys } return nil } type AdResponse struct { Ads []*Ad `protobuf:"bytes,1,rep,name=ads,proto3" json:"ads,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *AdResponse) Reset() { *m = AdResponse{} } func (m *AdResponse) String() string { return proto.CompactTextString(m) } func (*AdResponse) ProtoMessage() {} func (*AdResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{30} } func (m *AdResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AdResponse.Unmarshal(m, b) } func (m *AdResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_AdResponse.Marshal(b, m, deterministic) } func (m *AdResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_AdResponse.Merge(m, src) } func (m *AdResponse) XXX_Size() int { return xxx_messageInfo_AdResponse.Size(m) } func (m *AdResponse) XXX_DiscardUnknown() { xxx_messageInfo_AdResponse.DiscardUnknown(m) } var xxx_messageInfo_AdResponse proto.InternalMessageInfo func (m *AdResponse) GetAds() []*Ad { if m != nil { return m.Ads } return nil } type Ad struct { // url to redirect to when an ad is clicked. RedirectUrl string `protobuf:"bytes,1,opt,name=redirect_url,json=redirectUrl,proto3" json:"redirect_url,omitempty"` // short advertisement text to display. Text string `protobuf:"bytes,2,opt,name=text,proto3" json:"text,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Ad) Reset() { *m = Ad{} } func (m *Ad) String() string { return proto.CompactTextString(m) } func (*Ad) ProtoMessage() {} func (*Ad) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{31} } func (m *Ad) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Ad.Unmarshal(m, b) } func (m *Ad) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Ad.Marshal(b, m, deterministic) } func (m *Ad) XXX_Merge(src proto.Message) { xxx_messageInfo_Ad.Merge(m, src) } func (m *Ad) XXX_Size() int { return xxx_messageInfo_Ad.Size(m) } func (m *Ad) XXX_DiscardUnknown() { xxx_messageInfo_Ad.DiscardUnknown(m) } var xxx_messageInfo_Ad proto.InternalMessageInfo func (m *Ad) GetRedirectUrl() string { if m != nil { return m.RedirectUrl } return "" } func (m *Ad) GetText() string { if m != nil { return m.Text } return "" } func init() { proto.RegisterType((*CartItem)(nil), "hipstershop.CartItem") proto.RegisterType((*AddItemRequest)(nil), "hipstershop.AddItemRequest") proto.RegisterType((*EmptyCartRequest)(nil), "hipstershop.EmptyCartRequest") proto.RegisterType((*GetCartRequest)(nil), "hipstershop.GetCartRequest") proto.RegisterType((*Cart)(nil), "hipstershop.Cart") proto.RegisterType((*Empty)(nil), "hipstershop.Empty") proto.RegisterType((*ListRecommendationsRequest)(nil), "hipstershop.ListRecommendationsRequest") proto.RegisterType((*ListRecommendationsResponse)(nil), "hipstershop.ListRecommendationsResponse") proto.RegisterType((*Product)(nil), "hipstershop.Product") proto.RegisterType((*ListProductsResponse)(nil), "hipstershop.ListProductsResponse") proto.RegisterType((*GetProductRequest)(nil), "hipstershop.GetProductRequest") proto.RegisterType((*SearchProductsRequest)(nil), "hipstershop.SearchProductsRequest") proto.RegisterType((*SearchProductsResponse)(nil), "hipstershop.SearchProductsResponse") proto.RegisterType((*GetQuoteRequest)(nil), "hipstershop.GetQuoteRequest") proto.RegisterType((*GetQuoteResponse)(nil), "hipstershop.GetQuoteResponse") proto.RegisterType((*ShipOrderRequest)(nil), "hipstershop.ShipOrderRequest") proto.RegisterType((*ShipOrderResponse)(nil), "hipstershop.ShipOrderResponse") proto.RegisterType((*Address)(nil), "hipstershop.Address") proto.RegisterType((*Money)(nil), "hipstershop.Money") proto.RegisterType((*GetSupportedCurrenciesResponse)(nil), "hipstershop.GetSupportedCurrenciesResponse") proto.RegisterType((*CurrencyConversionRequest)(nil), "hipstershop.CurrencyConversionRequest") proto.RegisterType((*CreditCardInfo)(nil), "hipstershop.CreditCardInfo") proto.RegisterType((*ChargeRequest)(nil), "hipstershop.ChargeRequest") proto.RegisterType((*ChargeResponse)(nil), "hipstershop.ChargeResponse") proto.RegisterType((*OrderItem)(nil), "hipstershop.OrderItem") proto.RegisterType((*OrderResult)(nil), "hipstershop.OrderResult") proto.RegisterType((*SendOrderConfirmationRequest)(nil), "hipstershop.SendOrderConfirmationRequest") proto.RegisterType((*PlaceOrderRequest)(nil), "hipstershop.PlaceOrderRequest") proto.RegisterType((*PlaceOrderResponse)(nil), "hipstershop.PlaceOrderResponse") proto.RegisterType((*AdRequest)(nil), "hipstershop.AdRequest") proto.RegisterType((*AdResponse)(nil), "hipstershop.AdResponse") proto.RegisterType((*Ad)(nil), "hipstershop.Ad") } // Reference imports to suppress errors if they are not otherwise used. var _ context.Context var _ grpc.ClientConn // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. const _ = grpc.SupportPackageIsVersion4 // CartServiceClient is the client API for CartService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type CartServiceClient interface { AddItem(ctx context.Context, in *AddItemRequest, opts ...grpc.CallOption) (*Empty, error) GetCart(ctx context.Context, in *GetCartRequest, opts ...grpc.CallOption) (*Cart, error) EmptyCart(ctx context.Context, in *EmptyCartRequest, opts ...grpc.CallOption) (*Empty, error) } type cartServiceClient struct { cc *grpc.ClientConn } func NewCartServiceClient(cc *grpc.ClientConn) CartServiceClient { return &cartServiceClient{cc} } func (c *cartServiceClient) AddItem(ctx context.Context, in *AddItemRequest, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) err := c.cc.Invoke(ctx, "/hipstershop.CartService/AddItem", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *cartServiceClient) GetCart(ctx context.Context, in *GetCartRequest, opts ...grpc.CallOption) (*Cart, error) { out := new(Cart) err := c.cc.Invoke(ctx, "/hipstershop.CartService/GetCart", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *cartServiceClient) EmptyCart(ctx context.Context, in *EmptyCartRequest, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) err := c.cc.Invoke(ctx, "/hipstershop.CartService/EmptyCart", in, out, opts...) if err != nil { return nil, err } return out, nil } // CartServiceServer is the server API for CartService service. type CartServiceServer interface { AddItem(context.Context, *AddItemRequest) (*Empty, error) GetCart(context.Context, *GetCartRequest) (*Cart, error) EmptyCart(context.Context, *EmptyCartRequest) (*Empty, error) } func RegisterCartServiceServer(s *grpc.Server, srv CartServiceServer) { s.RegisterService(&_CartService_serviceDesc, srv) } func _CartService_AddItem_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AddItemRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CartServiceServer).AddItem(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CartService/AddItem", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CartServiceServer).AddItem(ctx, req.(*AddItemRequest)) } return interceptor(ctx, in, info, handler) } func _CartService_GetCart_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetCartRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CartServiceServer).GetCart(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CartService/GetCart", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CartServiceServer).GetCart(ctx, req.(*GetCartRequest)) } return interceptor(ctx, in, info, handler) } func _CartService_EmptyCart_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(EmptyCartRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CartServiceServer).EmptyCart(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CartService/EmptyCart", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CartServiceServer).EmptyCart(ctx, req.(*EmptyCartRequest)) } return interceptor(ctx, in, info, handler) } var _CartService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.CartService", HandlerType: (*CartServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "AddItem", Handler: _CartService_AddItem_Handler, }, { MethodName: "GetCart", Handler: _CartService_GetCart_Handler, }, { MethodName: "EmptyCart", Handler: _CartService_EmptyCart_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // RecommendationServiceClient is the client API for RecommendationService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type RecommendationServiceClient interface { ListRecommendations(ctx context.Context, in *ListRecommendationsRequest, opts ...grpc.CallOption) (*ListRecommendationsResponse, error) } type recommendationServiceClient struct { cc *grpc.ClientConn } func NewRecommendationServiceClient(cc *grpc.ClientConn) RecommendationServiceClient { return &recommendationServiceClient{cc} } func (c *recommendationServiceClient) ListRecommendations(ctx context.Context, in *ListRecommendationsRequest, opts ...grpc.CallOption) (*ListRecommendationsResponse, error) { out := new(ListRecommendationsResponse) err := c.cc.Invoke(ctx, "/hipstershop.RecommendationService/ListRecommendations", in, out, opts...) if err != nil { return nil, err } return out, nil } // RecommendationServiceServer is the server API for RecommendationService service. type RecommendationServiceServer interface { ListRecommendations(context.Context, *ListRecommendationsRequest) (*ListRecommendationsResponse, error) } func RegisterRecommendationServiceServer(s *grpc.Server, srv RecommendationServiceServer) { s.RegisterService(&_RecommendationService_serviceDesc, srv) } func _RecommendationService_ListRecommendations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListRecommendationsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(RecommendationServiceServer).ListRecommendations(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.RecommendationService/ListRecommendations", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(RecommendationServiceServer).ListRecommendations(ctx, req.(*ListRecommendationsRequest)) } return interceptor(ctx, in, info, handler) } var _RecommendationService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.RecommendationService", HandlerType: (*RecommendationServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "ListRecommendations", Handler: _RecommendationService_ListRecommendations_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // ProductCatalogServiceClient is the client API for ProductCatalogService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type ProductCatalogServiceClient interface { ListProducts(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ListProductsResponse, error) GetProduct(ctx context.Context, in *GetProductRequest, opts ...grpc.CallOption) (*Product, error) SearchProducts(ctx context.Context, in *SearchProductsRequest, opts ...grpc.CallOption) (*SearchProductsResponse, error) } type productCatalogServiceClient struct { cc *grpc.ClientConn } func NewProductCatalogServiceClient(cc *grpc.ClientConn) ProductCatalogServiceClient { return &productCatalogServiceClient{cc} } func (c *productCatalogServiceClient) ListProducts(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ListProductsResponse, error) { out := new(ListProductsResponse) err := c.cc.Invoke(ctx, "/hipstershop.ProductCatalogService/ListProducts", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *productCatalogServiceClient) GetProduct(ctx context.Context, in *GetProductRequest, opts ...grpc.CallOption) (*Product, error) { out := new(Product) err := c.cc.Invoke(ctx, "/hipstershop.ProductCatalogService/GetProduct", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *productCatalogServiceClient) SearchProducts(ctx context.Context, in *SearchProductsRequest, opts ...grpc.CallOption) (*SearchProductsResponse, error) { out := new(SearchProductsResponse) err := c.cc.Invoke(ctx, "/hipstershop.ProductCatalogService/SearchProducts", in, out, opts...) if err != nil { return nil, err } return out, nil } // ProductCatalogServiceServer is the server API for ProductCatalogService service. type ProductCatalogServiceServer interface { ListProducts(context.Context, *Empty) (*ListProductsResponse, error) GetProduct(context.Context, *GetProductRequest) (*Product, error) SearchProducts(context.Context, *SearchProductsRequest) (*SearchProductsResponse, error) } func RegisterProductCatalogServiceServer(s *grpc.Server, srv ProductCatalogServiceServer) { s.RegisterService(&_ProductCatalogService_serviceDesc, srv) } func _ProductCatalogService_ListProducts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(Empty) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(ProductCatalogServiceServer).ListProducts(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.ProductCatalogService/ListProducts", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ProductCatalogServiceServer).ListProducts(ctx, req.(*Empty)) } return interceptor(ctx, in, info, handler) } func _ProductCatalogService_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.(ProductCatalogServiceServer).GetProduct(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.ProductCatalogService/GetProduct", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ProductCatalogServiceServer).GetProduct(ctx, req.(*GetProductRequest)) } return interceptor(ctx, in, info, handler) } func _ProductCatalogService_SearchProducts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(SearchProductsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(ProductCatalogServiceServer).SearchProducts(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.ProductCatalogService/SearchProducts", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ProductCatalogServiceServer).SearchProducts(ctx, req.(*SearchProductsRequest)) } return interceptor(ctx, in, info, handler) } var _ProductCatalogService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.ProductCatalogService", HandlerType: (*ProductCatalogServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "ListProducts", Handler: _ProductCatalogService_ListProducts_Handler, }, { MethodName: "GetProduct", Handler: _ProductCatalogService_GetProduct_Handler, }, { MethodName: "SearchProducts", Handler: _ProductCatalogService_SearchProducts_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // ShippingServiceClient is the client API for ShippingService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type ShippingServiceClient interface { GetQuote(ctx context.Context, in *GetQuoteRequest, opts ...grpc.CallOption) (*GetQuoteResponse, error) ShipOrder(ctx context.Context, in *ShipOrderRequest, opts ...grpc.CallOption) (*ShipOrderResponse, error) } type shippingServiceClient struct { cc *grpc.ClientConn } func NewShippingServiceClient(cc *grpc.ClientConn) ShippingServiceClient { return &shippingServiceClient{cc} } func (c *shippingServiceClient) GetQuote(ctx context.Context, in *GetQuoteRequest, opts ...grpc.CallOption) (*GetQuoteResponse, error) { out := new(GetQuoteResponse) err := c.cc.Invoke(ctx, "/hipstershop.ShippingService/GetQuote", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *shippingServiceClient) ShipOrder(ctx context.Context, in *ShipOrderRequest, opts ...grpc.CallOption) (*ShipOrderResponse, error) { out := new(ShipOrderResponse) err := c.cc.Invoke(ctx, "/hipstershop.ShippingService/ShipOrder", in, out, opts...) if err != nil { return nil, err } return out, nil } // ShippingServiceServer is the server API for ShippingService service. type ShippingServiceServer interface { GetQuote(context.Context, *GetQuoteRequest) (*GetQuoteResponse, error) ShipOrder(context.Context, *ShipOrderRequest) (*ShipOrderResponse, error) } func RegisterShippingServiceServer(s *grpc.Server, srv ShippingServiceServer) { s.RegisterService(&_ShippingService_serviceDesc, srv) } func _ShippingService_GetQuote_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetQuoteRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(ShippingServiceServer).GetQuote(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.ShippingService/GetQuote", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ShippingServiceServer).GetQuote(ctx, req.(*GetQuoteRequest)) } return interceptor(ctx, in, info, handler) } func _ShippingService_ShipOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ShipOrderRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(ShippingServiceServer).ShipOrder(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.ShippingService/ShipOrder", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ShippingServiceServer).ShipOrder(ctx, req.(*ShipOrderRequest)) } return interceptor(ctx, in, info, handler) } var _ShippingService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.ShippingService", HandlerType: (*ShippingServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "GetQuote", Handler: _ShippingService_GetQuote_Handler, }, { MethodName: "ShipOrder", Handler: _ShippingService_ShipOrder_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // CurrencyServiceClient is the client API for CurrencyService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type CurrencyServiceClient interface { GetSupportedCurrencies(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetSupportedCurrenciesResponse, error) Convert(ctx context.Context, in *CurrencyConversionRequest, opts ...grpc.CallOption) (*Money, error) } type currencyServiceClient struct { cc *grpc.ClientConn } func NewCurrencyServiceClient(cc *grpc.ClientConn) CurrencyServiceClient { return ¤cyServiceClient{cc} } func (c *currencyServiceClient) GetSupportedCurrencies(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetSupportedCurrenciesResponse, error) { out := new(GetSupportedCurrenciesResponse) err := c.cc.Invoke(ctx, "/hipstershop.CurrencyService/GetSupportedCurrencies", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *currencyServiceClient) Convert(ctx context.Context, in *CurrencyConversionRequest, opts ...grpc.CallOption) (*Money, error) { out := new(Money) err := c.cc.Invoke(ctx, "/hipstershop.CurrencyService/Convert", in, out, opts...) if err != nil { return nil, err } return out, nil } // CurrencyServiceServer is the server API for CurrencyService service. type CurrencyServiceServer interface { GetSupportedCurrencies(context.Context, *Empty) (*GetSupportedCurrenciesResponse, error) Convert(context.Context, *CurrencyConversionRequest) (*Money, error) } func RegisterCurrencyServiceServer(s *grpc.Server, srv CurrencyServiceServer) { s.RegisterService(&_CurrencyService_serviceDesc, srv) } func _CurrencyService_GetSupportedCurrencies_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(Empty) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CurrencyServiceServer).GetSupportedCurrencies(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CurrencyService/GetSupportedCurrencies", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CurrencyServiceServer).GetSupportedCurrencies(ctx, req.(*Empty)) } return interceptor(ctx, in, info, handler) } func _CurrencyService_Convert_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CurrencyConversionRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CurrencyServiceServer).Convert(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CurrencyService/Convert", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CurrencyServiceServer).Convert(ctx, req.(*CurrencyConversionRequest)) } return interceptor(ctx, in, info, handler) } var _CurrencyService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.CurrencyService", HandlerType: (*CurrencyServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "GetSupportedCurrencies", Handler: _CurrencyService_GetSupportedCurrencies_Handler, }, { MethodName: "Convert", Handler: _CurrencyService_Convert_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // PaymentServiceClient is the client API for PaymentService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type PaymentServiceClient interface { Charge(ctx context.Context, in *ChargeRequest, opts ...grpc.CallOption) (*ChargeResponse, error) } type paymentServiceClient struct { cc *grpc.ClientConn } func NewPaymentServiceClient(cc *grpc.ClientConn) PaymentServiceClient { return &paymentServiceClient{cc} } func (c *paymentServiceClient) Charge(ctx context.Context, in *ChargeRequest, opts ...grpc.CallOption) (*ChargeResponse, error) { out := new(ChargeResponse) err := c.cc.Invoke(ctx, "/hipstershop.PaymentService/Charge", in, out, opts...) if err != nil { return nil, err } return out, nil } // PaymentServiceServer is the server API for PaymentService service. type PaymentServiceServer interface { Charge(context.Context, *ChargeRequest) (*ChargeResponse, error) } func RegisterPaymentServiceServer(s *grpc.Server, srv PaymentServiceServer) { s.RegisterService(&_PaymentService_serviceDesc, srv) } func _PaymentService_Charge_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ChargeRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(PaymentServiceServer).Charge(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.PaymentService/Charge", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(PaymentServiceServer).Charge(ctx, req.(*ChargeRequest)) } return interceptor(ctx, in, info, handler) } var _PaymentService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.PaymentService", HandlerType: (*PaymentServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "Charge", Handler: _PaymentService_Charge_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // EmailServiceClient is the client API for EmailService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type EmailServiceClient interface { SendOrderConfirmation(ctx context.Context, in *SendOrderConfirmationRequest, opts ...grpc.CallOption) (*Empty, error) } type emailServiceClient struct { cc *grpc.ClientConn } func NewEmailServiceClient(cc *grpc.ClientConn) EmailServiceClient { return &emailServiceClient{cc} } func (c *emailServiceClient) SendOrderConfirmation(ctx context.Context, in *SendOrderConfirmationRequest, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) err := c.cc.Invoke(ctx, "/hipstershop.EmailService/SendOrderConfirmation", in, out, opts...) if err != nil { return nil, err } return out, nil } // EmailServiceServer is the server API for EmailService service. type EmailServiceServer interface { SendOrderConfirmation(context.Context, *SendOrderConfirmationRequest) (*Empty, error) } func RegisterEmailServiceServer(s *grpc.Server, srv EmailServiceServer) { s.RegisterService(&_EmailService_serviceDesc, srv) } func _EmailService_SendOrderConfirmation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(SendOrderConfirmationRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(EmailServiceServer).SendOrderConfirmation(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.EmailService/SendOrderConfirmation", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(EmailServiceServer).SendOrderConfirmation(ctx, req.(*SendOrderConfirmationRequest)) } return interceptor(ctx, in, info, handler) } var _EmailService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.EmailService", HandlerType: (*EmailServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "SendOrderConfirmation", Handler: _EmailService_SendOrderConfirmation_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // CheckoutServiceClient is the client API for CheckoutService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type CheckoutServiceClient interface { PlaceOrder(ctx context.Context, in *PlaceOrderRequest, opts ...grpc.CallOption) (*PlaceOrderResponse, error) } type checkoutServiceClient struct { cc *grpc.ClientConn } func NewCheckoutServiceClient(cc *grpc.ClientConn) CheckoutServiceClient { return &checkoutServiceClient{cc} } func (c *checkoutServiceClient) PlaceOrder(ctx context.Context, in *PlaceOrderRequest, opts ...grpc.CallOption) (*PlaceOrderResponse, error) { out := new(PlaceOrderResponse) err := c.cc.Invoke(ctx, "/hipstershop.CheckoutService/PlaceOrder", in, out, opts...) if err != nil { return nil, err } return out, nil } // CheckoutServiceServer is the server API for CheckoutService service. type CheckoutServiceServer interface { PlaceOrder(context.Context, *PlaceOrderRequest) (*PlaceOrderResponse, error) } func RegisterCheckoutServiceServer(s *grpc.Server, srv CheckoutServiceServer) { s.RegisterService(&_CheckoutService_serviceDesc, srv) } func _CheckoutService_PlaceOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(PlaceOrderRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CheckoutServiceServer).PlaceOrder(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CheckoutService/PlaceOrder", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CheckoutServiceServer).PlaceOrder(ctx, req.(*PlaceOrderRequest)) } return interceptor(ctx, in, info, handler) } var _CheckoutService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.CheckoutService", HandlerType: (*CheckoutServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "PlaceOrder", Handler: _CheckoutService_PlaceOrder_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // AdServiceClient is the client API for AdService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type AdServiceClient interface { GetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error) } type adServiceClient struct { cc *grpc.ClientConn } func NewAdServiceClient(cc *grpc.ClientConn) AdServiceClient { return &adServiceClient{cc} } func (c *adServiceClient) GetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error) { out := new(AdResponse) err := c.cc.Invoke(ctx, "/hipstershop.AdService/GetAds", in, out, opts...) if err != nil { return nil, err } return out, nil } // AdServiceServer is the server API for AdService service. type AdServiceServer interface { GetAds(context.Context, *AdRequest) (*AdResponse, error) } func RegisterAdServiceServer(s *grpc.Server, srv AdServiceServer) { s.RegisterService(&_AdService_serviceDesc, srv) } func _AdService_GetAds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AdRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(AdServiceServer).GetAds(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.AdService/GetAds", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(AdServiceServer).GetAds(ctx, req.(*AdRequest)) } return interceptor(ctx, in, info, handler) } var _AdService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.AdService", HandlerType: (*AdServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "GetAds", Handler: _AdService_GetAds_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } func init() { proto.RegisterFile("demo.proto", fileDescriptor_ca53982754088a9d) } var fileDescriptor_ca53982754088a9d = []byte{ // 1500 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xef, 0x72, 0x13, 0xb7, 0x16, 0xcf, 0x26, 0xb1, 0x1d, 0x1f, 0xc7, 0x4e, 0xa2, 0x9b, 0x04, 0xb3, 0x81, 0x10, 0x94, 0x81, 0x0b, 0x17, 0x08, 0x4c, 0xee, 0x9d, 0xe1, 0x03, 0xdc, 0xd2, 0x8c, 0xc9, 0x18, 0x4f, 0xa1, 0xd0, 0x0d, 0xe9, 0xd0, 0xa1, 0x53, 0xcf, 0xb2, 0x12, 0xf1, 0x96, 0xec, 0x6a, 0x91, 0xb4, 0x19, 0xcc, 0xc7, 0xf6, 0x01, 0xfa, 0x1e, 0x7d, 0x81, 0xce, 0xf4, 0x11, 0xfa, 0xbd, 0xaf, 0xd0, 0xe7, 0xe8, 0x48, 0xbb, 0xda, 0x7f, 0xb1, 0x13, 0xf8, 0xd2, 0x6f, 0xab, 0xa3, 0x9f, 0xce, 0xf9, 0xe9, 0xe8, 0xfc, 0xb3, 0x01, 0x08, 0x0d, 0xd8, 0x4e, 0xc4, 0x99, 0x64, 0xa8, 0x35, 0xf2, 0x23, 0x21, 0x29, 0x17, 0x23, 0x16, 0xe1, 0x7d, 0x58, 0xe8, 0xb9, 0x5c, 0x0e, 0x24, 0x0d, 0xd0, 0x65, 0x80, 0x88, 0x33, 0x12, 0x7b, 0x72, 0xe8, 0x93, 0xae, 0xb5, 0x65, 0xdd, 0x68, 0x3a, 0xcd, 0x54, 0x32, 0x20, 0xc8, 0x86, 0x85, 0xf7, 0xb1, 0x1b, 0x4a, 0x5f, 0x8e, 0xbb, 0xb3, 0x5b, 0xd6, 0x8d, 0x9a, 0x93, 0xad, 0xf1, 0x4b, 0xe8, 0xec, 0x11, 0xa2, 0xb4, 0x38, 0xf4, 0x7d, 0x4c, 0x85, 0x44, 0x17, 0xa0, 0x11, 0x0b, 0xca, 0x73, 0x4d, 0x75, 0xb5, 0x1c, 0x10, 0x74, 0x13, 0xe6, 0x7d, 0x49, 0x03, 0xad, 0xa2, 0xb5, 0xbb, 0xb6, 0x53, 0x60, 0xb3, 0x63, 0xa8, 0x38, 0x1a, 0x82, 0x6f, 0xc1, 0xf2, 0x7e, 0x10, 0xc9, 0xb1, 0x12, 0x9f, 0xa7, 0x17, 0xdf, 0x84, 0x4e, 0x9f, 0xca, 0x4f, 0x82, 0x3e, 0x85, 0x79, 0x85, 0x9b, 0xce, 0xf1, 0x16, 0xd4, 0x14, 0x01, 0xd1, 0x9d, 0xdd, 0x9a, 0x9b, 0x4e, 0x32, 0xc1, 0xe0, 0x06, 0xd4, 0x34, 0x4b, 0xfc, 0x2d, 0xd8, 0x4f, 0x7d, 0x21, 0x1d, 0xea, 0xb1, 0x20, 0xa0, 0x21, 0x71, 0xa5, 0xcf, 0x42, 0x71, 0xae, 0x43, 0xae, 0x40, 0x2b, 0x77, 0x7b, 0x62, 0xb2, 0xe9, 0x40, 0xe6, 0x77, 0x81, 0xbf, 0x80, 0x8d, 0x89, 0x7a, 0x45, 0xc4, 0x42, 0x41, 0xab, 0xe7, 0xad, 0x53, 0xe7, 0x7f, 0xb7, 0xa0, 0xf1, 0x22, 0x59, 0xa2, 0x0e, 0xcc, 0x66, 0x04, 0x66, 0x7d, 0x82, 0x10, 0xcc, 0x87, 0x6e, 0x40, 0xf5, 0x6b, 0x34, 0x1d, 0xfd, 0x8d, 0xb6, 0xa0, 0x45, 0xa8, 0xf0, 0xb8, 0x1f, 0x29, 0x43, 0xdd, 0x39, 0xbd, 0x55, 0x14, 0xa1, 0x2e, 0x34, 0x22, 0xdf, 0x93, 0x31, 0xa7, 0xdd, 0x79, 0xbd, 0x6b, 0x96, 0xe8, 0x2e, 0x34, 0x23, 0xee, 0x7b, 0x74, 0x18, 0x0b, 0xd2, 0xad, 0xe9, 0x27, 0x46, 0x25, 0xef, 0x3d, 0x63, 0x21, 0x1d, 0x3b, 0x0b, 0x1a, 0x74, 0x28, 0x08, 0xda, 0x04, 0xf0, 0x5c, 0x49, 0x8f, 0x18, 0xf7, 0xa9, 0xe8, 0xd6, 0x13, 0xf2, 0xb9, 0x04, 0x3f, 0x81, 0x55, 0x75, 0xf9, 0x94, 0x7f, 0x7e, 0xeb, 0x7b, 0xb0, 0x90, 0x5e, 0x31, 0xb9, 0x72, 0x6b, 0x77, 0xb5, 0x64, 0x27, 0x3d, 0xe0, 0x64, 0x28, 0xbc, 0x0d, 0x2b, 0x7d, 0x6a, 0x14, 0x99, 0x57, 0xa9, 0xf8, 0x03, 0xdf, 0x81, 0xb5, 0x03, 0xea, 0x72, 0x6f, 0x94, 0x1b, 0x4c, 0x80, 0xab, 0x50, 0x7b, 0x1f, 0x53, 0x3e, 0x4e, 0xb1, 0xc9, 0x02, 0x3f, 0x81, 0xf5, 0x2a, 0x3c, 0xe5, 0xb7, 0x03, 0x0d, 0x4e, 0x45, 0x7c, 0x7c, 0x0e, 0x3d, 0x03, 0xc2, 0x21, 0x2c, 0xf5, 0xa9, 0xfc, 0x26, 0x66, 0x92, 0x1a, 0x93, 0x3b, 0xd0, 0x70, 0x09, 0xe1, 0x54, 0x08, 0x6d, 0xb4, 0xaa, 0x62, 0x2f, 0xd9, 0x73, 0x0c, 0xe8, 0xf3, 0xa2, 0x76, 0x0f, 0x96, 0x73, 0x7b, 0x29, 0xe7, 0x3b, 0xb0, 0xe0, 0x31, 0x21, 0xf5, 0xdb, 0x59, 0x53, 0xdf, 0xae, 0xa1, 0x30, 0x87, 0x82, 0x60, 0x06, 0xcb, 0x07, 0x23, 0x3f, 0x7a, 0xce, 0x09, 0xe5, 0xff, 0x08, 0xe7, 0xff, 0xc1, 0x4a, 0xc1, 0x60, 0x1e, 0xfe, 0x92, 0xbb, 0xde, 0x3b, 0x3f, 0x3c, 0xca, 0x73, 0x0b, 0x8c, 0x68, 0x40, 0xf0, 0x2f, 0x16, 0x34, 0x52, 0xbb, 0xe8, 0x1a, 0x74, 0x84, 0xe4, 0x94, 0xca, 0x61, 0x91, 0x65, 0xd3, 0x69, 0x27, 0x52, 0x03, 0x43, 0x30, 0xef, 0x99, 0x32, 0xd7, 0x74, 0xf4, 0xb7, 0x0a, 0x00, 0x21, 0x5d, 0x49, 0xd3, 0x7c, 0x48, 0x16, 0x2a, 0x13, 0x3c, 0x16, 0x87, 0x92, 0x8f, 0x4d, 0x26, 0xa4, 0x4b, 0x74, 0x11, 0x16, 0x3e, 0xfa, 0xd1, 0xd0, 0x63, 0x84, 0xea, 0x44, 0xa8, 0x39, 0x8d, 0x8f, 0x7e, 0xd4, 0x63, 0x84, 0xe2, 0x57, 0x50, 0xd3, 0xae, 0x44, 0xdb, 0xd0, 0xf6, 0x62, 0xce, 0x69, 0xe8, 0x8d, 0x13, 0x60, 0xc2, 0x66, 0xd1, 0x08, 0x15, 0x5a, 0x19, 0x8e, 0x43, 0x5f, 0x0a, 0xcd, 0x66, 0xce, 0x49, 0x16, 0x4a, 0x1a, 0xba, 0x21, 0x13, 0x9a, 0x4e, 0xcd, 0x49, 0x16, 0xb8, 0x0f, 0x9b, 0x7d, 0x2a, 0x0f, 0xe2, 0x28, 0x62, 0x5c, 0x52, 0xd2, 0x4b, 0xf4, 0xf8, 0x34, 0x8f, 0xcb, 0x6b, 0xd0, 0x29, 0x99, 0x34, 0x05, 0xa3, 0x5d, 0xb4, 0x29, 0xf0, 0xf7, 0x70, 0xb1, 0x97, 0x09, 0xc2, 0x13, 0xca, 0x85, 0xcf, 0x42, 0xf3, 0xc8, 0xd7, 0x61, 0xfe, 0x2d, 0x67, 0xc1, 0x19, 0x31, 0xa2, 0xf7, 0x55, 0xc9, 0x93, 0x2c, 0xb9, 0x58, 0xe2, 0xc9, 0xba, 0x64, 0xda, 0x01, 0x7f, 0x59, 0xd0, 0xe9, 0x71, 0x4a, 0x7c, 0x55, 0xaf, 0xc9, 0x20, 0x7c, 0xcb, 0xd0, 0x6d, 0x40, 0x9e, 0x96, 0x0c, 0x3d, 0x97, 0x93, 0x61, 0x18, 0x07, 0x6f, 0x28, 0x4f, 0xfd, 0xb1, 0xec, 0x65, 0xd8, 0xaf, 0xb5, 0x1c, 0x5d, 0x87, 0xa5, 0x22, 0xda, 0x3b, 0x39, 0x49, 0x5b, 0x52, 0x3b, 0x87, 0xf6, 0x4e, 0x4e, 0xd0, 0xff, 0x61, 0xa3, 0x88, 0xa3, 0x1f, 0x22, 0x9f, 0xeb, 0xf2, 0x39, 0x1c, 0x53, 0x97, 0xa7, 0xbe, 0xeb, 0xe6, 0x67, 0xf6, 0x33, 0xc0, 0x77, 0xd4, 0xe5, 0xe8, 0x11, 0x5c, 0x9a, 0x72, 0x3c, 0x60, 0xa1, 0x1c, 0xe9, 0x27, 0xaf, 0x39, 0x17, 0x27, 0x9d, 0x7f, 0xa6, 0x00, 0x78, 0x0c, 0xed, 0xde, 0xc8, 0xe5, 0x47, 0x59, 0x4e, 0xff, 0x07, 0xea, 0x6e, 0xa0, 0x22, 0xe4, 0x0c, 0xe7, 0xa5, 0x08, 0xf4, 0x10, 0x5a, 0x05, 0xeb, 0x69, 0xc3, 0xdc, 0x28, 0x67, 0x48, 0xc9, 0x89, 0x0e, 0xe4, 0x4c, 0xf0, 0x7d, 0xe8, 0x18, 0xd3, 0xf9, 0xd3, 0x4b, 0xee, 0x86, 0xc2, 0xf5, 0xf4, 0x15, 0xb2, 0x64, 0x69, 0x17, 0xa4, 0x03, 0x82, 0x7f, 0x80, 0xa6, 0xce, 0x30, 0x3d, 0x13, 0x98, 0x6e, 0x6d, 0x9d, 0xdb, 0xad, 0x55, 0x54, 0xa8, 0xca, 0x90, 0xf2, 0x9c, 0x18, 0x15, 0x6a, 0x1f, 0xff, 0x34, 0x0b, 0x2d, 0x93, 0xc2, 0xf1, 0xb1, 0x54, 0x89, 0xc2, 0xd4, 0x32, 0x27, 0xd4, 0xd0, 0xeb, 0x01, 0x41, 0xf7, 0x60, 0x55, 0x8c, 0xfc, 0x28, 0x52, 0xb9, 0x5d, 0x4c, 0xf2, 0x24, 0x9a, 0x90, 0xd9, 0x7b, 0x99, 0x25, 0x3b, 0xba, 0x0f, 0xed, 0xec, 0x84, 0x66, 0x33, 0x37, 0x95, 0xcd, 0xa2, 0x01, 0xf6, 0x98, 0x90, 0xe8, 0x11, 0x2c, 0x67, 0x07, 0x4d, 0x6d, 0x98, 0x3f, 0xa3, 0x82, 0x2d, 0x19, 0xb4, 0xa9, 0x19, 0xb7, 0x4d, 0x25, 0xab, 0xe9, 0x4a, 0xb6, 0x5e, 0x3a, 0x95, 0x39, 0xd4, 0x94, 0x32, 0x02, 0x97, 0x0e, 0x68, 0x48, 0xb4, 0xbc, 0xc7, 0xc2, 0xb7, 0x3e, 0x0f, 0x74, 0xd8, 0x14, 0xda, 0x0d, 0x0d, 0x5c, 0xff, 0xd8, 0xb4, 0x1b, 0xbd, 0x40, 0x3b, 0x50, 0xd3, 0xae, 0x49, 0x7d, 0xdc, 0x3d, 0x6d, 0x23, 0xf1, 0xa9, 0x93, 0xc0, 0xf0, 0x9f, 0x16, 0xac, 0xbc, 0x38, 0x76, 0x3d, 0x5a, 0xaa, 0xd1, 0x53, 0x27, 0x91, 0x6d, 0x68, 0xeb, 0x0d, 0x53, 0x0a, 0x52, 0x3f, 0x2f, 0x2a, 0xa1, 0xa9, 0x06, 0xc5, 0x0a, 0x3f, 0xf7, 0x29, 0x15, 0x3e, 0xbb, 0x49, 0xad, 0x78, 0x93, 0x4a, 0x6c, 0xd7, 0x3f, 0x2f, 0xb6, 0x1f, 0x03, 0x2a, 0x5e, 0x2b, 0x6b, 0xb9, 0xa9, 0x77, 0xac, 0x4f, 0xf3, 0xce, 0x0e, 0x34, 0xf7, 0x88, 0x71, 0xca, 0x55, 0x58, 0xf4, 0x58, 0x28, 0xe9, 0x07, 0x39, 0x7c, 0x47, 0xc7, 0xa6, 0x2a, 0xb6, 0x52, 0xd9, 0x57, 0x74, 0x2c, 0xf0, 0x5d, 0x00, 0x85, 0x4f, 0xad, 0x5d, 0x85, 0x39, 0x97, 0x98, 0xe6, 0xbe, 0x54, 0xf1, 0x81, 0xa3, 0xf6, 0xf0, 0x03, 0x98, 0xdd, 0x23, 0x4a, 0xb3, 0x62, 0xce, 0xa9, 0x27, 0x87, 0x31, 0x37, 0x2f, 0xda, 0x32, 0xb2, 0x43, 0x7e, 0xac, 0xfa, 0x8d, 0xb2, 0x62, 0xfa, 0x8d, 0xfa, 0xde, 0xfd, 0xc3, 0x82, 0x96, 0xca, 0xb0, 0x03, 0xca, 0x4f, 0x7c, 0x8f, 0xa2, 0x87, 0xba, 0x8b, 0xe9, 0xa4, 0xdc, 0xa8, 0x7a, 0xbc, 0x30, 0x78, 0xdb, 0xe5, 0x50, 0x4f, 0x26, 0xd3, 0x19, 0xf4, 0x00, 0x1a, 0xe9, 0x74, 0x5c, 0x39, 0x5d, 0x9e, 0x99, 0xed, 0x95, 0x53, 0x19, 0x8e, 0x67, 0xd0, 0x97, 0xd0, 0xcc, 0xe6, 0x70, 0x74, 0xf9, 0xb4, 0xfe, 0xa2, 0x82, 0x89, 0xe6, 0x77, 0x7f, 0xb6, 0x60, 0xad, 0x3c, 0xbf, 0x9a, 0x6b, 0xfd, 0x08, 0xff, 0x9a, 0x30, 0xdc, 0xa2, 0x7f, 0x97, 0xd4, 0x4c, 0x1f, 0xab, 0xed, 0x1b, 0xe7, 0x03, 0x93, 0x07, 0x53, 0x2c, 0x66, 0x61, 0x2d, 0x1d, 0xbc, 0x7a, 0xae, 0x74, 0x8f, 0xd9, 0x91, 0x61, 0xd1, 0x87, 0xc5, 0xe2, 0x94, 0x89, 0x26, 0xdc, 0xc2, 0xbe, 0x7a, 0xca, 0x52, 0x75, 0xe8, 0xc3, 0x33, 0xe8, 0x31, 0x40, 0x3e, 0x64, 0xa2, 0xcd, 0xaa, 0xab, 0xcb, 0xd3, 0xa7, 0x3d, 0x71, 0x26, 0xc4, 0x33, 0xe8, 0x35, 0x74, 0xca, 0x63, 0x25, 0xc2, 0x25, 0xe4, 0xc4, 0x11, 0xd5, 0xde, 0x3e, 0x13, 0x93, 0x79, 0xe1, 0x57, 0x0b, 0x96, 0x0e, 0xd2, 0xe2, 0x65, 0xee, 0x3f, 0x80, 0x05, 0x33, 0x0d, 0xa2, 0x4b, 0x55, 0xd2, 0xc5, 0xa1, 0xd4, 0xbe, 0x3c, 0x65, 0x37, 0xf3, 0xc0, 0x53, 0x68, 0x66, 0x43, 0x5a, 0x25, 0x58, 0xaa, 0xd3, 0xa2, 0xbd, 0x39, 0x6d, 0x3b, 0x23, 0xfb, 0x9b, 0x05, 0x4b, 0xa6, 0xf4, 0x18, 0xb2, 0xaf, 0x61, 0x7d, 0xf2, 0x90, 0x33, 0xf1, 0xd9, 0x6e, 0x55, 0x09, 0x9f, 0x31, 0x1d, 0xe1, 0x19, 0xd4, 0x87, 0x46, 0x32, 0xf0, 0x48, 0x74, 0xbd, 0x9c, 0x0b, 0xd3, 0xc6, 0x21, 0x7b, 0x42, 0x73, 0xc1, 0x33, 0xbb, 0x87, 0xd0, 0x79, 0xe1, 0x8e, 0x03, 0x1a, 0x66, 0x19, 0xdc, 0x83, 0x7a, 0xd2, 0x91, 0x91, 0x5d, 0xd6, 0x5c, 0x9c, 0x10, 0xec, 0x8d, 0x89, 0x7b, 0x99, 0x43, 0x46, 0xb0, 0xb8, 0xaf, 0x2a, 0xa8, 0x51, 0xfa, 0x4a, 0xfd, 0x60, 0x99, 0xd0, 0x48, 0xd0, 0xcd, 0x4a, 0x34, 0x4c, 0x6f, 0x36, 0x53, 0x72, 0xf6, 0x0d, 0x2c, 0xf5, 0x46, 0xd4, 0x7b, 0xc7, 0xe2, 0xec, 0x06, 0xcf, 0x01, 0xf2, 0xba, 0x5b, 0x89, 0xee, 0x53, 0x7d, 0xc6, 0xbe, 0x32, 0x75, 0x3f, 0xbb, 0xcd, 0x13, 0x55, 0x82, 0x8d, 0xf6, 0x07, 0x50, 0xef, 0xab, 0x19, 0x5c, 0xa0, 0xf5, 0x6a, 0x39, 0x4d, 0x35, 0x5e, 0x38, 0x25, 0x37, 0x9a, 0xde, 0xd4, 0xf5, 0x9f, 0x1b, 0xff, 0xfd, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xb2, 0xa0, 0x6e, 0x6c, 0xea, 0x10, 0x00, 0x00, } ================================================ FILE: microservices-demo/src/frontend/genproto.sh ================================================ #!/bin/bash -eu # # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # [START gke_frontend_genproto] PATH=$PATH:$GOPATH/bin protodir=../../pb protoc --go_out=plugins=grpc:genproto -I $protodir $protodir/demo.proto # [END gke_frontend_genproto] ================================================ FILE: microservices-demo/src/frontend/go.mod ================================================ module github.com/GoogleCloudPlatform/microservices-demo/src/frontend go 1.18 require ( cloud.google.com/go v0.104.0 cloud.google.com/go/compute v1.7.0 cloud.google.com/go/profiler v0.3.0 contrib.go.opencensus.io/exporter/jaeger v0.2.1 contrib.go.opencensus.io/exporter/stackdriver v0.13.12 github.com/golang/protobuf v1.5.2 github.com/google/uuid v1.3.0 github.com/gorilla/mux v1.8.0 github.com/pkg/errors v0.9.1 github.com/sirupsen/logrus v1.8.1 go.opencensus.io v0.23.0 golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b google.golang.org/grpc v1.48.0 ) require ( cloud.google.com/go/monitoring v1.1.0 // indirect cloud.google.com/go/trace v1.0.0 // indirect github.com/aws/aws-sdk-go v1.43.31 // indirect github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect github.com/cespare/xxhash/v2 v2.1.1 // indirect github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 // indirect github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 // indirect github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 // indirect github.com/envoyproxy/protoc-gen-validate v0.1.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/go-cmp v0.5.8 // indirect github.com/google/pprof v0.0.0-20220412212628-83db2b799d1f // indirect github.com/googleapis/enterprise-certificate-proxy v0.1.0 // indirect github.com/googleapis/gax-go/v2 v2.4.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/prometheus/prometheus v2.5.0+incompatible // indirect github.com/uber/jaeger-client-go v2.25.0+incompatible // indirect golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 // indirect golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect golang.org/x/text v0.3.7 // indirect google.golang.org/api v0.93.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc // indirect google.golang.org/protobuf v1.28.1 // indirect ) ================================================ FILE: microservices-demo/src/frontend/go.sum ================================================ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go v0.99.0 h1:y/cM2iqGgGi5D5DQZl6D9STN/3dR/Vx5Mp8s752oJTY= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= cloud.google.com/go v0.102.0 h1:DAq3r8y4mDgyB/ZPJ9v/5VJNqjgJAxTn6ZYLlUywOu8= cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= cloud.google.com/go v0.102.1 h1:vpK6iQWv/2uUeFJth4/cBHsQAGjn1iIE6AAlxipRaA0= cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= cloud.google.com/go v0.104.0 h1:gSmWO7DY1vOm0MVU6DNXM11BWHHsTUmsC5cv1fuW5X8= cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= cloud.google.com/go/compute v1.5.0 h1:b1zWmYuuHz7gO9kDcM/EpHGr06UgsYNRpNJzI2kFiLM= cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= cloud.google.com/go/compute v1.6.1 h1:2sMmt8prCn7DPaG4Pmh0N3Inmc8cT8ae5k1M6VJ9Wqc= cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= cloud.google.com/go/compute v1.7.0 h1:v/k9Eueb8aAJ0vZuxKMrgm6kPhCLZU9HxFU+AFDs9Uk= cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/monitoring v1.1.0 h1:ZnyNdf/XRcynMmKzRSNTOdOyYPs6G7do1l2D2hIvIKo= cloud.google.com/go/monitoring v1.1.0/go.mod h1:L81pzz7HKn14QCMaCs6NTQkdBnE87TElyanS95vIcl4= cloud.google.com/go/profiler v0.1.1 h1:seMHZtcgOwZXAOKDZuW2sN3u1yKjYG19dUkElb4mbcQ= cloud.google.com/go/profiler v0.1.1/go.mod h1:zG22vSCuJKJMvIlLpX3FhNjOsifaoLdPAYc4yLw5Iw4= cloud.google.com/go/profiler v0.3.0 h1:R6y/xAeifaUXxd2x6w+jIwKxoKl8Cv5HJvcvASTPWJo= cloud.google.com/go/profiler v0.3.0/go.mod h1:9wYk9eY4iZHsev8TQb61kh3wiOiSyz/xOYixWPzweCU= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= cloud.google.com/go/trace v1.0.0 h1:laKx2y7IWMjguCe5zZx6n7qLtREk4kyE69SXVC0VSN8= cloud.google.com/go/trace v1.0.0/go.mod h1:4iErSByzxkyHWzzlAj63/Gmjz0NH1ASqhJguHpGcr6A= contrib.go.opencensus.io/exporter/jaeger v0.2.1 h1:yGBYzYMewVL0yO9qqJv3Z5+IRhPdU7e9o/2oKpX4YvI= contrib.go.opencensus.io/exporter/jaeger v0.2.1/go.mod h1:Y8IsLgdxqh1QxYxPC5IgXVmBaeLUeQFfBeBi9PbeZd0= contrib.go.opencensus.io/exporter/stackdriver v0.13.10 h1:a9+GZPUe+ONKUwULjlEOucMMG0qfSCCenlji0Nhqbys= contrib.go.opencensus.io/exporter/stackdriver v0.13.10/go.mod h1:I5htMbyta491eUxufwwZPQdcKvvgzMB4O9ni41YnIM8= contrib.go.opencensus.io/exporter/stackdriver v0.13.12 h1:bjBKzIf7/TAkxd7L2utGaLM78bmUWlCval5K9UeElbY= contrib.go.opencensus.io/exporter/stackdriver v0.13.12/go.mod h1:mmxnWlrvrFdpiOHOhxBaVi1rkc0WOqhgfknj4Yg0SeQ= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/aws/aws-sdk-go v1.37.0 h1:GzFnhOIsrGyQ69s7VgqtrG2BG8v7X7vwB3Xpbd/DBBk= github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.43.31 h1:yJZIr8nMV1hXjAvvOLUFqZRJcHV7udPQBfhJqawDzI0= github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 h1:hzAQntlaYRkVSFEfj9OTWlVV1H155FMD8BTKktLv0QI= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 h1:zH8ljVhhq7yC0MIeUL/IviMtY8hx2mK8cN9wEYb8ggw= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021 h1:fP+fF0up6oPY49OrjPrhIJ8yQfdIM85NXMLkMg1EXVs= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 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.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= 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/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20211008130755-947d60d73cc0 h1:zHs+jv3LO743/zFGcByu2KmpbliCU2AhjcGgrdTwSG4= github.com/google/pprof v0.0.0-20211008130755-947d60d73cc0/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= github.com/google/pprof v0.0.0-20220412212628-83db2b799d1f h1:VrKTY4lquiy1oJzVZgXrauku9Jx9P+POv/gTLakG4Wk= github.com/google/pprof v0.0.0-20220412212628-83db2b799d1f/go.mod h1:Pt31oes+eGImORns3McJn8zHefuQl2rG8l6xQjGYB4U= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa h1:7MYGT2XEMam7Mtzv1yDUYXANedWvwk3HKkR3MyGowy8= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.1.0 h1:zO8WHNx/MYiAKJ3d5spxZXZE6KHmIQGQcAzwUzV7qQw= github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= github.com/googleapis/gax-go/v2 v2.2.0 h1:s7jOdKSaksJVOxE0Y/S32otcfiP+UQ0cL8/GTKaONwE= github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= github.com/googleapis/gax-go/v2 v2.4.0 h1:dS9eYAjhrE2RjmzYw2XAPvcXfmcQLtFEQWn0CR82awk= github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/prometheus v2.5.0+incompatible h1:7QPitgO2kOFG8ecuRn9O/4L9+10He72rVRJvMXrE9Hg= github.com/prometheus/prometheus v2.5.0+incompatible/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/uber/jaeger-client-go v2.25.0+incompatible h1:IxcNZ7WRY1Y3G4poYlx24szfsn/3LvK9QHCq9oQw8+U= github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 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.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220403103023-749bd193bc2b h1:vI32FkLJNAWtGD4BwkThwEy6XS7ZLLMHkSkYfF8M0W0= golang.org/x/net v0.0.0-20220403103023-749bd193bc2b/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220420153159-1850ba15e1be h1:yx80W7nvY5ySWpaU8UWaj5o9e23YgO9BRhQol7Lc+JI= golang.org/x/net v0.0.0-20220420153159-1850ba15e1be/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d h1:4SFsTMi4UahlKoloni7L4eYzhFRifURQLw+yv0QDCx8= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b h1:3ogNYyK4oIQdIKzTu68hQrr4iuVxF3AxKl9Aj/eDrw0= golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220805013720-a33c5aa5df48 h1:N9Vc/rorQUDes6B9CNdIxAn5jODGj2wzfrei2x4wNj4= golang.org/x/net v0.0.0-20220805013720-a33c5aa5df48/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220809012201-f428fae20770 h1:dIi4qVdvjZEjiMDv7vhokAZNGnz3kepwuXqFKYDdDMs= golang.org/x/net v0.0.0-20220809012201-f428fae20770/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220809184613-07c6da5e1ced h1:3dYNDff0VT5xj+mbj2XucFst9WKk6PdGOrb9n+SbIvw= golang.org/x/net v0.0.0-20220809184613-07c6da5e1ced/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E= golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb h1:8tDJ3aechhddbdPAxpycgXHJRMLpk/Ab+aa4OgdN5/g= golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 h1:+jnHzr9VPj32ykQVai5DNahi9+NSp7yYuCsl5eAQtL0= golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/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-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886 h1:eJv7u3ksNXoLbGSKuv2s/SIO4tJVxc/A+MTpzxDgz/Q= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba h1:AyHWHCBVlIYI5rgEM3o+1PLd0sLPcIAoaUckGQMaWtw= golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 h1:nonptSpoQ4vQjyraW20DXPAglgQfVnM9ZC6MmNLMR60= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d h1:Zu/JngovGLVi6t2J3nmAf3AoTDwuzw85YZ3b9o4yU7s= golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E= google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= google.golang.org/api v0.61.0 h1:TXXKS1slM3b2bZNJwD5DV/Tp6/M2cLzLOLh9PjDhrw8= google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= google.golang.org/api v0.74.0 h1:ExR2D+5TYIrMphWgs5JCgwRhEDlPDXXrLwHHMgPHTXE= google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= google.golang.org/api v0.78.0 h1:5ewPyCwP43C3i8B6C2Kb+eVAevbnke2xR8VbcSWjS4I= google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= google.golang.org/api v0.80.0 h1:IQWaGVCYnsm4MO3hh+WtSXMzMzuyFx/fuR8qkN3A0Qo= google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= google.golang.org/api v0.84.0 h1:NMB9J4cCxs9xEm+1Z9QiO3eFvn7EnQj3Eo3hN6ugVlg= google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= google.golang.org/api v0.93.0 h1:T2xt9gi0gHdxdnRkVQhT8mIvPaXKNsDNWz+L696M66M= google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210921142501-181ce0d877f6/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211018162055-cf77aa76bad2/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0 h1:c7yRRmuQiVMo+YppNj5MUREXUyc2lPo3DrtYMwaWQ28= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb h1:0m9wktIpOxGw+SSKmydXWB3Z3GTfcPP6+q75HCQa6HI= google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335 h1:2D0OT6tPVdrQTOnVe1VQjfJPTED6EZ7fdJ/f6Db6OsY= google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20220523171625-347a074981d8 h1:4NSrVrQGh6+UqBEd+Kwdh6ZDwESH0Sj2bNUQN+VjoQk= google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad h1:kqrS+lhvaMHCxul6sKQvKJ8nAAhlVItmZV822hYFH/U= google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc h1:Nf+EdcTLHR8qDNN/KfkQL0u0ssxt9OhbaWCl5C0ucEI= google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.43.0 h1:Eeu7bZtDZ2DpRCsLhUlcrLnvYaMK1Gz86a+hMVvELmM= google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.46.0 h1:oCjezcn6g6A75TGoKYBPgKmVBLexhYLM6MebdrPApP8= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= ================================================ FILE: microservices-demo/src/frontend/handlers.go ================================================ // Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "context" "fmt" "html/template" "math/rand" "net" "net/http" "os" "strconv" "strings" "time" "github.com/gorilla/mux" "github.com/pkg/errors" "github.com/sirupsen/logrus" pb "github.com/GoogleCloudPlatform/microservices-demo/src/frontend/genproto" "github.com/GoogleCloudPlatform/microservices-demo/src/frontend/money" ) type platformDetails struct { css string provider string } var ( isCymbalBrand = "true" == strings.ToLower(os.Getenv("CYMBAL_BRANDING")) templates = template.Must(template.New(""). Funcs(template.FuncMap{ "renderMoney": renderMoney, "renderCurrencyLogo": renderCurrencyLogo, }).ParseGlob("templates/*.html")) plat platformDetails ) var validEnvs = []string{"local", "gcp", "azure", "aws", "onprem", "alibaba"} func (fe *frontendServer) homeHandler(w http.ResponseWriter, r *http.Request) { log := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger) log.WithField("currency", currentCurrency(r)).Info("home") currencies, err := fe.getCurrencies(r.Context()) if err != nil { renderHTTPError(log, r, w, errors.Wrap(err, "could not retrieve currencies"), http.StatusInternalServerError) return } products, err := fe.getProducts(r.Context()) if err != nil { renderHTTPError(log, r, w, errors.Wrap(err, "could not retrieve products"), http.StatusInternalServerError) return } cart, err := fe.getCart(r.Context(), sessionID(r)) if err != nil { renderHTTPError(log, r, w, errors.Wrap(err, "could not retrieve cart"), http.StatusInternalServerError) return } type productView struct { Item *pb.Product Price *pb.Money } ps := make([]productView, len(products)) for i, p := range products { price, err := fe.convertCurrency(r.Context(), p.GetPriceUsd(), currentCurrency(r)) if err != nil { renderHTTPError(log, r, w, errors.Wrapf(err, "failed to do currency conversion for product %s", p.GetId()), http.StatusInternalServerError) return } ps[i] = productView{p, price} } // Set ENV_PLATFORM (default to local if not set; use env var if set; otherwise detect GCP, which overrides env)_ var env = os.Getenv("ENV_PLATFORM") // Only override from env variable if set + valid env if env == "" || stringinSlice(validEnvs, env) == false { fmt.Println("env platform is either empty or invalid") env = "local" } // Autodetect GCP addrs, err := net.LookupHost("metadata.google.internal.") if err == nil && len(addrs) >= 0 { log.Debugf("Detected Google metadata server: %v, setting ENV_PLATFORM to GCP.", addrs) env = "gcp" } log.Debugf("ENV_PLATFORM is: %s", env) plat = platformDetails{} plat.setPlatformDetails(strings.ToLower(env)) if err := templates.ExecuteTemplate(w, "home", map[string]interface{}{ "session_id": sessionID(r), "request_id": r.Context().Value(ctxKeyRequestID{}), "user_currency": currentCurrency(r), "show_currency": true, "currencies": currencies, "products": ps, "cart_size": cartSize(cart), "banner_color": os.Getenv("BANNER_COLOR"), // illustrates canary deployments "ad": fe.chooseAd(r.Context(), []string{}, log), "platform_css": plat.css, "platform_name": plat.provider, "is_cymbal_brand": isCymbalBrand, "deploymentDetails": deploymentDetailsMap, }); err != nil { log.Error(err) } } func (plat *platformDetails) setPlatformDetails(env string) { if env == "aws" { plat.provider = "AWS" plat.css = "aws-platform" } else if env == "onprem" { plat.provider = "On-Premises" plat.css = "onprem-platform" } else if env == "azure" { plat.provider = "Azure" plat.css = "azure-platform" } else if env == "gcp" { plat.provider = "Google Cloud" plat.css = "gcp-platform" } else if env == "alibaba" { plat.provider = "Alibaba Cloud" plat.css = "alibaba-platform" } else { plat.provider = "local" plat.css = "local" } } func (fe *frontendServer) productHandler(w http.ResponseWriter, r *http.Request) { log := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger) id := mux.Vars(r)["id"] if id == "" { renderHTTPError(log, r, w, errors.New("product id not specified"), http.StatusBadRequest) return } log.WithField("id", id).WithField("currency", currentCurrency(r)). Debug("serving product page") p, err := fe.getProduct(r.Context(), id) if err != nil { renderHTTPError(log, r, w, errors.Wrap(err, "could not retrieve product"), http.StatusInternalServerError) return } currencies, err := fe.getCurrencies(r.Context()) if err != nil { renderHTTPError(log, r, w, errors.Wrap(err, "could not retrieve currencies"), http.StatusInternalServerError) return } cart, err := fe.getCart(r.Context(), sessionID(r)) if err != nil { renderHTTPError(log, r, w, errors.Wrap(err, "could not retrieve cart"), http.StatusInternalServerError) return } price, err := fe.convertCurrency(r.Context(), p.GetPriceUsd(), currentCurrency(r)) if err != nil { renderHTTPError(log, r, w, errors.Wrap(err, "failed to convert currency"), http.StatusInternalServerError) return } recommendations, err := fe.getRecommendations(r.Context(), sessionID(r), []string{id}) if err != nil { renderHTTPError(log, r, w, errors.Wrap(err, "failed to get product recommendations"), http.StatusInternalServerError) return } product := struct { Item *pb.Product Price *pb.Money }{p, price} if err := templates.ExecuteTemplate(w, "product", map[string]interface{}{ "session_id": sessionID(r), "request_id": r.Context().Value(ctxKeyRequestID{}), "ad": fe.chooseAd(r.Context(), p.Categories, log), "user_currency": currentCurrency(r), "show_currency": true, "currencies": currencies, "product": product, "recommendations": recommendations, "cart_size": cartSize(cart), "platform_css": plat.css, "platform_name": plat.provider, "is_cymbal_brand": isCymbalBrand, "deploymentDetails": deploymentDetailsMap, }); err != nil { log.Println(err) } } func (fe *frontendServer) addToCartHandler(w http.ResponseWriter, r *http.Request) { log := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger) quantity, _ := strconv.ParseUint(r.FormValue("quantity"), 10, 32) productID := r.FormValue("product_id") if productID == "" || quantity == 0 { renderHTTPError(log, r, w, errors.New("invalid form input"), http.StatusBadRequest) return } log.WithField("product", productID).WithField("quantity", quantity).Debug("adding to cart") p, err := fe.getProduct(r.Context(), productID) if err != nil { renderHTTPError(log, r, w, errors.Wrap(err, "could not retrieve product"), http.StatusInternalServerError) return } if err := fe.insertCart(r.Context(), sessionID(r), p.GetId(), int32(quantity)); err != nil { renderHTTPError(log, r, w, errors.Wrap(err, "failed to add to cart"), http.StatusInternalServerError) return } w.Header().Set("location", "/cart") w.WriteHeader(http.StatusFound) } func (fe *frontendServer) emptyCartHandler(w http.ResponseWriter, r *http.Request) { log := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger) log.Debug("emptying cart") if err := fe.emptyCart(r.Context(), sessionID(r)); err != nil { renderHTTPError(log, r, w, errors.Wrap(err, "failed to empty cart"), http.StatusInternalServerError) return } w.Header().Set("location", "/") w.WriteHeader(http.StatusFound) } func (fe *frontendServer) viewCartHandler(w http.ResponseWriter, r *http.Request) { log := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger) log.Debug("view user cart") currencies, err := fe.getCurrencies(r.Context()) if err != nil { renderHTTPError(log, r, w, errors.Wrap(err, "could not retrieve currencies"), http.StatusInternalServerError) return } cart, err := fe.getCart(r.Context(), sessionID(r)) if err != nil { renderHTTPError(log, r, w, errors.Wrap(err, "could not retrieve cart"), http.StatusInternalServerError) return } recommendations, err := fe.getRecommendations(r.Context(), sessionID(r), cartIDs(cart)) if err != nil { renderHTTPError(log, r, w, errors.Wrap(err, "failed to get product recommendations"), http.StatusInternalServerError) return } shippingCost, err := fe.getShippingQuote(r.Context(), cart, currentCurrency(r)) if err != nil { renderHTTPError(log, r, w, errors.Wrap(err, "failed to get shipping quote"), http.StatusInternalServerError) return } type cartItemView struct { Item *pb.Product Quantity int32 Price *pb.Money } items := make([]cartItemView, len(cart)) totalPrice := pb.Money{CurrencyCode: currentCurrency(r)} for i, item := range cart { p, err := fe.getProduct(r.Context(), item.GetProductId()) if err != nil { renderHTTPError(log, r, w, errors.Wrapf(err, "could not retrieve product #%s", item.GetProductId()), http.StatusInternalServerError) return } price, err := fe.convertCurrency(r.Context(), p.GetPriceUsd(), currentCurrency(r)) if err != nil { renderHTTPError(log, r, w, errors.Wrapf(err, "could not convert currency for product #%s", item.GetProductId()), http.StatusInternalServerError) return } multPrice := money.MultiplySlow(*price, uint32(item.GetQuantity())) items[i] = cartItemView{ Item: p, Quantity: item.GetQuantity(), Price: &multPrice} totalPrice = money.Must(money.Sum(totalPrice, multPrice)) } totalPrice = money.Must(money.Sum(totalPrice, *shippingCost)) year := time.Now().Year() if err := templates.ExecuteTemplate(w, "cart", map[string]interface{}{ "session_id": sessionID(r), "request_id": r.Context().Value(ctxKeyRequestID{}), "user_currency": currentCurrency(r), "currencies": currencies, "recommendations": recommendations, "cart_size": cartSize(cart), "shipping_cost": shippingCost, "show_currency": true, "total_cost": totalPrice, "items": items, "expiration_years": []int{year, year + 1, year + 2, year + 3, year + 4}, "platform_css": plat.css, "platform_name": plat.provider, "is_cymbal_brand": isCymbalBrand, "deploymentDetails": deploymentDetailsMap, }); err != nil { log.Println(err) } } func (fe *frontendServer) placeOrderHandler(w http.ResponseWriter, r *http.Request) { log := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger) log.Debug("placing order") var ( email = r.FormValue("email") streetAddress = r.FormValue("street_address") zipCode, _ = strconv.ParseInt(r.FormValue("zip_code"), 10, 32) city = r.FormValue("city") state = r.FormValue("state") country = r.FormValue("country") ccNumber = r.FormValue("credit_card_number") ccMonth, _ = strconv.ParseInt(r.FormValue("credit_card_expiration_month"), 10, 32) ccYear, _ = strconv.ParseInt(r.FormValue("credit_card_expiration_year"), 10, 32) ccCVV, _ = strconv.ParseInt(r.FormValue("credit_card_cvv"), 10, 32) ) order, err := pb.NewCheckoutServiceClient(fe.checkoutSvcConn). PlaceOrder(r.Context(), &pb.PlaceOrderRequest{ Email: email, CreditCard: &pb.CreditCardInfo{ CreditCardNumber: ccNumber, CreditCardExpirationMonth: int32(ccMonth), CreditCardExpirationYear: int32(ccYear), CreditCardCvv: int32(ccCVV)}, UserId: sessionID(r), UserCurrency: currentCurrency(r), Address: &pb.Address{ StreetAddress: streetAddress, City: city, State: state, ZipCode: int32(zipCode), Country: country}, }) if err != nil { renderHTTPError(log, r, w, errors.Wrap(err, "failed to complete the order"), http.StatusInternalServerError) return } log.WithField("order", order.GetOrder().GetOrderId()).Info("order placed") order.GetOrder().GetItems() recommendations, _ := fe.getRecommendations(r.Context(), sessionID(r), nil) totalPaid := *order.GetOrder().GetShippingCost() for _, v := range order.GetOrder().GetItems() { multPrice := money.MultiplySlow(*v.GetCost(), uint32(v.GetItem().GetQuantity())) totalPaid = money.Must(money.Sum(totalPaid, multPrice)) } currencies, err := fe.getCurrencies(r.Context()) if err != nil { renderHTTPError(log, r, w, errors.Wrap(err, "could not retrieve currencies"), http.StatusInternalServerError) return } if err := templates.ExecuteTemplate(w, "order", map[string]interface{}{ "session_id": sessionID(r), "request_id": r.Context().Value(ctxKeyRequestID{}), "user_currency": currentCurrency(r), "show_currency": false, "currencies": currencies, "order": order.GetOrder(), "total_paid": &totalPaid, "recommendations": recommendations, "platform_css": plat.css, "platform_name": plat.provider, "is_cymbal_brand": isCymbalBrand, "deploymentDetails": deploymentDetailsMap, }); err != nil { log.Println(err) } } func (fe *frontendServer) logoutHandler(w http.ResponseWriter, r *http.Request) { log := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger) log.Debug("logging out") for _, c := range r.Cookies() { c.Expires = time.Now().Add(-time.Hour * 24 * 365) c.MaxAge = -1 http.SetCookie(w, c) } w.Header().Set("Location", "/") w.WriteHeader(http.StatusFound) } func (fe *frontendServer) setCurrencyHandler(w http.ResponseWriter, r *http.Request) { log := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger) cur := r.FormValue("currency_code") log.WithField("curr.new", cur).WithField("curr.old", currentCurrency(r)). Debug("setting currency") if cur != "" { http.SetCookie(w, &http.Cookie{ Name: cookieCurrency, Value: cur, MaxAge: cookieMaxAge, }) } referer := r.Header.Get("referer") if referer == "" { referer = "/" } w.Header().Set("Location", referer) w.WriteHeader(http.StatusFound) } // chooseAd queries for advertisements available and randomly chooses one, if // available. It ignores the error retrieving the ad since it is not critical. func (fe *frontendServer) chooseAd(ctx context.Context, ctxKeys []string, log logrus.FieldLogger) *pb.Ad { ads, err := fe.getAd(ctx, ctxKeys) if err != nil { log.WithField("error", err).Warn("failed to retrieve ads") return nil } return ads[rand.Intn(len(ads))] } func renderHTTPError(log logrus.FieldLogger, r *http.Request, w http.ResponseWriter, err error, code int) { log.WithField("error", err).Error("request error") errMsg := fmt.Sprintf("%+v", err) w.WriteHeader(code) if templateErr := templates.ExecuteTemplate(w, "error", map[string]interface{}{ "session_id": sessionID(r), "request_id": r.Context().Value(ctxKeyRequestID{}), "error": errMsg, "status_code": code, "status": http.StatusText(code), "deploymentDetails": deploymentDetailsMap, }); templateErr != nil { log.Println(templateErr) } } func currentCurrency(r *http.Request) string { c, _ := r.Cookie(cookieCurrency) if c != nil { return c.Value } return defaultCurrency } func sessionID(r *http.Request) string { v := r.Context().Value(ctxKeySessionID{}) if v != nil { return v.(string) } return "" } func cartIDs(c []*pb.CartItem) []string { out := make([]string, len(c)) for i, v := range c { out[i] = v.GetProductId() } return out } // get total # of items in cart func cartSize(c []*pb.CartItem) int { cartSize := 0 for _, item := range c { cartSize += int(item.GetQuantity()) } return cartSize } func renderMoney(money pb.Money) string { currencyLogo := renderCurrencyLogo(money.GetCurrencyCode()) return fmt.Sprintf("%s%d.%02d", currencyLogo, money.GetUnits(), money.GetNanos()/10000000) } func renderCurrencyLogo(currencyCode string) string { logos := map[string]string{ "USD": "$", "CAD": "$", "JPY": "¥", "EUR": "€", "TRY": "₺", "GBP": "£", } logo := "$" //default if val, ok := logos[currencyCode]; ok { logo = val } return logo } func stringinSlice(slice []string, val string) bool { for _, item := range slice { if item == val { return true } } return false } ================================================ FILE: microservices-demo/src/frontend/main.go ================================================ // Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "context" "fmt" "net/http" "os" "time" "cloud.google.com/go/profiler" "contrib.go.opencensus.io/exporter/jaeger" "contrib.go.opencensus.io/exporter/stackdriver" "github.com/gorilla/mux" "github.com/pkg/errors" "github.com/sirupsen/logrus" "go.opencensus.io/plugin/ocgrpc" "go.opencensus.io/plugin/ochttp" "go.opencensus.io/plugin/ochttp/propagation/b3" "go.opencensus.io/stats/view" "go.opencensus.io/trace" "google.golang.org/grpc" ) const ( port = "8080" defaultCurrency = "USD" cookieMaxAge = 60 * 60 * 48 cookiePrefix = "shop_" cookieSessionID = cookiePrefix + "session-id" cookieCurrency = cookiePrefix + "currency" ) var ( whitelistedCurrencies = map[string]bool{ "USD": true, "EUR": true, "CAD": true, "JPY": true, "GBP": true, "TRY": true} ) type ctxKeySessionID struct{} type frontendServer struct { productCatalogSvcAddr string productCatalogSvcConn *grpc.ClientConn currencySvcAddr string currencySvcConn *grpc.ClientConn cartSvcAddr string cartSvcConn *grpc.ClientConn recommendationSvcAddr string recommendationSvcConn *grpc.ClientConn checkoutSvcAddr string checkoutSvcConn *grpc.ClientConn shippingSvcAddr string shippingSvcConn *grpc.ClientConn adSvcAddr string adSvcConn *grpc.ClientConn } func main() { ctx := context.Background() log := logrus.New() log.Level = logrus.DebugLevel log.Formatter = &logrus.JSONFormatter{ FieldMap: logrus.FieldMap{ logrus.FieldKeyTime: "timestamp", logrus.FieldKeyLevel: "severity", logrus.FieldKeyMsg: "message", }, TimestampFormat: time.RFC3339Nano, } log.Out = os.Stdout if os.Getenv("DISABLE_TRACING") == "" { log.Info("Tracing enabled.") go initTracing(log) } else { log.Info("Tracing disabled.") } if os.Getenv("DISABLE_PROFILER") == "" { log.Info("Profiling enabled.") go initProfiling(log, "frontend", "1.0.0") } else { log.Info("Profiling disabled.") } srvPort := port if os.Getenv("PORT") != "" { srvPort = os.Getenv("PORT") } addr := os.Getenv("LISTEN_ADDR") svc := new(frontendServer) mustMapEnv(&svc.productCatalogSvcAddr, "PRODUCT_CATALOG_SERVICE_ADDR") mustMapEnv(&svc.currencySvcAddr, "CURRENCY_SERVICE_ADDR") mustMapEnv(&svc.cartSvcAddr, "CART_SERVICE_ADDR") mustMapEnv(&svc.recommendationSvcAddr, "RECOMMENDATION_SERVICE_ADDR") mustMapEnv(&svc.checkoutSvcAddr, "CHECKOUT_SERVICE_ADDR") mustMapEnv(&svc.shippingSvcAddr, "SHIPPING_SERVICE_ADDR") mustMapEnv(&svc.adSvcAddr, "AD_SERVICE_ADDR") mustConnGRPC(ctx, &svc.currencySvcConn, svc.currencySvcAddr) mustConnGRPC(ctx, &svc.productCatalogSvcConn, svc.productCatalogSvcAddr) mustConnGRPC(ctx, &svc.cartSvcConn, svc.cartSvcAddr) mustConnGRPC(ctx, &svc.recommendationSvcConn, svc.recommendationSvcAddr) mustConnGRPC(ctx, &svc.shippingSvcConn, svc.shippingSvcAddr) mustConnGRPC(ctx, &svc.checkoutSvcConn, svc.checkoutSvcAddr) mustConnGRPC(ctx, &svc.adSvcConn, svc.adSvcAddr) r := mux.NewRouter() r.HandleFunc("/", svc.homeHandler).Methods(http.MethodGet, http.MethodHead) r.HandleFunc("/product/{id}", svc.productHandler).Methods(http.MethodGet, http.MethodHead) r.HandleFunc("/cart", svc.viewCartHandler).Methods(http.MethodGet, http.MethodHead) r.HandleFunc("/cart", svc.addToCartHandler).Methods(http.MethodPost) r.HandleFunc("/cart/empty", svc.emptyCartHandler).Methods(http.MethodPost) r.HandleFunc("/setCurrency", svc.setCurrencyHandler).Methods(http.MethodPost) r.HandleFunc("/logout", svc.logoutHandler).Methods(http.MethodGet) r.HandleFunc("/cart/checkout", svc.placeOrderHandler).Methods(http.MethodPost) r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("./static/")))) r.HandleFunc("/robots.txt", func(w http.ResponseWriter, _ *http.Request) { fmt.Fprint(w, "User-agent: *\nDisallow: /") }) r.HandleFunc("/_healthz", func(w http.ResponseWriter, _ *http.Request) { fmt.Fprint(w, "ok") }) var handler http.Handler = r handler = &logHandler{log: log, next: handler} // add logging handler = ensureSessionID(handler) // add session ID handler = &ochttp.Handler{ // add opencensus instrumentation Handler: handler, Propagation: &b3.HTTPFormat{}} log.Infof("starting server on " + addr + ":" + srvPort) log.Fatal(http.ListenAndServe(addr+":"+srvPort, handler)) } func initJaegerTracing(log logrus.FieldLogger) { svcAddr := os.Getenv("JAEGER_SERVICE_ADDR") if svcAddr == "" { log.Info("jaeger initialization disabled.") return } // Register the Jaeger exporter to be able to retrieve // the collected spans. exporter, err := jaeger.NewExporter(jaeger.Options{ Endpoint: fmt.Sprintf("http://%s", svcAddr), Process: jaeger.Process{ ServiceName: "frontend", }, }) if err != nil { log.Fatal(err) } trace.RegisterExporter(exporter) log.Info("jaeger initialization completed.") } func initStats(log logrus.FieldLogger, exporter *stackdriver.Exporter) { view.SetReportingPeriod(60 * time.Second) view.RegisterExporter(exporter) if err := view.Register(ochttp.DefaultServerViews...); err != nil { log.Warn("Error registering http default server views") } else { log.Info("Registered http default server views") } if err := view.Register(ocgrpc.DefaultClientViews...); err != nil { log.Warn("Error registering grpc default client views") } else { log.Info("Registered grpc default client views") } } func initStackdriverTracing(log logrus.FieldLogger) { // TODO(ahmetb) this method is duplicated in other microservices using Go // since they are not sharing packages. for i := 1; i <= 3; i++ { log = log.WithField("retry", i) exporter, err := stackdriver.NewExporter(stackdriver.Options{}) if err != nil { // log.Warnf is used since there are multiple backends (stackdriver & jaeger) // to store the traces. In production setup most likely you would use only one backend. // In that case you should use log.Fatalf. log.Warnf("failed to initialize Stackdriver exporter: %+v", err) } else { trace.RegisterExporter(exporter) log.Info("registered Stackdriver tracing") // Register the views to collect server stats. initStats(log, exporter) return } d := time.Second * 20 * time.Duration(i) log.Debugf("sleeping %v to retry initializing Stackdriver exporter", d) time.Sleep(d) } log.Warn("could not initialize Stackdriver exporter after retrying, giving up") } func initTracing(log logrus.FieldLogger) { // This is a demo app with low QPS. trace.AlwaysSample() is used here // to make sure traces are available for observation and analysis. // In a production environment or high QPS setup please use // trace.ProbabilitySampler set at the desired probability. trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()}) initJaegerTracing(log) initStackdriverTracing(log) } func initProfiling(log logrus.FieldLogger, service, version string) { // TODO(ahmetb) this method is duplicated in other microservices using Go // since they are not sharing packages. for i := 1; i <= 3; i++ { log = log.WithField("retry", i) if err := profiler.Start(profiler.Config{ Service: service, ServiceVersion: version, // ProjectID must be set if not running on GCP. // ProjectID: "my-project", }); err != nil { log.Warnf("warn: failed to start profiler: %+v", err) } else { log.Info("started Stackdriver profiler") return } d := time.Second * 10 * time.Duration(i) log.Debugf("sleeping %v to retry initializing Stackdriver profiler", d) time.Sleep(d) } log.Warn("warning: could not initialize Stackdriver profiler after retrying, giving up") } func mustMapEnv(target *string, envKey string) { v := os.Getenv(envKey) if v == "" { panic(fmt.Sprintf("environment variable %q not set", envKey)) } *target = v } func mustConnGRPC(ctx context.Context, conn **grpc.ClientConn, addr string) { var err error ctx, cancel := context.WithTimeout(ctx, time.Second*3) defer cancel() *conn, err = grpc.DialContext(ctx, addr, grpc.WithInsecure(), grpc.WithStatsHandler(&ocgrpc.ClientHandler{})) if err != nil { panic(errors.Wrapf(err, "grpc: failed to connect %s", addr)) } } ================================================ FILE: microservices-demo/src/frontend/middleware.go ================================================ // Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "context" "net/http" "time" "github.com/google/uuid" "github.com/sirupsen/logrus" ) type ctxKeyLog struct{} type ctxKeyRequestID struct{} type logHandler struct { log *logrus.Logger next http.Handler } type responseRecorder struct { b int status int w http.ResponseWriter } func (r *responseRecorder) Header() http.Header { return r.w.Header() } func (r *responseRecorder) Write(p []byte) (int, error) { if r.status == 0 { r.status = http.StatusOK } n, err := r.w.Write(p) r.b += n return n, err } func (r *responseRecorder) WriteHeader(statusCode int) { r.status = statusCode r.w.WriteHeader(statusCode) } func (lh *logHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { ctx := r.Context() requestID, _ := uuid.NewRandom() ctx = context.WithValue(ctx, ctxKeyRequestID{}, requestID.String()) start := time.Now() rr := &responseRecorder{w: w} log := lh.log.WithFields(logrus.Fields{ "http.req.path": r.URL.Path, "http.req.method": r.Method, "http.req.id": requestID.String(), }) if v, ok := r.Context().Value(ctxKeySessionID{}).(string); ok { log = log.WithField("session", v) } log.Debug("request started") defer func() { log.WithFields(logrus.Fields{ "http.resp.took_ms": int64(time.Since(start) / time.Millisecond), "http.resp.status": rr.status, "http.resp.bytes": rr.b}).Debugf("request complete") }() ctx = context.WithValue(ctx, ctxKeyLog{}, log) r = r.WithContext(ctx) lh.next.ServeHTTP(rr, r) } func ensureSessionID(next http.Handler) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var sessionID string c, err := r.Cookie(cookieSessionID) if err == http.ErrNoCookie { u, _ := uuid.NewRandom() sessionID = u.String() http.SetCookie(w, &http.Cookie{ Name: cookieSessionID, Value: sessionID, MaxAge: cookieMaxAge, }) } else if err != nil { return } else { sessionID = c.Value } ctx := context.WithValue(r.Context(), ctxKeySessionID{}, sessionID) r = r.WithContext(ctx) next.ServeHTTP(w, r) } } ================================================ FILE: microservices-demo/src/frontend/money/money.go ================================================ // Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package money import ( "errors" pb "github.com/GoogleCloudPlatform/microservices-demo/src/frontend/genproto" ) const ( nanosMin = -999999999 nanosMax = +999999999 nanosMod = 1000000000 ) var ( ErrInvalidValue = errors.New("one of the specified money values is invalid") ErrMismatchingCurrency = errors.New("mismatching currency codes") ) // IsValid checks if specified value has a valid units/nanos signs and ranges. func IsValid(m pb.Money) bool { return signMatches(m) && validNanos(m.GetNanos()) } func signMatches(m pb.Money) bool { return m.GetNanos() == 0 || m.GetUnits() == 0 || (m.GetNanos() < 0) == (m.GetUnits() < 0) } func validNanos(nanos int32) bool { return nanosMin <= nanos && nanos <= nanosMax } // IsZero returns true if the specified money value is equal to zero. func IsZero(m pb.Money) bool { return m.GetUnits() == 0 && m.GetNanos() == 0 } // IsPositive returns true if the specified money value is valid and is // positive. func IsPositive(m pb.Money) bool { return IsValid(m) && m.GetUnits() > 0 || (m.GetUnits() == 0 && m.GetNanos() > 0) } // IsNegative returns true if the specified money value is valid and is // negative. func IsNegative(m pb.Money) bool { return IsValid(m) && m.GetUnits() < 0 || (m.GetUnits() == 0 && m.GetNanos() < 0) } // AreSameCurrency returns true if values l and r have a currency code and // they are the same values. func AreSameCurrency(l, r pb.Money) bool { return l.GetCurrencyCode() == r.GetCurrencyCode() && l.GetCurrencyCode() != "" } // AreEquals returns true if values l and r are the equal, including the // currency. This does not check validity of the provided values. func AreEquals(l, r pb.Money) bool { return l.GetCurrencyCode() == r.GetCurrencyCode() && l.GetUnits() == r.GetUnits() && l.GetNanos() == r.GetNanos() } // Negate returns the same amount with the sign negated. func Negate(m pb.Money) pb.Money { return pb.Money{ Units: -m.GetUnits(), Nanos: -m.GetNanos(), CurrencyCode: m.GetCurrencyCode()} } // Must panics if the given error is not nil. This can be used with other // functions like: "m := Must(Sum(a,b))". func Must(v pb.Money, err error) pb.Money { if err != nil { panic(err) } return v } // Sum adds two values. Returns an error if one of the values are invalid or // currency codes are not matching (unless currency code is unspecified for // both). func Sum(l, r pb.Money) (pb.Money, error) { if !IsValid(l) || !IsValid(r) { return pb.Money{}, ErrInvalidValue } else if l.GetCurrencyCode() != r.GetCurrencyCode() { return pb.Money{}, ErrMismatchingCurrency } units := l.GetUnits() + r.GetUnits() nanos := l.GetNanos() + r.GetNanos() if (units == 0 && nanos == 0) || (units > 0 && nanos >= 0) || (units < 0 && nanos <= 0) { // same sign units += int64(nanos / nanosMod) nanos = nanos % nanosMod } else { // different sign. nanos guaranteed to not to go over the limit if units > 0 { units-- nanos += nanosMod } else { units++ nanos -= nanosMod } } return pb.Money{ Units: units, Nanos: nanos, CurrencyCode: l.GetCurrencyCode()}, nil } // MultiplySlow is a slow multiplication operation done through adding the value // to itself n-1 times. func MultiplySlow(m pb.Money, n uint32) pb.Money { out := m for n > 1 { out = Must(Sum(out, m)) n-- } return out } ================================================ FILE: microservices-demo/src/frontend/money/money_test.go ================================================ // Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package money import ( "fmt" "reflect" "testing" pb "github.com/GoogleCloudPlatform/microservices-demo/src/frontend/genproto" ) func mmc(u int64, n int32, c string) pb.Money { return pb.Money{Units: u, Nanos: n, CurrencyCode: c} } func mm(u int64, n int32) pb.Money { return mmc(u, n, "") } func TestIsValid(t *testing.T) { tests := []struct { name string in pb.Money want bool }{ {"valid -/-", mm(-981273891273, -999999999), true}, {"invalid -/+", mm(-981273891273, +999999999), false}, {"valid +/+", mm(981273891273, 999999999), true}, {"invalid +/-", mm(981273891273, -999999999), false}, {"invalid +/+overflow", mm(3, 1000000000), false}, {"invalid +/-overflow", mm(3, -1000000000), false}, {"invalid -/+overflow", mm(-3, 1000000000), false}, {"invalid -/-overflow", mm(-3, -1000000000), false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := IsValid(tt.in); got != tt.want { t.Errorf("IsValid(%v) = %v, want %v", tt.in, got, tt.want) } }) } } func TestIsZero(t *testing.T) { tests := []struct { name string in pb.Money want bool }{ {"zero", mm(0, 0), true}, {"not-zero (-/+)", mm(-1, +1), false}, {"not-zero (-/-)", mm(-1, -1), false}, {"not-zero (+/+)", mm(+1, +1), false}, {"not-zero (+/-)", mm(+1, -1), false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := IsZero(tt.in); got != tt.want { t.Errorf("IsZero(%v) = %v, want %v", tt.in, got, tt.want) } }) } } func TestIsPositive(t *testing.T) { tests := []struct { name string in pb.Money want bool }{ {"zero", mm(0, 0), false}, {"positive (+/+)", mm(+1, +1), true}, {"invalid (-/+)", mm(-1, +1), false}, {"negative (-/-)", mm(-1, -1), false}, {"invalid (+/-)", mm(+1, -1), false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := IsPositive(tt.in); got != tt.want { t.Errorf("IsPositive(%v) = %v, want %v", tt.in, got, tt.want) } }) } } func TestIsNegative(t *testing.T) { tests := []struct { name string in pb.Money want bool }{ {"zero", mm(0, 0), false}, {"positive (+/+)", mm(+1, +1), false}, {"invalid (-/+)", mm(-1, +1), false}, {"negative (-/-)", mm(-1, -1), true}, {"invalid (+/-)", mm(+1, -1), false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := IsNegative(tt.in); got != tt.want { t.Errorf("IsNegative(%v) = %v, want %v", tt.in, got, tt.want) } }) } } func TestAreSameCurrency(t *testing.T) { type args struct { l pb.Money r pb.Money } tests := []struct { name string args args want bool }{ {"both empty currency", args{mmc(1, 0, ""), mmc(2, 0, "")}, false}, {"left empty currency", args{mmc(1, 0, ""), mmc(2, 0, "USD")}, false}, {"right empty currency", args{mmc(1, 0, "USD"), mmc(2, 0, "")}, false}, {"mismatching", args{mmc(1, 0, "USD"), mmc(2, 0, "CAD")}, false}, {"matching", args{mmc(1, 0, "USD"), mmc(2, 0, "USD")}, true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := AreSameCurrency(tt.args.l, tt.args.r); got != tt.want { t.Errorf("AreSameCurrency([%v],[%v]) = %v, want %v", tt.args.l, tt.args.r, got, tt.want) } }) } } func TestAreEquals(t *testing.T) { type args struct { l pb.Money r pb.Money } tests := []struct { name string args args want bool }{ {"equals", args{mmc(1, 2, "USD"), mmc(1, 2, "USD")}, true}, {"mismatching currency", args{mmc(1, 2, "USD"), mmc(1, 2, "CAD")}, false}, {"mismatching units", args{mmc(10, 20, "USD"), mmc(1, 20, "USD")}, false}, {"mismatching nanos", args{mmc(1, 2, "USD"), mmc(1, 20, "USD")}, false}, {"negated", args{mmc(1, 2, "USD"), mmc(-1, -2, "USD")}, false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := AreEquals(tt.args.l, tt.args.r); got != tt.want { t.Errorf("AreEquals([%v],[%v]) = %v, want %v", tt.args.l, tt.args.r, got, tt.want) } }) } } func TestNegate(t *testing.T) { tests := []struct { name string in pb.Money want pb.Money }{ {"zero", mm(0, 0), mm(0, 0)}, {"negative", mm(-1, -200), mm(1, 200)}, {"positive", mm(1, 200), mm(-1, -200)}, {"carries currency code", mmc(0, 0, "XXX"), mmc(0, 0, "XXX")}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := Negate(tt.in); !AreEquals(got, tt.want) { t.Errorf("Negate([%v]) = %v, want %v", tt.in, got, tt.want) } }) } } func TestMust_pass(t *testing.T) { v := Must(mm(2, 3), nil) if !AreEquals(v, mm(2, 3)) { t.Errorf("returned the wrong value: %v", v) } } func TestMust_panic(t *testing.T) { defer func() { if r := recover(); r != nil { t.Logf("panic captured: %v", r) } }() Must(mm(2, 3), fmt.Errorf("some error")) t.Fatal("this should not have executed due to the panic above") } func TestSum(t *testing.T) { type args struct { l pb.Money r pb.Money } tests := []struct { name string args args want pb.Money wantErr error }{ {"0+0=0", args{mm(0, 0), mm(0, 0)}, mm(0, 0), nil}, {"Error: currency code on left", args{mmc(0, 0, "XXX"), mm(0, 0)}, mm(0, 0), ErrMismatchingCurrency}, {"Error: currency code on right", args{mm(0, 0), mmc(0, 0, "YYY")}, mm(0, 0), ErrMismatchingCurrency}, {"Error: currency code mismatch", args{mmc(0, 0, "AAA"), mmc(0, 0, "BBB")}, mm(0, 0), ErrMismatchingCurrency}, {"Error: invalid +/-", args{mm(+1, -1), mm(0, 0)}, mm(0, 0), ErrInvalidValue}, {"Error: invalid -/+", args{mm(0, 0), mm(-1, +2)}, mm(0, 0), ErrInvalidValue}, {"Error: invalid nanos", args{mm(0, 1000000000), mm(1, 0)}, mm(0, 0), ErrInvalidValue}, {"both positive (no carry)", args{mm(2, 200000000), mm(2, 200000000)}, mm(4, 400000000), nil}, {"both positive (nanos=max)", args{mm(2, 111111111), mm(2, 888888888)}, mm(4, 999999999), nil}, {"both positive (carry)", args{mm(2, 200000000), mm(2, 900000000)}, mm(5, 100000000), nil}, {"both negative (no carry)", args{mm(-2, -200000000), mm(-2, -200000000)}, mm(-4, -400000000), nil}, {"both negative (carry)", args{mm(-2, -200000000), mm(-2, -900000000)}, mm(-5, -100000000), nil}, {"mixed (larger positive, just decimals)", args{mm(11, 0), mm(-2, 0)}, mm(9, 0), nil}, {"mixed (larger negative, just decimals)", args{mm(-11, 0), mm(2, 0)}, mm(-9, 0), nil}, {"mixed (larger positive, no borrow)", args{mm(11, 100000000), mm(-2, -100000000)}, mm(9, 0), nil}, {"mixed (larger positive, with borrow)", args{mm(11, 100000000), mm(-2, -9000000 /*.09*/)}, mm(9, 91000000 /*.091*/), nil}, {"mixed (larger negative, no borrow)", args{mm(-11, -100000000), mm(2, 100000000)}, mm(-9, 0), nil}, {"mixed (larger negative, with borrow)", args{mm(-11, -100000000), mm(2, 9000000 /*.09*/)}, mm(-9, -91000000 /*.091*/), nil}, {"0+negative", args{mm(0, 0), mm(-2, -100000000)}, mm(-2, -100000000), nil}, {"negative+0", args{mm(-2, -100000000), mm(0, 0)}, mm(-2, -100000000), nil}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := Sum(tt.args.l, tt.args.r) if err != tt.wantErr { t.Errorf("Sum([%v],[%v]): expected err=\"%v\" got=\"%v\"", tt.args.l, tt.args.r, tt.wantErr, err) } if !reflect.DeepEqual(got, tt.want) { t.Errorf("Sum([%v],[%v]) = %v, want %v", tt.args.l, tt.args.r, got, tt.want) } }) } } ================================================ FILE: microservices-demo/src/frontend/rpc.go ================================================ // Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "context" "time" pb "github.com/GoogleCloudPlatform/microservices-demo/src/frontend/genproto" "github.com/pkg/errors" ) const ( avoidNoopCurrencyConversionRPC = false ) func (fe *frontendServer) getCurrencies(ctx context.Context) ([]string, error) { currs, err := pb.NewCurrencyServiceClient(fe.currencySvcConn). GetSupportedCurrencies(ctx, &pb.Empty{}) if err != nil { return nil, err } var out []string for _, c := range currs.CurrencyCodes { if _, ok := whitelistedCurrencies[c]; ok { out = append(out, c) } } return out, nil } func (fe *frontendServer) getProducts(ctx context.Context) ([]*pb.Product, error) { resp, err := pb.NewProductCatalogServiceClient(fe.productCatalogSvcConn). ListProducts(ctx, &pb.Empty{}) return resp.GetProducts(), err } func (fe *frontendServer) getProduct(ctx context.Context, id string) (*pb.Product, error) { resp, err := pb.NewProductCatalogServiceClient(fe.productCatalogSvcConn). GetProduct(ctx, &pb.GetProductRequest{Id: id}) return resp, err } func (fe *frontendServer) getCart(ctx context.Context, userID string) ([]*pb.CartItem, error) { resp, err := pb.NewCartServiceClient(fe.cartSvcConn).GetCart(ctx, &pb.GetCartRequest{UserId: userID}) return resp.GetItems(), err } func (fe *frontendServer) emptyCart(ctx context.Context, userID string) error { _, err := pb.NewCartServiceClient(fe.cartSvcConn).EmptyCart(ctx, &pb.EmptyCartRequest{UserId: userID}) return err } func (fe *frontendServer) insertCart(ctx context.Context, userID, productID string, quantity int32) error { _, err := pb.NewCartServiceClient(fe.cartSvcConn).AddItem(ctx, &pb.AddItemRequest{ UserId: userID, Item: &pb.CartItem{ ProductId: productID, Quantity: quantity}, }) return err } func (fe *frontendServer) convertCurrency(ctx context.Context, money *pb.Money, currency string) (*pb.Money, error) { if avoidNoopCurrencyConversionRPC && money.GetCurrencyCode() == currency { return money, nil } return pb.NewCurrencyServiceClient(fe.currencySvcConn). Convert(ctx, &pb.CurrencyConversionRequest{ From: money, ToCode: currency}) } func (fe *frontendServer) getShippingQuote(ctx context.Context, items []*pb.CartItem, currency string) (*pb.Money, error) { quote, err := pb.NewShippingServiceClient(fe.shippingSvcConn).GetQuote(ctx, &pb.GetQuoteRequest{ Address: nil, Items: items}) if err != nil { return nil, err } localized, err := fe.convertCurrency(ctx, quote.GetCostUsd(), currency) return localized, errors.Wrap(err, "failed to convert currency for shipping cost") } func (fe *frontendServer) getRecommendations(ctx context.Context, userID string, productIDs []string) ([]*pb.Product, error) { resp, err := pb.NewRecommendationServiceClient(fe.recommendationSvcConn).ListRecommendations(ctx, &pb.ListRecommendationsRequest{UserId: userID, ProductIds: productIDs}) if err != nil { return nil, err } out := make([]*pb.Product, len(resp.GetProductIds())) for i, v := range resp.GetProductIds() { p, err := fe.getProduct(ctx, v) if err != nil { return nil, errors.Wrapf(err, "failed to get recommended product info (#%s)", v) } out[i] = p } if len(out) > 4 { out = out[:4] // take only first four to fit the UI } return out, err } func (fe *frontendServer) getAd(ctx context.Context, ctxKeys []string) ([]*pb.Ad, error) { ctx, cancel := context.WithTimeout(ctx, time.Millisecond*100) defer cancel() resp, err := pb.NewAdServiceClient(fe.adSvcConn).GetAds(ctx, &pb.AdRequest{ ContextKeys: ctxKeys, }) return resp.GetAds(), errors.Wrap(err, "failed to get ads") } ================================================ FILE: microservices-demo/src/frontend/static/images/credits.txt ================================================ folded-clothes-on-white-chair.jpg,,https://unsplash.com/photos/fr0J5-GIVyg folded-clothes-on-white-chair-wide.jpg,,https://unsplash.com/photos/fr0J5-GIVyg ================================================ FILE: microservices-demo/src/frontend/static/styles/cart.css ================================================ /** * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ .cart-sections { padding-bottom: 120px; padding-top: 56px; background-color: #F9F9F9; } .cart-sections h3 { font-size: 36px; font-weight: normal; } .cart-sections a.cymbal-button-primary:hover { text-decoration: none; color: white; } /* Empty Cart Section */ .empty-cart-section { max-width: 458px; margin: auto; text-align: center; } .empty-cart-section a { display: inline-block; /* So margin-top works. */ margin-top: 32px; } .empty-cart-section a:hover { color: white; text-decoration: none; } /* Cart Summary Section */ .cart-summary-empty-cart-button { margin-right: 10px; } .cart-summary-item-row, .cart-summary-shipping-row, .cart-summary-total-row { padding-bottom: 24px; padding-top: 24px; border-top: solid 1px rgba(154, 160, 166, 0.5); } .cart-summary-item-row img { border-radius: 20% 0 20% 20%; } .cart-summary-item-row-item-id-row { font-size: 12px; color: #5C6063; } .cart-summary-item-row h4 { font-size: 18px; font-weight: normal; } /* Stick item quantity and cost to the bottom (for wider screens). */ @media (min-width: 768px) { .cart-summary-item-row .row:last-child { position: absolute; bottom: 0px; width: 100%; } } /* Item cost (price). */ .cart-summary-item-row .row:last-child strong { font-weight: 500; } .cart-summary-total-row { font-size: 28px; } /* Cart Checkout Form */ .cart-checkout-form h3 { margin-bottom: 0; } .payment-method-heading { margin-top: 36px; } /* "Place Order" button */ .cart-checkout-form .cymbal-button-primary { margin-top: 36px; } ================================================ FILE: microservices-demo/src/frontend/static/styles/order.css ================================================ /** * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ .order { background: #F9F9F9; } .order-complete-section { max-width: 487px; padding-top: 56px; padding-bottom: 120px; } .order-complete-section h3 { margin: 0; font-size: 36px; font-weight: normal; } .order-complete-section p { margin-top: 8px; } .order-complete-section .padding-y-24 { padding-bottom: 24px; padding-top: 24px; } .order-complete-section .border-bottom-solid { border-bottom: 1px solid rgba(154, 160, 166, 0.5); } .order-complete-section .cymbal-button-primary { margin-top: 24px; } .order-complete-section a.cymbal-button-primary:hover { text-decoration: none; color: white; } ================================================ FILE: microservices-demo/src/frontend/static/styles/styles.css ================================================ /** * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* General */ html, body { height: 100%; } body { color: #111111; font-family: 'DM Sans', sans-serif; display: flex; flex-direction: column; } /* Header */ header { background-color: #853B5C; color: white; } /* This allows the sub-navbar (white strip containing logo) to be as wide as the browser window. */ header > div:nth-child(2).navbar.sub-navbar { padding-left: 0; padding-right: 0; } header > div:nth-child(2) > .container { max-width: none; } header .cart-link { position: relative; display: block; margin-left: 25px; display: flex; flex-flow: column; align-items: center; justify-content: center; } header .cart-size-circle { display: flex; align-items: center; justify-content: center; position: absolute; top: 24px; left: 11px; width: 16px; height: 16px; font-size: 11px; border-radius: 4px 4px 0 4px; color: white; background-color: #853B5C; } header .h-free-shipping { font-size: 14px; } header .h-controls { display: flex; justify-content: flex-end; } header .h-control { display: flex; align-items: center; font-size: 12px; position: relative; margin-left: 40px; color: #605f64; } header .h-control:first-child { margin-left: 0; } header .h-control input { border: none; padding: 0 31px 0 31px; width: 250px; height: 24px; flex-shrink: 0; background-color: #f2f2f2; display: flex; align-items: center; } header .h-control input:focus { outline: 0; border: 0; box-shadow: 0; } header .icon { width: 20px; height: 20px; } header .icon.search-icon { width: 12px; height: 13px; position: absolute; left: 10px; } /* The currency drop-down. */ header img.currency-icon, header span.currency-icon { position: relative; left: 35px; top: -1px; width: 20px; display: inline-block; height: 20px; } header span.currency-icon { font-size: 16px; text-align: center; } header .h-control select { display: flex; align-items: center; background: transparent; border-radius: 0; border: 1px solid #acacac; width: 130px; height: 40px; flex-shrink: 0; padding: 1px 0 0 45px; font-size: 16px; border-radius: 8px; } header .icon.arrow { position: absolute; right: 25px; width: 10px; height: 5px; } header .h-control::-webkit-input-placeholder { /* Chrome/Opera/Safari */ font-size: 12px; color: #605f64; } header .h-control::-moz-placeholder { /* Firefox 19+ */ font-size: 12px; color: #605f64; } header .h-control :-ms-input-placeholder { /* IE 10+ */ font-size: 12px; color: #605f64; } header .h-control :-moz-placeholder { /* Firefox 18- */ font-size: 12px; color: #605f64; } header .navbar.sub-navbar { height: 60px; background-color: white; font-size: 15px; color: #b4b2bb; padding-top: 0; padding-bottom: 0; box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.25); z-index: 1; /* Need this to see the box-shadow on the home page. */ } header .navbar.sub-navbar > .container { padding-left: 26px; padding-right: 26px; } header .top-left-logo { height: 40px; } header .top-left-logo-cymbal { height: 30px; } header .navbar.sub-navbar .navbar-brand { padding: 0; } header .navbar.sub-navbar a { color: #b4b2bb; } header .navbar.sub-navbar nav a { margin: 0 10px; } header .navbar.sub-navbar .controls { display: flex; height: 60px; } header .navbar.sub-navbar .controls a img { width: 20px; height: 20px; margin-bottom: 3px; } /* Footer */ footer.py-5 { flex-shrink: 0; padding: 0 !important; } footer .footer-top { padding: 60px 0px; background-color: #570D2E; color: white; } footer .footer-top a { color: white; text-decoration: underline; } /* The

containing the session-id. */ footer .footer-top p:nth-child(3) { margin-top: 56px; } footer .footer-top .footer-social, footer .footer-top .footer-app, footer .footer-links, footer .footer-top .social, footer .footer-top .app { display: block; align-items: center; } footer .footer-top .footer-social { padding: 31px; } footer .footer-top .footer-social h4 { margin-bottom: 0; } footer .footer-top .footer-social div { width: 50%; } /* Home */ main { flex: 1 0 auto; background-color: #F9F9F9; } @media (min-width: 992px) { .home .container-fluid { height: calc(100vh - 91px); /* 91px is the height of the top/header bars. */ } .home .container-fluid > .row > .col-4 { height: calc(100vh - 91px); } .home .container-fluid > .row > .col-lg-8 { height: calc(100vh - 91px); overflow-y: scroll; } } .home-mobile-hero-banner { height: 200px; background: url(/static/images/folded-clothes-on-white-chair-wide.jpg) no-repeat top center; background-size: cover; } .home-desktop-left-image { background: url(/static/images/folded-clothes-on-white-chair.jpg) no-repeat center; background-size: cover; } .hot-products-row h3 { margin-bottom: 32px; margin-top: 56px; font-size: 36px; font-weight: normal; } .hot-products-row { padding-bottom: 70px; padding-left: 10%; padding-right: 10%; } .hot-product-card { margin-bottom: 52px; padding-left: 16px; padding-right: 16px; } .hot-product-card img { width: 100%; height: auto; border-radius: 20% 0 20% 20%; } .hot-product-card-name { margin-top: 8px; font-size: 18px; } .hot-product-card-price { font-size: 14px; } .hot-product-card > a:first-child { position: relative; display: block; } .hot-product-card-img-overlay { position: absolute; height: 100%; width: 100%; top: 0; left: 0; border-radius: 20% 0 20% 20%; background-color: transparent; } .hot-product-card:hover .hot-product-card-img-overlay { background-color: rgba(71, 0, 29, 0.2); } /* This chunk ensures the left/right padding of the footer is similar to that of the hot-products-row. */ .home-desktop-footer-row { padding-left: 9%; padding-right: 9%; background-color: #570D2E; } /* Ad */ .ad { position: relative; background-color: #FF9A9B; font-size: 24px; text-align: center; } /* "Ad" text. */ .ad strong { position: absolute; top: 6px; left: 12px; font-size: 14px; font-weight: normal; } .ad a { color: black; } /* Product */ .h-product { margin-top: 56px; margin-bottom: 112px; max-width: 1200px; background-color: #F9F9F9; } .h-product > .row { align-items: flex-end; } .h-product .product-image { width: 100%; border-radius: 20% 20% 0 20%; } .h-product .product-price { font-size: 28px; } .h-product .product-info .product-wrapper { margin-left: 15px; } .h-product .product-info h2 { margin-bottom: 16px; margin-top: 16px; font-size: 56px; line-height: 1.14; font-weight: normal; color: #111111; } .h-product .input-group-text, .h-product .btn.btn-info { font-size: 18px; line-height: 1.89; letter-spacing: 3.6px; text-align: center; color: #111111; border-radius: 0; } .product-quantity-dropdown { position: relative; width: 100px; } .product-quantity-dropdown select { width: 100%; height: 45px; border: 1px solid #acacac; padding: 10px 16px; border-radius: 8px; } .product-quantity-dropdown img { position: absolute; right: 25px; top: 20px; width: 10px; height: 5px; } .h-product .cymbal-button-primary { margin-top: 16px; } /* Platform Banner */ .local, .aws-platform, .onprem-platform, .azure-platform, .alibaba-platform, .gcp-platform { position: fixed; top: 0; left: 0; width: 10px; height: 100vh; color: white; font-size: 24px; z-index: 999; } .aws-platform, .aws-platform .platform-flag { background-color: #ff9900; } .onprem-platform, .onprem-platform .platform-flag { background-color: #34A853; } .gcp-platform, .gcp-platform .platform-flag { background-color: #4285f4; } .azure-platform, .azure-platform .platform-flag { background-color: #f35426; } .alibaba-platform, .alibaba-platform .platform-flag { background-color: #ffC300; } .local, .local .platform-flag { background-color: #2c0678; } .platform-flag { position: absolute; top: 98px; left: 0; width: 190px; height: 50px; display: flex; justify-content: center; align-items: center; } /* Recommendation */ .recommendations { background: #F9F9F9; padding-bottom: 55px; } .recommendations .container { max-width: 1174px; } @media (max-width: 992px) { .recommendations .container { max-width: none; } } .recommendations h2 { border-top: solid 1px; padding: 40px 0; font-weight: normal; text-align: center; } .recommendations h5 { margin-top: 8px; font-weight: normal; font-size: 18px; } .recommendations img { height: 100%; width: 100%; border-radius: 20% 0 20% 20%; } select { -webkit-appearance: none; -webkit-border-radius: 0px; } /* Cymbal */ /* If we ever decide to create a separate Cymbal CSS library for Cymbal components, the rules below could be extracted. */ .cymbal-button-primary, .cymbal-button-secondary { display: inline-block; border: solid 1px #CE0631; padding: 8px 16px; outline: none; font-size: 14px; border-radius: 22px; cursor: pointer; } .cymbal-button-primary:focus, .cymbal-button-secondary:focus { outline: none; /* To override browser (Chrome) default blue outline. */ } .cymbal-button-primary { background-color: #CE0631; color: white; } .cymbal-button-secondary { background: none; color: #CE0631; } .cymbal-form-field { position: relative; margin-top: 24px; } .cymbal-form-field label { width: 100%; margin: 0; padding: 8px 16px 0 16px; font-size: 12px; line-height: 1.8em; /* Without this, there might be a 1px gap underneath. */ font-weight: normal; border-radius: 4px 4px 0px 0px; color: #5C6063; background-color: white; } .cymbal-form-field input[type='email'], .cymbal-form-field input[type='password'], .cymbal-form-field select, .cymbal-form-field input[type='text'] { width: 100%; border: none; border-bottom: 1px solid #9AA0A6; padding: 0 16px 8px 16px; outline: none; color: #1E2021; } .cymbal-form-field .cymbal-dropdown-chevron { position: absolute; right: 25px; width: 10px; height: 5px; } ================================================ FILE: microservices-demo/src/frontend/templates/ad.html ================================================ {{ define "text_ad" }}

{{ end }} ================================================ FILE: microservices-demo/src/frontend/templates/cart.html ================================================ {{ define "cart" }} {{ template "header" . }}
{{$.platform_name}}
{{ if eq (len $.items) 0 }}

Your shopping cart is empty!

Items you add to your shopping cart will appear here.

Continue Shopping
{{ else }}

Cart ({{ $.cart_size }})

{{ range $.items }}

{{ .Item.Name }}

SKU #{{ .Item.Id }}
Quantity: {{ .Quantity }}
{{ renderMoney .Price }}
{{ end }}
Shipping
{{ renderMoney .shipping_cost }}
Total
{{ renderMoney .total_cost }}

Shipping Address

Payment Method

{{ end }}
{{ if $.recommendations}} {{ template "recommendations" $.recommendations }} {{ end }} {{ template "footer" . }} {{ end }} ================================================ FILE: microservices-demo/src/frontend/templates/error.html ================================================ {{ define "error" }} {{ template "header" . }}
{{$.platform_name}}

Uh, oh!

Something has failed. Below are some details for debugging.

HTTP Status: {{.status_code}} {{.status}}

                    {{- .error -}}
                
{{ template "footer" . }} {{ end }} ================================================ FILE: microservices-demo/src/frontend/templates/footer.html ================================================ {{ define "footer" }}
{{ end }} ================================================ FILE: microservices-demo/src/frontend/templates/header.html ================================================ {{ define "header" }} {{ if $.is_cymbal_brand }} Cymbal Shops {{ else }} Online Boutique {{ end }} {{ if $.is_cymbal_brand }} {{ else }} {{ end }}
{{end}} ================================================ FILE: microservices-demo/src/frontend/templates/home.html ================================================ {{ define "home" }} {{ template "header" . }}
{{$.platform_name}}

Hot Products

{{ range $.products }}
{{ .Item.Name }}
{{ renderMoney .Price }}
{{ end }}
{{ template "footer" . }}
{{ end }} ================================================ FILE: microservices-demo/src/frontend/templates/order.html ================================================ {{ define "order" }} {{ template "header" . }}
{{$.platform_name}}

Your order is complete!

We've sent you a confirmation email.

Confirmation #
{{.order.OrderId}}
Tracking #
{{.order.ShippingTrackingId}}
Total Paid
{{renderMoney .total_paid}}
{{ if $.recommendations }} {{ template "recommendations" $.recommendations }} {{ end }}
{{ template "footer" . }} {{ end }} ================================================ FILE: microservices-demo/src/frontend/templates/product.html ================================================ {{ define "product" }} {{ template "header" . }}
{{$.platform_name}}

{{ $.product.Item.Name }}

{{ renderMoney $.product.Price }}

{{ $.product.Item.Description }}

{{ if $.recommendations}} {{ template "recommendations" $.recommendations }} {{ end }}
{{ with $.ad }}{{ template "text_ad" . }}{{ end }}
{{ template "footer" . }} {{ end }} ================================================ FILE: microservices-demo/src/frontend/templates/recommendations.html ================================================ {{ define "recommendations" }}

You May Also Like

{{range . }}
{{ .Name }}
{{ end }}
{{ end }} ================================================ FILE: microservices-demo/src/loadgenerator/Dockerfile ================================================ # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. FROM python:3.9-slim as base FROM base as builder RUN apt-get -qq update \ && apt-get install -y --no-install-recommends \ g++ COPY requirements.txt . RUN pip install --prefix="/install" -r requirements.txt FROM base WORKDIR /loadgen COPY --from=builder /install /usr/local # Add application code. COPY locustfile.py . # enable gevent support in debugger ENV GEVENT_SUPPORT=True ENTRYPOINT locust --host="http://${FRONTEND_ADDR}" --headless -u "${USERS:-10}" 2>&1 ================================================ FILE: microservices-demo/src/loadgenerator/loadgenerator.yaml ================================================ # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. apiVersion: apps/v1 kind: Deployment metadata: name: loadgenerator spec: selector: matchLabels: app: loadgenerator replicas: 1 template: metadata: labels: app: loadgenerator annotations: sidecar.istio.io/rewriteAppHTTPProbers: "true" spec: serviceAccountName: default terminationGracePeriodSeconds: 5 restartPolicy: Always securityContext: fsGroup: 1000 runAsGroup: 1000 runAsNonRoot: true runAsUser: 1000 initContainers: - command: - /bin/sh - -exc - | echo "Init container pinging frontend: ${FRONTEND_ADDR}..." STATUSCODE=$(wget --server-response http://${FRONTEND_ADDR} 2>&1 | awk '/^ HTTP/{print $2}') if test $STATUSCODE -ne 200; then echo "Error: Could not reach frontend - Status code: ${STATUSCODE}" exit 1 fi name: frontend-check securityContext: allowPrivilegeEscalation: false capabilities: drop: - all privileged: false readOnlyRootFilesystem: true image: busybox:latest env: - name: FRONTEND_ADDR value: "frontend:80" containers: - name: main securityContext: allowPrivilegeEscalation: false capabilities: drop: - all privileged: false readOnlyRootFilesystem: true image: env: - name: FRONTEND_ADDR value: "frontend:80" - name: USERS value: "10" resources: requests: cpu: 300m memory: 256Mi limits: cpu: 500m memory: 512Mi ================================================ FILE: microservices-demo/src/loadgenerator/locustfile.py ================================================ #!/usr/bin/python # # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import random from locust import HttpUser, TaskSet, between products = [ '0PUK6V6EV0', '1YMWWN1N4O', '2ZYFJ3GM2N', '66VCHSJNUP', '6E92ZMYYFZ', '9SIQT8TOJO', 'L9ECAV7KIM', 'LS4PSXUNUM', 'OLJCESPC7Z'] def index(l): l.client.get("/") def setCurrency(l): currencies = ['EUR', 'USD', 'JPY', 'CAD'] l.client.post("/setCurrency", {'currency_code': random.choice(currencies)}) def browseProduct(l): l.client.get("/product/" + random.choice(products)) def viewCart(l): l.client.get("/cart") def addToCart(l): product = random.choice(products) l.client.get("/product/" + product) l.client.post("/cart", { 'product_id': product, 'quantity': random.choice([1,2,3,4,5,10])}) def checkout(l): addToCart(l) l.client.post("/cart/checkout", { 'email': 'someone@example.com', 'street_address': '1600 Amphitheatre Parkway', 'zip_code': '94043', 'city': 'Mountain View', 'state': 'CA', 'country': 'United States', 'credit_card_number': '4432-8015-6152-0454', 'credit_card_expiration_month': '1', 'credit_card_expiration_year': '2039', 'credit_card_cvv': '672', }) class UserBehavior(TaskSet): def on_start(self): index(self) tasks = {index: 1, setCurrency: 2, browseProduct: 10, addToCart: 2, viewCart: 3, checkout: 1} class WebsiteUser(HttpUser): tasks = [UserBehavior] wait_time = between(1, 10) ================================================ FILE: microservices-demo/src/loadgenerator/requirements.in ================================================ locust==2.12.1 ================================================ FILE: microservices-demo/src/loadgenerator/requirements.txt ================================================ # # This file is autogenerated by pip-compile with python 3.9 # To update, run: # # pip-compile --output-file=requirements.txt requirements.in # brotli==1.0.9 # via geventhttpclient certifi==2022.9.24 # via # geventhttpclient # requests charset-normalizer==2.1.1 # via requests click==8.1.3 # via flask configargparse==1.5.3 # via locust flask==2.2.2 # via # flask-basicauth # flask-cors # locust flask-basicauth==0.2.0 # via locust flask-cors==3.0.10 # via locust gevent==21.12.0 # via # geventhttpclient # locust geventhttpclient==2.0.2 # via locust greenlet==1.1.3 # via gevent idna==3.4 # via requests importlib-metadata==5.0.0 # via flask itsdangerous==2.1.2 # via flask jinja2==3.1.2 # via flask locust==2.12.1 # via -r requirements.in markupsafe==2.1.1 # via # jinja2 # werkzeug msgpack==1.0.4 # via locust psutil==5.9.2 # via locust pyzmq==24.0.1 # via locust requests==2.28.1 # via locust roundrobin==0.0.4 # via locust six==1.16.0 # via # flask-cors # geventhttpclient typing-extensions==4.3.0 # via locust urllib3==1.26.12 # via requests werkzeug==2.2.2 # via # flask # locust zipp==3.8.1 # via importlib-metadata zope-event==4.5.0 # via gevent zope-interface==5.4.0 # via gevent # The following packages are considered to be unsafe in a requirements file: # setuptools ================================================ FILE: microservices-demo/src/paymentservice/.dockerignore ================================================ node_modules ================================================ FILE: microservices-demo/src/paymentservice/.gitignore ================================================ node_modules .DS_Store ================================================ FILE: microservices-demo/src/paymentservice/Dockerfile ================================================ # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. FROM node:18-alpine as base FROM base as builder # Some packages (e.g. @google-cloud/profiler) require additional # deps for post-install scripts RUN apk add --update --no-cache \ python3 \ make \ g++ WORKDIR /usr/src/app COPY package*.json ./ RUN npm install --only=production FROM base RUN GRPC_HEALTH_PROBE_VERSION=v0.4.11 && \ wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \ chmod +x /bin/grpc_health_probe WORKDIR /usr/src/app COPY --from=builder /usr/src/app/node_modules ./node_modules COPY . . EXPOSE 50051 ENTRYPOINT [ "node", "index.js" ] ================================================ FILE: microservices-demo/src/paymentservice/charge.js ================================================ // Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. const cardValidator = require('simple-card-validator'); const uuid = require('uuid/v4'); const pino = require('pino'); const logger = pino({ name: 'paymentservice-charge', messageKey: 'message', changeLevelName: 'severity', useLevelLabels: true }); class CreditCardError extends Error { constructor (message) { super(message); this.code = 400; // Invalid argument error } } class InvalidCreditCard extends CreditCardError { constructor (cardType) { super(`Credit card info is invalid`); } } class UnacceptedCreditCard extends CreditCardError { constructor (cardType) { super(`Sorry, we cannot process ${cardType} credit cards. Only VISA or MasterCard is accepted.`); } } class ExpiredCreditCard extends CreditCardError { constructor (number, month, year) { super(`Your credit card (ending ${number.substr(-4)}) expired on ${month}/${year}`); } } /** * Verifies the credit card number and (pretend) charges the card. * * @param {*} request * @return transaction_id - a random uuid v4. */ module.exports = function charge (request) { const { amount, credit_card: creditCard } = request; const cardNumber = creditCard.credit_card_number; const cardInfo = cardValidator(cardNumber); const { card_type: cardType, valid } = cardInfo.getCardDetails(); if (!valid) { throw new InvalidCreditCard(); } // Only VISA and mastercard is accepted, other card types (AMEX, dinersclub) will // throw UnacceptedCreditCard error. if (!(cardType === 'visa' || cardType === 'mastercard')) { throw new UnacceptedCreditCard(cardType); } // Also validate expiration is > today. const currentMonth = new Date().getMonth() + 1; const currentYear = new Date().getFullYear(); const { credit_card_expiration_year: year, credit_card_expiration_month: month } = creditCard; if ((currentYear * 12 + currentMonth) > (year * 12 + month)) { throw new ExpiredCreditCard(cardNumber.replace('-', ''), month, year); } logger.info(`Transaction processed: ${cardType} ending ${cardNumber.substr(-4)} \ Amount: ${amount.currency_code}${amount.units}.${amount.nanos}`); return { transaction_id: uuid() }; }; ================================================ FILE: microservices-demo/src/paymentservice/genproto.sh ================================================ #!/bin/bash -eu # # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # [START gke_paymentservice_genproto] # protos are loaded dynamically for node, simply copies over the proto. mkdir -p proto cp -r ../../pb/* ./proto # [END gke_paymentservice_genproto] ================================================ FILE: microservices-demo/src/paymentservice/index.js ================================================ /* * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 'use strict'; if(process.env.DISABLE_PROFILER) { console.log("Profiler disabled.") } else { console.log("Profiler enabled.") require('@google-cloud/profiler').start({ serviceContext: { service: 'paymentservice', version: '1.0.0' } }); } if(process.env.DISABLE_TRACING) { console.log("Tracing disabled.") } else { console.log("Tracing enabled.") require('@google-cloud/trace-agent').start(); } if(process.env.DISABLE_DEBUGGER) { console.log("Debugger disabled.") } else { console.log("Debugger enabled.") require('@google-cloud/debug-agent').start({ serviceContext: { service: 'paymentservice', version: 'VERSION' } }); } const path = require('path'); const HipsterShopServer = require('./server'); const PORT = process.env['PORT']; const PROTO_PATH = path.join(__dirname, '/proto/'); const server = new HipsterShopServer(PROTO_PATH, PORT); server.listen(); ================================================ FILE: microservices-demo/src/paymentservice/package.json ================================================ { "name": "paymentservice", "version": "0.0.1", "description": "Payment Microservice demo", "repository": "https://github.com/GoogleCloudPlatform/microservices-demo", "main": "index.js", "scripts": { "test": "echo \"Warn: no test specified\" && exit 0", "lint": "semistandard *.js" }, "author": "Jonathan Lui", "license": "ISC", "dependencies": { "@google-cloud/debug-agent": "5.2.9", "@google-cloud/profiler": "4.2.0", "@google-cloud/trace-agent": "5.1.6", "@grpc/grpc-js": "1.6.11", "@grpc/proto-loader": "0.6.13", "pino": "5.17.0", "simple-card-validator": "^1.1.0", "uuid": "^3.2.1" }, "devDependencies": { "semistandard": "16.0.1" } } ================================================ FILE: microservices-demo/src/paymentservice/proto/demo.proto ================================================ // Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. syntax = "proto3"; package hipstershop; // -----------------Cart service----------------- service CartService { rpc AddItem(AddItemRequest) returns (Empty) {} rpc GetCart(GetCartRequest) returns (Cart) {} rpc EmptyCart(EmptyCartRequest) returns (Empty) {} } message CartItem { string product_id = 1; int32 quantity = 2; } message AddItemRequest { string user_id = 1; CartItem item = 2; } message EmptyCartRequest { string user_id = 1; } message GetCartRequest { string user_id = 1; } message Cart { string user_id = 1; repeated CartItem items = 2; } message Empty {} // ---------------Recommendation service---------- service RecommendationService { rpc ListRecommendations(ListRecommendationsRequest) returns (ListRecommendationsResponse){} } message ListRecommendationsRequest { string user_id = 1; repeated string product_ids = 2; } message ListRecommendationsResponse { repeated string product_ids = 1; } // ---------------Product Catalog---------------- service ProductCatalogService { rpc ListProducts(Empty) returns (ListProductsResponse) {} rpc GetProduct(GetProductRequest) returns (Product) {} rpc SearchProducts(SearchProductsRequest) returns (SearchProductsResponse) {} } message Product { string id = 1; string name = 2; string description = 3; string picture = 4; Money price_usd = 5; // Categories such as "clothing" or "kitchen" that can be used to look up // other related products. repeated string categories = 6; } message ListProductsResponse { repeated Product products = 1; } message GetProductRequest { string id = 1; } message SearchProductsRequest { string query = 1; } message SearchProductsResponse { repeated Product results = 1; } // ---------------Shipping Service---------- service ShippingService { rpc GetQuote(GetQuoteRequest) returns (GetQuoteResponse) {} rpc ShipOrder(ShipOrderRequest) returns (ShipOrderResponse) {} } message GetQuoteRequest { Address address = 1; repeated CartItem items = 2; } message GetQuoteResponse { Money cost_usd = 1; } message ShipOrderRequest { Address address = 1; repeated CartItem items = 2; } message ShipOrderResponse { string tracking_id = 1; } message Address { string street_address = 1; string city = 2; string state = 3; string country = 4; int32 zip_code = 5; } // -----------------Currency service----------------- service CurrencyService { rpc GetSupportedCurrencies(Empty) returns (GetSupportedCurrenciesResponse) {} rpc Convert(CurrencyConversionRequest) returns (Money) {} } // Represents an amount of money with its currency type. message Money { // The 3-letter currency code defined in ISO 4217. string currency_code = 1; // The whole units of the amount. // For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar. int64 units = 2; // Number of nano (10^-9) units of the amount. // The value must be between -999,999,999 and +999,999,999 inclusive. // If `units` is positive, `nanos` must be positive or zero. // If `units` is zero, `nanos` can be positive, zero, or negative. // If `units` is negative, `nanos` must be negative or zero. // For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000. int32 nanos = 3; } message GetSupportedCurrenciesResponse { // The 3-letter currency code defined in ISO 4217. repeated string currency_codes = 1; } message CurrencyConversionRequest { Money from = 1; // The 3-letter currency code defined in ISO 4217. string to_code = 2; } // -------------Payment service----------------- service PaymentService { rpc Charge(ChargeRequest) returns (ChargeResponse) {} } message CreditCardInfo { string credit_card_number = 1; int32 credit_card_cvv = 2; int32 credit_card_expiration_year = 3; int32 credit_card_expiration_month = 4; } message ChargeRequest { Money amount = 1; CreditCardInfo credit_card = 2; } message ChargeResponse { string transaction_id = 1; } // -------------Email service----------------- service EmailService { rpc SendOrderConfirmation(SendOrderConfirmationRequest) returns (Empty) {} } message OrderItem { CartItem item = 1; Money cost = 2; } message OrderResult { string order_id = 1; string shipping_tracking_id = 2; Money shipping_cost = 3; Address shipping_address = 4; repeated OrderItem items = 5; } message SendOrderConfirmationRequest { string email = 1; OrderResult order = 2; } // -------------Checkout service----------------- service CheckoutService { rpc PlaceOrder(PlaceOrderRequest) returns (PlaceOrderResponse) {} } message PlaceOrderRequest { string user_id = 1; string user_currency = 2; Address address = 3; string email = 5; CreditCardInfo credit_card = 6; } message PlaceOrderResponse { OrderResult order = 1; } // ------------Ad service------------------ service AdService { rpc GetAds(AdRequest) returns (AdResponse) {} } message AdRequest { // List of important key words from the current page describing the context. repeated string context_keys = 1; } message AdResponse { repeated Ad ads = 1; } message Ad { // url to redirect to when an ad is clicked. string redirect_url = 1; // short advertisement text to display. string text = 2; } ================================================ FILE: microservices-demo/src/paymentservice/proto/grpc/health/v1/health.proto ================================================ // Copyright 2015 The gRPC Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // The canonical version of this proto can be found at // https://github.com/grpc/grpc-proto/blob/master/grpc/health/v1/health.proto syntax = "proto3"; package grpc.health.v1; option csharp_namespace = "Grpc.Health.V1"; option go_package = "google.golang.org/grpc/health/grpc_health_v1"; option java_multiple_files = true; option java_outer_classname = "HealthProto"; option java_package = "io.grpc.health.v1"; message HealthCheckRequest { string service = 1; } message HealthCheckResponse { enum ServingStatus { UNKNOWN = 0; SERVING = 1; NOT_SERVING = 2; } ServingStatus status = 1; } service Health { rpc Check(HealthCheckRequest) returns (HealthCheckResponse); } ================================================ FILE: microservices-demo/src/paymentservice/server.js ================================================ // Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. const path = require('path'); const grpc = require('@grpc/grpc-js'); const pino = require('pino'); const protoLoader = require('@grpc/proto-loader'); const charge = require('./charge'); const logger = pino({ name: 'paymentservice-server', messageKey: 'message', changeLevelName: 'severity', useLevelLabels: true }); class HipsterShopServer { constructor(protoRoot, port = HipsterShopServer.PORT) { this.port = port; this.packages = { hipsterShop: this.loadProto(path.join(protoRoot, 'demo.proto')), health: this.loadProto(path.join(protoRoot, 'grpc/health/v1/health.proto')) }; this.server = new grpc.Server(); this.loadAllProtos(protoRoot); } /** * Handler for PaymentService.Charge. * @param {*} call { ChargeRequest } * @param {*} callback fn(err, ChargeResponse) */ static ChargeServiceHandler(call, callback) { try { logger.info(`PaymentService#Charge invoked with request ${JSON.stringify(call.request)}`); const response = charge(call.request); callback(null, response); } catch (err) { console.warn(err); callback(err); } } static CheckHandler(call, callback) { callback(null, { status: 'SERVING' }); } listen() { const server = this.server const port = this.port server.bindAsync( `0.0.0.0:${port}`, grpc.ServerCredentials.createInsecure(), function () { logger.info(`PaymentService gRPC server started on port ${port}`); server.start(); } ); } loadProto(path) { const packageDefinition = protoLoader.loadSync( path, { keepCase: true, longs: String, enums: String, defaults: true, oneofs: true } ); return grpc.loadPackageDefinition(packageDefinition); } loadAllProtos(protoRoot) { const hipsterShopPackage = this.packages.hipsterShop.hipstershop; const healthPackage = this.packages.health.grpc.health.v1; this.server.addService( hipsterShopPackage.PaymentService.service, { charge: HipsterShopServer.ChargeServiceHandler.bind(this) } ); this.server.addService( healthPackage.Health.service, { check: HipsterShopServer.CheckHandler.bind(this) } ); } } HipsterShopServer.PORT = process.env.PORT; module.exports = HipsterShopServer; ================================================ FILE: microservices-demo/src/productcatalogservice/.dockerignore ================================================ vendor/ ================================================ FILE: microservices-demo/src/productcatalogservice/Dockerfile ================================================ # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. FROM golang:1.18.4-alpine AS builder RUN apk add --no-cache ca-certificates git RUN apk add build-base WORKDIR /src # restore dependencies COPY go.mod go.sum ./ RUN go mod download COPY . . # Skaffold passes in debug-oriented compiler flags ARG SKAFFOLD_GO_GCFLAGS RUN go build -gcflags="${SKAFFOLD_GO_GCFLAGS}" -o /productcatalogservice . FROM alpine AS release RUN apk add --no-cache ca-certificates RUN GRPC_HEALTH_PROBE_VERSION=v0.4.11 && \ wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \ chmod +x /bin/grpc_health_probe WORKDIR /src COPY --from=builder /productcatalogservice ./server COPY products.json . # Definition of this variable is used by 'skaffold debug' to identify a golang binary. # Default behavior - a failure prints a stack trace for the current goroutine. # See https://golang.org/pkg/runtime/ ENV GOTRACEBACK=single EXPOSE 3550 ENTRYPOINT ["/src/server"] ================================================ FILE: microservices-demo/src/productcatalogservice/README.md ================================================ # productcatalogservice Run the following command to restore dependencies to `vendor/` directory: dep ensure --vendor-only ## Dynamic catalog reloading / artificial delay This service has a "dynamic catalog reloading" feature that is purposefully not well implemented. The goal of this feature is to allow you to modify the `products.json` file and have the changes be picked up without having to restart the service. However, this feature is bugged: the catalog is actually reloaded on each request, introducing a noticeable delay in the frontend. This delay will also show up in profiling tools: the `parseCatalog` function will take more than 80% of the CPU time. You can trigger this feature (and the delay) by sending a `USR1` signal and remove it (if needed) by sending a `USR2` signal: ``` # Trigger bug kubectl exec \ $(kubectl get pods -l app=productcatalogservice -o jsonpath='{.items[0].metadata.name}') \ -c server -- kill -USR1 1 # Remove bug kubectl exec \ $(kubectl get pods -l app=productcatalogservice -o jsonpath='{.items[0].metadata.name}') \ -c server -- kill -USR2 1 ``` ## Latency injection This service has an `EXTRA_LATENCY` environment variable. This will inject a sleep for the specified [time.Duration](https://golang.org/pkg/time/#ParseDuration) on every call to to the server. For example, use `EXTRA_LATENCY="5.5s"` to sleep for 5.5 seconds on every request. ================================================ FILE: microservices-demo/src/productcatalogservice/genproto/demo.pb.go ================================================ // Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go. DO NOT EDIT. // source: demo.proto package hipstershop import ( fmt "fmt" proto "github.com/golang/protobuf/proto" math "math" ) import ( context "golang.org/x/net/context" grpc "google.golang.org/grpc" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package type CartItem struct { ProductId string `protobuf:"bytes,1,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` Quantity int32 `protobuf:"varint,2,opt,name=quantity,proto3" json:"quantity,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *CartItem) Reset() { *m = CartItem{} } func (m *CartItem) String() string { return proto.CompactTextString(m) } func (*CartItem) ProtoMessage() {} func (*CartItem) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{0} } func (m *CartItem) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CartItem.Unmarshal(m, b) } func (m *CartItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CartItem.Marshal(b, m, deterministic) } func (m *CartItem) XXX_Merge(src proto.Message) { xxx_messageInfo_CartItem.Merge(m, src) } func (m *CartItem) XXX_Size() int { return xxx_messageInfo_CartItem.Size(m) } func (m *CartItem) XXX_DiscardUnknown() { xxx_messageInfo_CartItem.DiscardUnknown(m) } var xxx_messageInfo_CartItem proto.InternalMessageInfo func (m *CartItem) GetProductId() string { if m != nil { return m.ProductId } return "" } func (m *CartItem) GetQuantity() int32 { if m != nil { return m.Quantity } return 0 } type AddItemRequest struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` Item *CartItem `protobuf:"bytes,2,opt,name=item,proto3" json:"item,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *AddItemRequest) Reset() { *m = AddItemRequest{} } func (m *AddItemRequest) String() string { return proto.CompactTextString(m) } func (*AddItemRequest) ProtoMessage() {} func (*AddItemRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{1} } func (m *AddItemRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AddItemRequest.Unmarshal(m, b) } func (m *AddItemRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_AddItemRequest.Marshal(b, m, deterministic) } func (m *AddItemRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_AddItemRequest.Merge(m, src) } func (m *AddItemRequest) XXX_Size() int { return xxx_messageInfo_AddItemRequest.Size(m) } func (m *AddItemRequest) XXX_DiscardUnknown() { xxx_messageInfo_AddItemRequest.DiscardUnknown(m) } var xxx_messageInfo_AddItemRequest proto.InternalMessageInfo func (m *AddItemRequest) GetUserId() string { if m != nil { return m.UserId } return "" } func (m *AddItemRequest) GetItem() *CartItem { if m != nil { return m.Item } return nil } type EmptyCartRequest struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *EmptyCartRequest) Reset() { *m = EmptyCartRequest{} } func (m *EmptyCartRequest) String() string { return proto.CompactTextString(m) } func (*EmptyCartRequest) ProtoMessage() {} func (*EmptyCartRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{2} } func (m *EmptyCartRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_EmptyCartRequest.Unmarshal(m, b) } func (m *EmptyCartRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_EmptyCartRequest.Marshal(b, m, deterministic) } func (m *EmptyCartRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_EmptyCartRequest.Merge(m, src) } func (m *EmptyCartRequest) XXX_Size() int { return xxx_messageInfo_EmptyCartRequest.Size(m) } func (m *EmptyCartRequest) XXX_DiscardUnknown() { xxx_messageInfo_EmptyCartRequest.DiscardUnknown(m) } var xxx_messageInfo_EmptyCartRequest proto.InternalMessageInfo func (m *EmptyCartRequest) GetUserId() string { if m != nil { return m.UserId } return "" } type GetCartRequest struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *GetCartRequest) Reset() { *m = GetCartRequest{} } func (m *GetCartRequest) String() string { return proto.CompactTextString(m) } func (*GetCartRequest) ProtoMessage() {} func (*GetCartRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{3} } func (m *GetCartRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetCartRequest.Unmarshal(m, b) } func (m *GetCartRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetCartRequest.Marshal(b, m, deterministic) } func (m *GetCartRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_GetCartRequest.Merge(m, src) } func (m *GetCartRequest) XXX_Size() int { return xxx_messageInfo_GetCartRequest.Size(m) } func (m *GetCartRequest) XXX_DiscardUnknown() { xxx_messageInfo_GetCartRequest.DiscardUnknown(m) } var xxx_messageInfo_GetCartRequest proto.InternalMessageInfo func (m *GetCartRequest) GetUserId() string { if m != nil { return m.UserId } return "" } type Cart struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Cart) Reset() { *m = Cart{} } func (m *Cart) String() string { return proto.CompactTextString(m) } func (*Cart) ProtoMessage() {} func (*Cart) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{4} } func (m *Cart) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Cart.Unmarshal(m, b) } func (m *Cart) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Cart.Marshal(b, m, deterministic) } func (m *Cart) XXX_Merge(src proto.Message) { xxx_messageInfo_Cart.Merge(m, src) } func (m *Cart) XXX_Size() int { return xxx_messageInfo_Cart.Size(m) } func (m *Cart) XXX_DiscardUnknown() { xxx_messageInfo_Cart.DiscardUnknown(m) } var xxx_messageInfo_Cart proto.InternalMessageInfo func (m *Cart) GetUserId() string { if m != nil { return m.UserId } return "" } func (m *Cart) GetItems() []*CartItem { if m != nil { return m.Items } return nil } type Empty struct { XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Empty) Reset() { *m = Empty{} } func (m *Empty) String() string { return proto.CompactTextString(m) } func (*Empty) ProtoMessage() {} func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{5} } func (m *Empty) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Empty.Unmarshal(m, b) } func (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Empty.Marshal(b, m, deterministic) } func (m *Empty) XXX_Merge(src proto.Message) { xxx_messageInfo_Empty.Merge(m, src) } func (m *Empty) XXX_Size() int { return xxx_messageInfo_Empty.Size(m) } func (m *Empty) XXX_DiscardUnknown() { xxx_messageInfo_Empty.DiscardUnknown(m) } var xxx_messageInfo_Empty proto.InternalMessageInfo type ListRecommendationsRequest struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` ProductIds []string `protobuf:"bytes,2,rep,name=product_ids,json=productIds,proto3" json:"product_ids,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ListRecommendationsRequest) Reset() { *m = ListRecommendationsRequest{} } func (m *ListRecommendationsRequest) String() string { return proto.CompactTextString(m) } func (*ListRecommendationsRequest) ProtoMessage() {} func (*ListRecommendationsRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{6} } func (m *ListRecommendationsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ListRecommendationsRequest.Unmarshal(m, b) } func (m *ListRecommendationsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ListRecommendationsRequest.Marshal(b, m, deterministic) } func (m *ListRecommendationsRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_ListRecommendationsRequest.Merge(m, src) } func (m *ListRecommendationsRequest) XXX_Size() int { return xxx_messageInfo_ListRecommendationsRequest.Size(m) } func (m *ListRecommendationsRequest) XXX_DiscardUnknown() { xxx_messageInfo_ListRecommendationsRequest.DiscardUnknown(m) } var xxx_messageInfo_ListRecommendationsRequest proto.InternalMessageInfo func (m *ListRecommendationsRequest) GetUserId() string { if m != nil { return m.UserId } return "" } func (m *ListRecommendationsRequest) GetProductIds() []string { if m != nil { return m.ProductIds } return nil } type ListRecommendationsResponse struct { ProductIds []string `protobuf:"bytes,1,rep,name=product_ids,json=productIds,proto3" json:"product_ids,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ListRecommendationsResponse) Reset() { *m = ListRecommendationsResponse{} } func (m *ListRecommendationsResponse) String() string { return proto.CompactTextString(m) } func (*ListRecommendationsResponse) ProtoMessage() {} func (*ListRecommendationsResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{7} } func (m *ListRecommendationsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ListRecommendationsResponse.Unmarshal(m, b) } func (m *ListRecommendationsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ListRecommendationsResponse.Marshal(b, m, deterministic) } func (m *ListRecommendationsResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_ListRecommendationsResponse.Merge(m, src) } func (m *ListRecommendationsResponse) XXX_Size() int { return xxx_messageInfo_ListRecommendationsResponse.Size(m) } func (m *ListRecommendationsResponse) XXX_DiscardUnknown() { xxx_messageInfo_ListRecommendationsResponse.DiscardUnknown(m) } var xxx_messageInfo_ListRecommendationsResponse proto.InternalMessageInfo func (m *ListRecommendationsResponse) GetProductIds() []string { if m != nil { return m.ProductIds } return nil } type Product struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` Picture string `protobuf:"bytes,4,opt,name=picture,proto3" json:"picture,omitempty"` PriceUsd *Money `protobuf:"bytes,5,opt,name=price_usd,json=priceUsd,proto3" json:"price_usd,omitempty"` // Categories such as "clothing" or "kitchen" that can be used to look up // other related products. Categories []string `protobuf:"bytes,6,rep,name=categories,proto3" json:"categories,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Product) Reset() { *m = Product{} } func (m *Product) String() string { return proto.CompactTextString(m) } func (*Product) ProtoMessage() {} func (*Product) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{8} } func (m *Product) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Product.Unmarshal(m, b) } func (m *Product) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Product.Marshal(b, m, deterministic) } func (m *Product) XXX_Merge(src proto.Message) { xxx_messageInfo_Product.Merge(m, src) } func (m *Product) XXX_Size() int { return xxx_messageInfo_Product.Size(m) } func (m *Product) XXX_DiscardUnknown() { xxx_messageInfo_Product.DiscardUnknown(m) } var xxx_messageInfo_Product proto.InternalMessageInfo func (m *Product) GetId() string { if m != nil { return m.Id } return "" } func (m *Product) GetName() string { if m != nil { return m.Name } return "" } func (m *Product) GetDescription() string { if m != nil { return m.Description } return "" } func (m *Product) GetPicture() string { if m != nil { return m.Picture } return "" } func (m *Product) GetPriceUsd() *Money { if m != nil { return m.PriceUsd } return nil } func (m *Product) GetCategories() []string { if m != nil { return m.Categories } return nil } type ListProductsResponse struct { Products []*Product `protobuf:"bytes,1,rep,name=products,proto3" json:"products,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ListProductsResponse) Reset() { *m = ListProductsResponse{} } func (m *ListProductsResponse) String() string { return proto.CompactTextString(m) } func (*ListProductsResponse) ProtoMessage() {} func (*ListProductsResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{9} } func (m *ListProductsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ListProductsResponse.Unmarshal(m, b) } func (m *ListProductsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ListProductsResponse.Marshal(b, m, deterministic) } func (m *ListProductsResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_ListProductsResponse.Merge(m, src) } func (m *ListProductsResponse) XXX_Size() int { return xxx_messageInfo_ListProductsResponse.Size(m) } func (m *ListProductsResponse) XXX_DiscardUnknown() { xxx_messageInfo_ListProductsResponse.DiscardUnknown(m) } var xxx_messageInfo_ListProductsResponse proto.InternalMessageInfo func (m *ListProductsResponse) GetProducts() []*Product { if m != nil { return m.Products } return nil } type GetProductRequest struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *GetProductRequest) Reset() { *m = GetProductRequest{} } func (m *GetProductRequest) String() string { return proto.CompactTextString(m) } func (*GetProductRequest) ProtoMessage() {} func (*GetProductRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{10} } func (m *GetProductRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetProductRequest.Unmarshal(m, b) } func (m *GetProductRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetProductRequest.Marshal(b, m, deterministic) } func (m *GetProductRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_GetProductRequest.Merge(m, src) } func (m *GetProductRequest) XXX_Size() int { return xxx_messageInfo_GetProductRequest.Size(m) } func (m *GetProductRequest) XXX_DiscardUnknown() { xxx_messageInfo_GetProductRequest.DiscardUnknown(m) } var xxx_messageInfo_GetProductRequest proto.InternalMessageInfo func (m *GetProductRequest) GetId() string { if m != nil { return m.Id } return "" } type SearchProductsRequest struct { Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *SearchProductsRequest) Reset() { *m = SearchProductsRequest{} } func (m *SearchProductsRequest) String() string { return proto.CompactTextString(m) } func (*SearchProductsRequest) ProtoMessage() {} func (*SearchProductsRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{11} } func (m *SearchProductsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SearchProductsRequest.Unmarshal(m, b) } func (m *SearchProductsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SearchProductsRequest.Marshal(b, m, deterministic) } func (m *SearchProductsRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_SearchProductsRequest.Merge(m, src) } func (m *SearchProductsRequest) XXX_Size() int { return xxx_messageInfo_SearchProductsRequest.Size(m) } func (m *SearchProductsRequest) XXX_DiscardUnknown() { xxx_messageInfo_SearchProductsRequest.DiscardUnknown(m) } var xxx_messageInfo_SearchProductsRequest proto.InternalMessageInfo func (m *SearchProductsRequest) GetQuery() string { if m != nil { return m.Query } return "" } type SearchProductsResponse struct { Results []*Product `protobuf:"bytes,1,rep,name=results,proto3" json:"results,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *SearchProductsResponse) Reset() { *m = SearchProductsResponse{} } func (m *SearchProductsResponse) String() string { return proto.CompactTextString(m) } func (*SearchProductsResponse) ProtoMessage() {} func (*SearchProductsResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{12} } func (m *SearchProductsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SearchProductsResponse.Unmarshal(m, b) } func (m *SearchProductsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SearchProductsResponse.Marshal(b, m, deterministic) } func (m *SearchProductsResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_SearchProductsResponse.Merge(m, src) } func (m *SearchProductsResponse) XXX_Size() int { return xxx_messageInfo_SearchProductsResponse.Size(m) } func (m *SearchProductsResponse) XXX_DiscardUnknown() { xxx_messageInfo_SearchProductsResponse.DiscardUnknown(m) } var xxx_messageInfo_SearchProductsResponse proto.InternalMessageInfo func (m *SearchProductsResponse) GetResults() []*Product { if m != nil { return m.Results } return nil } type GetQuoteRequest struct { Address *Address `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *GetQuoteRequest) Reset() { *m = GetQuoteRequest{} } func (m *GetQuoteRequest) String() string { return proto.CompactTextString(m) } func (*GetQuoteRequest) ProtoMessage() {} func (*GetQuoteRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{13} } func (m *GetQuoteRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetQuoteRequest.Unmarshal(m, b) } func (m *GetQuoteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetQuoteRequest.Marshal(b, m, deterministic) } func (m *GetQuoteRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_GetQuoteRequest.Merge(m, src) } func (m *GetQuoteRequest) XXX_Size() int { return xxx_messageInfo_GetQuoteRequest.Size(m) } func (m *GetQuoteRequest) XXX_DiscardUnknown() { xxx_messageInfo_GetQuoteRequest.DiscardUnknown(m) } var xxx_messageInfo_GetQuoteRequest proto.InternalMessageInfo func (m *GetQuoteRequest) GetAddress() *Address { if m != nil { return m.Address } return nil } func (m *GetQuoteRequest) GetItems() []*CartItem { if m != nil { return m.Items } return nil } type GetQuoteResponse struct { CostUsd *Money `protobuf:"bytes,1,opt,name=cost_usd,json=costUsd,proto3" json:"cost_usd,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *GetQuoteResponse) Reset() { *m = GetQuoteResponse{} } func (m *GetQuoteResponse) String() string { return proto.CompactTextString(m) } func (*GetQuoteResponse) ProtoMessage() {} func (*GetQuoteResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{14} } func (m *GetQuoteResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetQuoteResponse.Unmarshal(m, b) } func (m *GetQuoteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetQuoteResponse.Marshal(b, m, deterministic) } func (m *GetQuoteResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_GetQuoteResponse.Merge(m, src) } func (m *GetQuoteResponse) XXX_Size() int { return xxx_messageInfo_GetQuoteResponse.Size(m) } func (m *GetQuoteResponse) XXX_DiscardUnknown() { xxx_messageInfo_GetQuoteResponse.DiscardUnknown(m) } var xxx_messageInfo_GetQuoteResponse proto.InternalMessageInfo func (m *GetQuoteResponse) GetCostUsd() *Money { if m != nil { return m.CostUsd } return nil } type ShipOrderRequest struct { Address *Address `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ShipOrderRequest) Reset() { *m = ShipOrderRequest{} } func (m *ShipOrderRequest) String() string { return proto.CompactTextString(m) } func (*ShipOrderRequest) ProtoMessage() {} func (*ShipOrderRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{15} } func (m *ShipOrderRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ShipOrderRequest.Unmarshal(m, b) } func (m *ShipOrderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ShipOrderRequest.Marshal(b, m, deterministic) } func (m *ShipOrderRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_ShipOrderRequest.Merge(m, src) } func (m *ShipOrderRequest) XXX_Size() int { return xxx_messageInfo_ShipOrderRequest.Size(m) } func (m *ShipOrderRequest) XXX_DiscardUnknown() { xxx_messageInfo_ShipOrderRequest.DiscardUnknown(m) } var xxx_messageInfo_ShipOrderRequest proto.InternalMessageInfo func (m *ShipOrderRequest) GetAddress() *Address { if m != nil { return m.Address } return nil } func (m *ShipOrderRequest) GetItems() []*CartItem { if m != nil { return m.Items } return nil } type ShipOrderResponse struct { TrackingId string `protobuf:"bytes,1,opt,name=tracking_id,json=trackingId,proto3" json:"tracking_id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ShipOrderResponse) Reset() { *m = ShipOrderResponse{} } func (m *ShipOrderResponse) String() string { return proto.CompactTextString(m) } func (*ShipOrderResponse) ProtoMessage() {} func (*ShipOrderResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{16} } func (m *ShipOrderResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ShipOrderResponse.Unmarshal(m, b) } func (m *ShipOrderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ShipOrderResponse.Marshal(b, m, deterministic) } func (m *ShipOrderResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_ShipOrderResponse.Merge(m, src) } func (m *ShipOrderResponse) XXX_Size() int { return xxx_messageInfo_ShipOrderResponse.Size(m) } func (m *ShipOrderResponse) XXX_DiscardUnknown() { xxx_messageInfo_ShipOrderResponse.DiscardUnknown(m) } var xxx_messageInfo_ShipOrderResponse proto.InternalMessageInfo func (m *ShipOrderResponse) GetTrackingId() string { if m != nil { return m.TrackingId } return "" } type Address struct { StreetAddress string `protobuf:"bytes,1,opt,name=street_address,json=streetAddress,proto3" json:"street_address,omitempty"` City string `protobuf:"bytes,2,opt,name=city,proto3" json:"city,omitempty"` State string `protobuf:"bytes,3,opt,name=state,proto3" json:"state,omitempty"` Country string `protobuf:"bytes,4,opt,name=country,proto3" json:"country,omitempty"` ZipCode int32 `protobuf:"varint,5,opt,name=zip_code,json=zipCode,proto3" json:"zip_code,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Address) Reset() { *m = Address{} } func (m *Address) String() string { return proto.CompactTextString(m) } func (*Address) ProtoMessage() {} func (*Address) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{17} } func (m *Address) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Address.Unmarshal(m, b) } func (m *Address) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Address.Marshal(b, m, deterministic) } func (m *Address) XXX_Merge(src proto.Message) { xxx_messageInfo_Address.Merge(m, src) } func (m *Address) XXX_Size() int { return xxx_messageInfo_Address.Size(m) } func (m *Address) XXX_DiscardUnknown() { xxx_messageInfo_Address.DiscardUnknown(m) } var xxx_messageInfo_Address proto.InternalMessageInfo func (m *Address) GetStreetAddress() string { if m != nil { return m.StreetAddress } return "" } func (m *Address) GetCity() string { if m != nil { return m.City } return "" } func (m *Address) GetState() string { if m != nil { return m.State } return "" } func (m *Address) GetCountry() string { if m != nil { return m.Country } return "" } func (m *Address) GetZipCode() int32 { if m != nil { return m.ZipCode } return 0 } // Represents an amount of money with its currency type. type Money struct { // The 3-letter currency code defined in ISO 4217. CurrencyCode string `protobuf:"bytes,1,opt,name=currency_code,json=currencyCode,proto3" json:"currency_code,omitempty"` // The whole units of the amount. // For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar. Units int64 `protobuf:"varint,2,opt,name=units,proto3" json:"units,omitempty"` // Number of nano (10^-9) units of the amount. // The value must be between -999,999,999 and +999,999,999 inclusive. // If `units` is positive, `nanos` must be positive or zero. // If `units` is zero, `nanos` can be positive, zero, or negative. // If `units` is negative, `nanos` must be negative or zero. // For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000. Nanos int32 `protobuf:"varint,3,opt,name=nanos,proto3" json:"nanos,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Money) Reset() { *m = Money{} } func (m *Money) String() string { return proto.CompactTextString(m) } func (*Money) ProtoMessage() {} func (*Money) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{18} } func (m *Money) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Money.Unmarshal(m, b) } func (m *Money) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Money.Marshal(b, m, deterministic) } func (m *Money) XXX_Merge(src proto.Message) { xxx_messageInfo_Money.Merge(m, src) } func (m *Money) XXX_Size() int { return xxx_messageInfo_Money.Size(m) } func (m *Money) XXX_DiscardUnknown() { xxx_messageInfo_Money.DiscardUnknown(m) } var xxx_messageInfo_Money proto.InternalMessageInfo func (m *Money) GetCurrencyCode() string { if m != nil { return m.CurrencyCode } return "" } func (m *Money) GetUnits() int64 { if m != nil { return m.Units } return 0 } func (m *Money) GetNanos() int32 { if m != nil { return m.Nanos } return 0 } type GetSupportedCurrenciesResponse struct { // The 3-letter currency code defined in ISO 4217. CurrencyCodes []string `protobuf:"bytes,1,rep,name=currency_codes,json=currencyCodes,proto3" json:"currency_codes,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *GetSupportedCurrenciesResponse) Reset() { *m = GetSupportedCurrenciesResponse{} } func (m *GetSupportedCurrenciesResponse) String() string { return proto.CompactTextString(m) } func (*GetSupportedCurrenciesResponse) ProtoMessage() {} func (*GetSupportedCurrenciesResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{19} } func (m *GetSupportedCurrenciesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSupportedCurrenciesResponse.Unmarshal(m, b) } func (m *GetSupportedCurrenciesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetSupportedCurrenciesResponse.Marshal(b, m, deterministic) } func (m *GetSupportedCurrenciesResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_GetSupportedCurrenciesResponse.Merge(m, src) } func (m *GetSupportedCurrenciesResponse) XXX_Size() int { return xxx_messageInfo_GetSupportedCurrenciesResponse.Size(m) } func (m *GetSupportedCurrenciesResponse) XXX_DiscardUnknown() { xxx_messageInfo_GetSupportedCurrenciesResponse.DiscardUnknown(m) } var xxx_messageInfo_GetSupportedCurrenciesResponse proto.InternalMessageInfo func (m *GetSupportedCurrenciesResponse) GetCurrencyCodes() []string { if m != nil { return m.CurrencyCodes } return nil } type CurrencyConversionRequest struct { From *Money `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"` // The 3-letter currency code defined in ISO 4217. ToCode string `protobuf:"bytes,2,opt,name=to_code,json=toCode,proto3" json:"to_code,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *CurrencyConversionRequest) Reset() { *m = CurrencyConversionRequest{} } func (m *CurrencyConversionRequest) String() string { return proto.CompactTextString(m) } func (*CurrencyConversionRequest) ProtoMessage() {} func (*CurrencyConversionRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{20} } func (m *CurrencyConversionRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CurrencyConversionRequest.Unmarshal(m, b) } func (m *CurrencyConversionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CurrencyConversionRequest.Marshal(b, m, deterministic) } func (m *CurrencyConversionRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_CurrencyConversionRequest.Merge(m, src) } func (m *CurrencyConversionRequest) XXX_Size() int { return xxx_messageInfo_CurrencyConversionRequest.Size(m) } func (m *CurrencyConversionRequest) XXX_DiscardUnknown() { xxx_messageInfo_CurrencyConversionRequest.DiscardUnknown(m) } var xxx_messageInfo_CurrencyConversionRequest proto.InternalMessageInfo func (m *CurrencyConversionRequest) GetFrom() *Money { if m != nil { return m.From } return nil } func (m *CurrencyConversionRequest) GetToCode() string { if m != nil { return m.ToCode } return "" } type CreditCardInfo struct { CreditCardNumber string `protobuf:"bytes,1,opt,name=credit_card_number,json=creditCardNumber,proto3" json:"credit_card_number,omitempty"` CreditCardCvv int32 `protobuf:"varint,2,opt,name=credit_card_cvv,json=creditCardCvv,proto3" json:"credit_card_cvv,omitempty"` CreditCardExpirationYear int32 `protobuf:"varint,3,opt,name=credit_card_expiration_year,json=creditCardExpirationYear,proto3" json:"credit_card_expiration_year,omitempty"` CreditCardExpirationMonth int32 `protobuf:"varint,4,opt,name=credit_card_expiration_month,json=creditCardExpirationMonth,proto3" json:"credit_card_expiration_month,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *CreditCardInfo) Reset() { *m = CreditCardInfo{} } func (m *CreditCardInfo) String() string { return proto.CompactTextString(m) } func (*CreditCardInfo) ProtoMessage() {} func (*CreditCardInfo) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{21} } func (m *CreditCardInfo) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CreditCardInfo.Unmarshal(m, b) } func (m *CreditCardInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CreditCardInfo.Marshal(b, m, deterministic) } func (m *CreditCardInfo) XXX_Merge(src proto.Message) { xxx_messageInfo_CreditCardInfo.Merge(m, src) } func (m *CreditCardInfo) XXX_Size() int { return xxx_messageInfo_CreditCardInfo.Size(m) } func (m *CreditCardInfo) XXX_DiscardUnknown() { xxx_messageInfo_CreditCardInfo.DiscardUnknown(m) } var xxx_messageInfo_CreditCardInfo proto.InternalMessageInfo func (m *CreditCardInfo) GetCreditCardNumber() string { if m != nil { return m.CreditCardNumber } return "" } func (m *CreditCardInfo) GetCreditCardCvv() int32 { if m != nil { return m.CreditCardCvv } return 0 } func (m *CreditCardInfo) GetCreditCardExpirationYear() int32 { if m != nil { return m.CreditCardExpirationYear } return 0 } func (m *CreditCardInfo) GetCreditCardExpirationMonth() int32 { if m != nil { return m.CreditCardExpirationMonth } return 0 } type ChargeRequest struct { Amount *Money `protobuf:"bytes,1,opt,name=amount,proto3" json:"amount,omitempty"` CreditCard *CreditCardInfo `protobuf:"bytes,2,opt,name=credit_card,json=creditCard,proto3" json:"credit_card,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ChargeRequest) Reset() { *m = ChargeRequest{} } func (m *ChargeRequest) String() string { return proto.CompactTextString(m) } func (*ChargeRequest) ProtoMessage() {} func (*ChargeRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{22} } func (m *ChargeRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ChargeRequest.Unmarshal(m, b) } func (m *ChargeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ChargeRequest.Marshal(b, m, deterministic) } func (m *ChargeRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_ChargeRequest.Merge(m, src) } func (m *ChargeRequest) XXX_Size() int { return xxx_messageInfo_ChargeRequest.Size(m) } func (m *ChargeRequest) XXX_DiscardUnknown() { xxx_messageInfo_ChargeRequest.DiscardUnknown(m) } var xxx_messageInfo_ChargeRequest proto.InternalMessageInfo func (m *ChargeRequest) GetAmount() *Money { if m != nil { return m.Amount } return nil } func (m *ChargeRequest) GetCreditCard() *CreditCardInfo { if m != nil { return m.CreditCard } return nil } type ChargeResponse struct { TransactionId string `protobuf:"bytes,1,opt,name=transaction_id,json=transactionId,proto3" json:"transaction_id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ChargeResponse) Reset() { *m = ChargeResponse{} } func (m *ChargeResponse) String() string { return proto.CompactTextString(m) } func (*ChargeResponse) ProtoMessage() {} func (*ChargeResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{23} } func (m *ChargeResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ChargeResponse.Unmarshal(m, b) } func (m *ChargeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ChargeResponse.Marshal(b, m, deterministic) } func (m *ChargeResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_ChargeResponse.Merge(m, src) } func (m *ChargeResponse) XXX_Size() int { return xxx_messageInfo_ChargeResponse.Size(m) } func (m *ChargeResponse) XXX_DiscardUnknown() { xxx_messageInfo_ChargeResponse.DiscardUnknown(m) } var xxx_messageInfo_ChargeResponse proto.InternalMessageInfo func (m *ChargeResponse) GetTransactionId() string { if m != nil { return m.TransactionId } return "" } type OrderItem struct { Item *CartItem `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` Cost *Money `protobuf:"bytes,2,opt,name=cost,proto3" json:"cost,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *OrderItem) Reset() { *m = OrderItem{} } func (m *OrderItem) String() string { return proto.CompactTextString(m) } func (*OrderItem) ProtoMessage() {} func (*OrderItem) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{24} } func (m *OrderItem) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_OrderItem.Unmarshal(m, b) } func (m *OrderItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_OrderItem.Marshal(b, m, deterministic) } func (m *OrderItem) XXX_Merge(src proto.Message) { xxx_messageInfo_OrderItem.Merge(m, src) } func (m *OrderItem) XXX_Size() int { return xxx_messageInfo_OrderItem.Size(m) } func (m *OrderItem) XXX_DiscardUnknown() { xxx_messageInfo_OrderItem.DiscardUnknown(m) } var xxx_messageInfo_OrderItem proto.InternalMessageInfo func (m *OrderItem) GetItem() *CartItem { if m != nil { return m.Item } return nil } func (m *OrderItem) GetCost() *Money { if m != nil { return m.Cost } return nil } type OrderResult struct { OrderId string `protobuf:"bytes,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` ShippingTrackingId string `protobuf:"bytes,2,opt,name=shipping_tracking_id,json=shippingTrackingId,proto3" json:"shipping_tracking_id,omitempty"` ShippingCost *Money `protobuf:"bytes,3,opt,name=shipping_cost,json=shippingCost,proto3" json:"shipping_cost,omitempty"` ShippingAddress *Address `protobuf:"bytes,4,opt,name=shipping_address,json=shippingAddress,proto3" json:"shipping_address,omitempty"` Items []*OrderItem `protobuf:"bytes,5,rep,name=items,proto3" json:"items,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *OrderResult) Reset() { *m = OrderResult{} } func (m *OrderResult) String() string { return proto.CompactTextString(m) } func (*OrderResult) ProtoMessage() {} func (*OrderResult) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{25} } func (m *OrderResult) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_OrderResult.Unmarshal(m, b) } func (m *OrderResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_OrderResult.Marshal(b, m, deterministic) } func (m *OrderResult) XXX_Merge(src proto.Message) { xxx_messageInfo_OrderResult.Merge(m, src) } func (m *OrderResult) XXX_Size() int { return xxx_messageInfo_OrderResult.Size(m) } func (m *OrderResult) XXX_DiscardUnknown() { xxx_messageInfo_OrderResult.DiscardUnknown(m) } var xxx_messageInfo_OrderResult proto.InternalMessageInfo func (m *OrderResult) GetOrderId() string { if m != nil { return m.OrderId } return "" } func (m *OrderResult) GetShippingTrackingId() string { if m != nil { return m.ShippingTrackingId } return "" } func (m *OrderResult) GetShippingCost() *Money { if m != nil { return m.ShippingCost } return nil } func (m *OrderResult) GetShippingAddress() *Address { if m != nil { return m.ShippingAddress } return nil } func (m *OrderResult) GetItems() []*OrderItem { if m != nil { return m.Items } return nil } type SendOrderConfirmationRequest struct { Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` Order *OrderResult `protobuf:"bytes,2,opt,name=order,proto3" json:"order,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *SendOrderConfirmationRequest) Reset() { *m = SendOrderConfirmationRequest{} } func (m *SendOrderConfirmationRequest) String() string { return proto.CompactTextString(m) } func (*SendOrderConfirmationRequest) ProtoMessage() {} func (*SendOrderConfirmationRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{26} } func (m *SendOrderConfirmationRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SendOrderConfirmationRequest.Unmarshal(m, b) } func (m *SendOrderConfirmationRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SendOrderConfirmationRequest.Marshal(b, m, deterministic) } func (m *SendOrderConfirmationRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_SendOrderConfirmationRequest.Merge(m, src) } func (m *SendOrderConfirmationRequest) XXX_Size() int { return xxx_messageInfo_SendOrderConfirmationRequest.Size(m) } func (m *SendOrderConfirmationRequest) XXX_DiscardUnknown() { xxx_messageInfo_SendOrderConfirmationRequest.DiscardUnknown(m) } var xxx_messageInfo_SendOrderConfirmationRequest proto.InternalMessageInfo func (m *SendOrderConfirmationRequest) GetEmail() string { if m != nil { return m.Email } return "" } func (m *SendOrderConfirmationRequest) GetOrder() *OrderResult { if m != nil { return m.Order } return nil } type PlaceOrderRequest struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` UserCurrency string `protobuf:"bytes,2,opt,name=user_currency,json=userCurrency,proto3" json:"user_currency,omitempty"` Address *Address `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"` Email string `protobuf:"bytes,5,opt,name=email,proto3" json:"email,omitempty"` CreditCard *CreditCardInfo `protobuf:"bytes,6,opt,name=credit_card,json=creditCard,proto3" json:"credit_card,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *PlaceOrderRequest) Reset() { *m = PlaceOrderRequest{} } func (m *PlaceOrderRequest) String() string { return proto.CompactTextString(m) } func (*PlaceOrderRequest) ProtoMessage() {} func (*PlaceOrderRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{27} } func (m *PlaceOrderRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PlaceOrderRequest.Unmarshal(m, b) } func (m *PlaceOrderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PlaceOrderRequest.Marshal(b, m, deterministic) } func (m *PlaceOrderRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_PlaceOrderRequest.Merge(m, src) } func (m *PlaceOrderRequest) XXX_Size() int { return xxx_messageInfo_PlaceOrderRequest.Size(m) } func (m *PlaceOrderRequest) XXX_DiscardUnknown() { xxx_messageInfo_PlaceOrderRequest.DiscardUnknown(m) } var xxx_messageInfo_PlaceOrderRequest proto.InternalMessageInfo func (m *PlaceOrderRequest) GetUserId() string { if m != nil { return m.UserId } return "" } func (m *PlaceOrderRequest) GetUserCurrency() string { if m != nil { return m.UserCurrency } return "" } func (m *PlaceOrderRequest) GetAddress() *Address { if m != nil { return m.Address } return nil } func (m *PlaceOrderRequest) GetEmail() string { if m != nil { return m.Email } return "" } func (m *PlaceOrderRequest) GetCreditCard() *CreditCardInfo { if m != nil { return m.CreditCard } return nil } type PlaceOrderResponse struct { Order *OrderResult `protobuf:"bytes,1,opt,name=order,proto3" json:"order,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *PlaceOrderResponse) Reset() { *m = PlaceOrderResponse{} } func (m *PlaceOrderResponse) String() string { return proto.CompactTextString(m) } func (*PlaceOrderResponse) ProtoMessage() {} func (*PlaceOrderResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{28} } func (m *PlaceOrderResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PlaceOrderResponse.Unmarshal(m, b) } func (m *PlaceOrderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PlaceOrderResponse.Marshal(b, m, deterministic) } func (m *PlaceOrderResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_PlaceOrderResponse.Merge(m, src) } func (m *PlaceOrderResponse) XXX_Size() int { return xxx_messageInfo_PlaceOrderResponse.Size(m) } func (m *PlaceOrderResponse) XXX_DiscardUnknown() { xxx_messageInfo_PlaceOrderResponse.DiscardUnknown(m) } var xxx_messageInfo_PlaceOrderResponse proto.InternalMessageInfo func (m *PlaceOrderResponse) GetOrder() *OrderResult { if m != nil { return m.Order } return nil } type AdRequest struct { // List of important key words from the current page describing the context. ContextKeys []string `protobuf:"bytes,1,rep,name=context_keys,json=contextKeys,proto3" json:"context_keys,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *AdRequest) Reset() { *m = AdRequest{} } func (m *AdRequest) String() string { return proto.CompactTextString(m) } func (*AdRequest) ProtoMessage() {} func (*AdRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{29} } func (m *AdRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AdRequest.Unmarshal(m, b) } func (m *AdRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_AdRequest.Marshal(b, m, deterministic) } func (m *AdRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_AdRequest.Merge(m, src) } func (m *AdRequest) XXX_Size() int { return xxx_messageInfo_AdRequest.Size(m) } func (m *AdRequest) XXX_DiscardUnknown() { xxx_messageInfo_AdRequest.DiscardUnknown(m) } var xxx_messageInfo_AdRequest proto.InternalMessageInfo func (m *AdRequest) GetContextKeys() []string { if m != nil { return m.ContextKeys } return nil } type AdResponse struct { Ads []*Ad `protobuf:"bytes,1,rep,name=ads,proto3" json:"ads,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *AdResponse) Reset() { *m = AdResponse{} } func (m *AdResponse) String() string { return proto.CompactTextString(m) } func (*AdResponse) ProtoMessage() {} func (*AdResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{30} } func (m *AdResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AdResponse.Unmarshal(m, b) } func (m *AdResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_AdResponse.Marshal(b, m, deterministic) } func (m *AdResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_AdResponse.Merge(m, src) } func (m *AdResponse) XXX_Size() int { return xxx_messageInfo_AdResponse.Size(m) } func (m *AdResponse) XXX_DiscardUnknown() { xxx_messageInfo_AdResponse.DiscardUnknown(m) } var xxx_messageInfo_AdResponse proto.InternalMessageInfo func (m *AdResponse) GetAds() []*Ad { if m != nil { return m.Ads } return nil } type Ad struct { // url to redirect to when an ad is clicked. RedirectUrl string `protobuf:"bytes,1,opt,name=redirect_url,json=redirectUrl,proto3" json:"redirect_url,omitempty"` // short advertisement text to display. Text string `protobuf:"bytes,2,opt,name=text,proto3" json:"text,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Ad) Reset() { *m = Ad{} } func (m *Ad) String() string { return proto.CompactTextString(m) } func (*Ad) ProtoMessage() {} func (*Ad) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{31} } func (m *Ad) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Ad.Unmarshal(m, b) } func (m *Ad) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Ad.Marshal(b, m, deterministic) } func (m *Ad) XXX_Merge(src proto.Message) { xxx_messageInfo_Ad.Merge(m, src) } func (m *Ad) XXX_Size() int { return xxx_messageInfo_Ad.Size(m) } func (m *Ad) XXX_DiscardUnknown() { xxx_messageInfo_Ad.DiscardUnknown(m) } var xxx_messageInfo_Ad proto.InternalMessageInfo func (m *Ad) GetRedirectUrl() string { if m != nil { return m.RedirectUrl } return "" } func (m *Ad) GetText() string { if m != nil { return m.Text } return "" } func init() { proto.RegisterType((*CartItem)(nil), "hipstershop.CartItem") proto.RegisterType((*AddItemRequest)(nil), "hipstershop.AddItemRequest") proto.RegisterType((*EmptyCartRequest)(nil), "hipstershop.EmptyCartRequest") proto.RegisterType((*GetCartRequest)(nil), "hipstershop.GetCartRequest") proto.RegisterType((*Cart)(nil), "hipstershop.Cart") proto.RegisterType((*Empty)(nil), "hipstershop.Empty") proto.RegisterType((*ListRecommendationsRequest)(nil), "hipstershop.ListRecommendationsRequest") proto.RegisterType((*ListRecommendationsResponse)(nil), "hipstershop.ListRecommendationsResponse") proto.RegisterType((*Product)(nil), "hipstershop.Product") proto.RegisterType((*ListProductsResponse)(nil), "hipstershop.ListProductsResponse") proto.RegisterType((*GetProductRequest)(nil), "hipstershop.GetProductRequest") proto.RegisterType((*SearchProductsRequest)(nil), "hipstershop.SearchProductsRequest") proto.RegisterType((*SearchProductsResponse)(nil), "hipstershop.SearchProductsResponse") proto.RegisterType((*GetQuoteRequest)(nil), "hipstershop.GetQuoteRequest") proto.RegisterType((*GetQuoteResponse)(nil), "hipstershop.GetQuoteResponse") proto.RegisterType((*ShipOrderRequest)(nil), "hipstershop.ShipOrderRequest") proto.RegisterType((*ShipOrderResponse)(nil), "hipstershop.ShipOrderResponse") proto.RegisterType((*Address)(nil), "hipstershop.Address") proto.RegisterType((*Money)(nil), "hipstershop.Money") proto.RegisterType((*GetSupportedCurrenciesResponse)(nil), "hipstershop.GetSupportedCurrenciesResponse") proto.RegisterType((*CurrencyConversionRequest)(nil), "hipstershop.CurrencyConversionRequest") proto.RegisterType((*CreditCardInfo)(nil), "hipstershop.CreditCardInfo") proto.RegisterType((*ChargeRequest)(nil), "hipstershop.ChargeRequest") proto.RegisterType((*ChargeResponse)(nil), "hipstershop.ChargeResponse") proto.RegisterType((*OrderItem)(nil), "hipstershop.OrderItem") proto.RegisterType((*OrderResult)(nil), "hipstershop.OrderResult") proto.RegisterType((*SendOrderConfirmationRequest)(nil), "hipstershop.SendOrderConfirmationRequest") proto.RegisterType((*PlaceOrderRequest)(nil), "hipstershop.PlaceOrderRequest") proto.RegisterType((*PlaceOrderResponse)(nil), "hipstershop.PlaceOrderResponse") proto.RegisterType((*AdRequest)(nil), "hipstershop.AdRequest") proto.RegisterType((*AdResponse)(nil), "hipstershop.AdResponse") proto.RegisterType((*Ad)(nil), "hipstershop.Ad") } // Reference imports to suppress errors if they are not otherwise used. var _ context.Context var _ grpc.ClientConn // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. const _ = grpc.SupportPackageIsVersion4 // CartServiceClient is the client API for CartService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type CartServiceClient interface { AddItem(ctx context.Context, in *AddItemRequest, opts ...grpc.CallOption) (*Empty, error) GetCart(ctx context.Context, in *GetCartRequest, opts ...grpc.CallOption) (*Cart, error) EmptyCart(ctx context.Context, in *EmptyCartRequest, opts ...grpc.CallOption) (*Empty, error) } type cartServiceClient struct { cc *grpc.ClientConn } func NewCartServiceClient(cc *grpc.ClientConn) CartServiceClient { return &cartServiceClient{cc} } func (c *cartServiceClient) AddItem(ctx context.Context, in *AddItemRequest, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) err := c.cc.Invoke(ctx, "/hipstershop.CartService/AddItem", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *cartServiceClient) GetCart(ctx context.Context, in *GetCartRequest, opts ...grpc.CallOption) (*Cart, error) { out := new(Cart) err := c.cc.Invoke(ctx, "/hipstershop.CartService/GetCart", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *cartServiceClient) EmptyCart(ctx context.Context, in *EmptyCartRequest, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) err := c.cc.Invoke(ctx, "/hipstershop.CartService/EmptyCart", in, out, opts...) if err != nil { return nil, err } return out, nil } // CartServiceServer is the server API for CartService service. type CartServiceServer interface { AddItem(context.Context, *AddItemRequest) (*Empty, error) GetCart(context.Context, *GetCartRequest) (*Cart, error) EmptyCart(context.Context, *EmptyCartRequest) (*Empty, error) } func RegisterCartServiceServer(s *grpc.Server, srv CartServiceServer) { s.RegisterService(&_CartService_serviceDesc, srv) } func _CartService_AddItem_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AddItemRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CartServiceServer).AddItem(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CartService/AddItem", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CartServiceServer).AddItem(ctx, req.(*AddItemRequest)) } return interceptor(ctx, in, info, handler) } func _CartService_GetCart_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetCartRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CartServiceServer).GetCart(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CartService/GetCart", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CartServiceServer).GetCart(ctx, req.(*GetCartRequest)) } return interceptor(ctx, in, info, handler) } func _CartService_EmptyCart_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(EmptyCartRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CartServiceServer).EmptyCart(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CartService/EmptyCart", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CartServiceServer).EmptyCart(ctx, req.(*EmptyCartRequest)) } return interceptor(ctx, in, info, handler) } var _CartService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.CartService", HandlerType: (*CartServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "AddItem", Handler: _CartService_AddItem_Handler, }, { MethodName: "GetCart", Handler: _CartService_GetCart_Handler, }, { MethodName: "EmptyCart", Handler: _CartService_EmptyCart_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // RecommendationServiceClient is the client API for RecommendationService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type RecommendationServiceClient interface { ListRecommendations(ctx context.Context, in *ListRecommendationsRequest, opts ...grpc.CallOption) (*ListRecommendationsResponse, error) } type recommendationServiceClient struct { cc *grpc.ClientConn } func NewRecommendationServiceClient(cc *grpc.ClientConn) RecommendationServiceClient { return &recommendationServiceClient{cc} } func (c *recommendationServiceClient) ListRecommendations(ctx context.Context, in *ListRecommendationsRequest, opts ...grpc.CallOption) (*ListRecommendationsResponse, error) { out := new(ListRecommendationsResponse) err := c.cc.Invoke(ctx, "/hipstershop.RecommendationService/ListRecommendations", in, out, opts...) if err != nil { return nil, err } return out, nil } // RecommendationServiceServer is the server API for RecommendationService service. type RecommendationServiceServer interface { ListRecommendations(context.Context, *ListRecommendationsRequest) (*ListRecommendationsResponse, error) } func RegisterRecommendationServiceServer(s *grpc.Server, srv RecommendationServiceServer) { s.RegisterService(&_RecommendationService_serviceDesc, srv) } func _RecommendationService_ListRecommendations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListRecommendationsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(RecommendationServiceServer).ListRecommendations(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.RecommendationService/ListRecommendations", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(RecommendationServiceServer).ListRecommendations(ctx, req.(*ListRecommendationsRequest)) } return interceptor(ctx, in, info, handler) } var _RecommendationService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.RecommendationService", HandlerType: (*RecommendationServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "ListRecommendations", Handler: _RecommendationService_ListRecommendations_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // ProductCatalogServiceClient is the client API for ProductCatalogService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type ProductCatalogServiceClient interface { ListProducts(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ListProductsResponse, error) GetProduct(ctx context.Context, in *GetProductRequest, opts ...grpc.CallOption) (*Product, error) SearchProducts(ctx context.Context, in *SearchProductsRequest, opts ...grpc.CallOption) (*SearchProductsResponse, error) } type productCatalogServiceClient struct { cc *grpc.ClientConn } func NewProductCatalogServiceClient(cc *grpc.ClientConn) ProductCatalogServiceClient { return &productCatalogServiceClient{cc} } func (c *productCatalogServiceClient) ListProducts(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ListProductsResponse, error) { out := new(ListProductsResponse) err := c.cc.Invoke(ctx, "/hipstershop.ProductCatalogService/ListProducts", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *productCatalogServiceClient) GetProduct(ctx context.Context, in *GetProductRequest, opts ...grpc.CallOption) (*Product, error) { out := new(Product) err := c.cc.Invoke(ctx, "/hipstershop.ProductCatalogService/GetProduct", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *productCatalogServiceClient) SearchProducts(ctx context.Context, in *SearchProductsRequest, opts ...grpc.CallOption) (*SearchProductsResponse, error) { out := new(SearchProductsResponse) err := c.cc.Invoke(ctx, "/hipstershop.ProductCatalogService/SearchProducts", in, out, opts...) if err != nil { return nil, err } return out, nil } // ProductCatalogServiceServer is the server API for ProductCatalogService service. type ProductCatalogServiceServer interface { ListProducts(context.Context, *Empty) (*ListProductsResponse, error) GetProduct(context.Context, *GetProductRequest) (*Product, error) SearchProducts(context.Context, *SearchProductsRequest) (*SearchProductsResponse, error) } func RegisterProductCatalogServiceServer(s *grpc.Server, srv ProductCatalogServiceServer) { s.RegisterService(&_ProductCatalogService_serviceDesc, srv) } func _ProductCatalogService_ListProducts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(Empty) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(ProductCatalogServiceServer).ListProducts(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.ProductCatalogService/ListProducts", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ProductCatalogServiceServer).ListProducts(ctx, req.(*Empty)) } return interceptor(ctx, in, info, handler) } func _ProductCatalogService_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.(ProductCatalogServiceServer).GetProduct(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.ProductCatalogService/GetProduct", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ProductCatalogServiceServer).GetProduct(ctx, req.(*GetProductRequest)) } return interceptor(ctx, in, info, handler) } func _ProductCatalogService_SearchProducts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(SearchProductsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(ProductCatalogServiceServer).SearchProducts(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.ProductCatalogService/SearchProducts", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ProductCatalogServiceServer).SearchProducts(ctx, req.(*SearchProductsRequest)) } return interceptor(ctx, in, info, handler) } var _ProductCatalogService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.ProductCatalogService", HandlerType: (*ProductCatalogServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "ListProducts", Handler: _ProductCatalogService_ListProducts_Handler, }, { MethodName: "GetProduct", Handler: _ProductCatalogService_GetProduct_Handler, }, { MethodName: "SearchProducts", Handler: _ProductCatalogService_SearchProducts_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // ShippingServiceClient is the client API for ShippingService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type ShippingServiceClient interface { GetQuote(ctx context.Context, in *GetQuoteRequest, opts ...grpc.CallOption) (*GetQuoteResponse, error) ShipOrder(ctx context.Context, in *ShipOrderRequest, opts ...grpc.CallOption) (*ShipOrderResponse, error) } type shippingServiceClient struct { cc *grpc.ClientConn } func NewShippingServiceClient(cc *grpc.ClientConn) ShippingServiceClient { return &shippingServiceClient{cc} } func (c *shippingServiceClient) GetQuote(ctx context.Context, in *GetQuoteRequest, opts ...grpc.CallOption) (*GetQuoteResponse, error) { out := new(GetQuoteResponse) err := c.cc.Invoke(ctx, "/hipstershop.ShippingService/GetQuote", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *shippingServiceClient) ShipOrder(ctx context.Context, in *ShipOrderRequest, opts ...grpc.CallOption) (*ShipOrderResponse, error) { out := new(ShipOrderResponse) err := c.cc.Invoke(ctx, "/hipstershop.ShippingService/ShipOrder", in, out, opts...) if err != nil { return nil, err } return out, nil } // ShippingServiceServer is the server API for ShippingService service. type ShippingServiceServer interface { GetQuote(context.Context, *GetQuoteRequest) (*GetQuoteResponse, error) ShipOrder(context.Context, *ShipOrderRequest) (*ShipOrderResponse, error) } func RegisterShippingServiceServer(s *grpc.Server, srv ShippingServiceServer) { s.RegisterService(&_ShippingService_serviceDesc, srv) } func _ShippingService_GetQuote_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetQuoteRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(ShippingServiceServer).GetQuote(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.ShippingService/GetQuote", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ShippingServiceServer).GetQuote(ctx, req.(*GetQuoteRequest)) } return interceptor(ctx, in, info, handler) } func _ShippingService_ShipOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ShipOrderRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(ShippingServiceServer).ShipOrder(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.ShippingService/ShipOrder", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ShippingServiceServer).ShipOrder(ctx, req.(*ShipOrderRequest)) } return interceptor(ctx, in, info, handler) } var _ShippingService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.ShippingService", HandlerType: (*ShippingServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "GetQuote", Handler: _ShippingService_GetQuote_Handler, }, { MethodName: "ShipOrder", Handler: _ShippingService_ShipOrder_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // CurrencyServiceClient is the client API for CurrencyService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type CurrencyServiceClient interface { GetSupportedCurrencies(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetSupportedCurrenciesResponse, error) Convert(ctx context.Context, in *CurrencyConversionRequest, opts ...grpc.CallOption) (*Money, error) } type currencyServiceClient struct { cc *grpc.ClientConn } func NewCurrencyServiceClient(cc *grpc.ClientConn) CurrencyServiceClient { return ¤cyServiceClient{cc} } func (c *currencyServiceClient) GetSupportedCurrencies(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetSupportedCurrenciesResponse, error) { out := new(GetSupportedCurrenciesResponse) err := c.cc.Invoke(ctx, "/hipstershop.CurrencyService/GetSupportedCurrencies", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *currencyServiceClient) Convert(ctx context.Context, in *CurrencyConversionRequest, opts ...grpc.CallOption) (*Money, error) { out := new(Money) err := c.cc.Invoke(ctx, "/hipstershop.CurrencyService/Convert", in, out, opts...) if err != nil { return nil, err } return out, nil } // CurrencyServiceServer is the server API for CurrencyService service. type CurrencyServiceServer interface { GetSupportedCurrencies(context.Context, *Empty) (*GetSupportedCurrenciesResponse, error) Convert(context.Context, *CurrencyConversionRequest) (*Money, error) } func RegisterCurrencyServiceServer(s *grpc.Server, srv CurrencyServiceServer) { s.RegisterService(&_CurrencyService_serviceDesc, srv) } func _CurrencyService_GetSupportedCurrencies_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(Empty) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CurrencyServiceServer).GetSupportedCurrencies(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CurrencyService/GetSupportedCurrencies", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CurrencyServiceServer).GetSupportedCurrencies(ctx, req.(*Empty)) } return interceptor(ctx, in, info, handler) } func _CurrencyService_Convert_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CurrencyConversionRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CurrencyServiceServer).Convert(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CurrencyService/Convert", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CurrencyServiceServer).Convert(ctx, req.(*CurrencyConversionRequest)) } return interceptor(ctx, in, info, handler) } var _CurrencyService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.CurrencyService", HandlerType: (*CurrencyServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "GetSupportedCurrencies", Handler: _CurrencyService_GetSupportedCurrencies_Handler, }, { MethodName: "Convert", Handler: _CurrencyService_Convert_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // PaymentServiceClient is the client API for PaymentService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type PaymentServiceClient interface { Charge(ctx context.Context, in *ChargeRequest, opts ...grpc.CallOption) (*ChargeResponse, error) } type paymentServiceClient struct { cc *grpc.ClientConn } func NewPaymentServiceClient(cc *grpc.ClientConn) PaymentServiceClient { return &paymentServiceClient{cc} } func (c *paymentServiceClient) Charge(ctx context.Context, in *ChargeRequest, opts ...grpc.CallOption) (*ChargeResponse, error) { out := new(ChargeResponse) err := c.cc.Invoke(ctx, "/hipstershop.PaymentService/Charge", in, out, opts...) if err != nil { return nil, err } return out, nil } // PaymentServiceServer is the server API for PaymentService service. type PaymentServiceServer interface { Charge(context.Context, *ChargeRequest) (*ChargeResponse, error) } func RegisterPaymentServiceServer(s *grpc.Server, srv PaymentServiceServer) { s.RegisterService(&_PaymentService_serviceDesc, srv) } func _PaymentService_Charge_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ChargeRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(PaymentServiceServer).Charge(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.PaymentService/Charge", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(PaymentServiceServer).Charge(ctx, req.(*ChargeRequest)) } return interceptor(ctx, in, info, handler) } var _PaymentService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.PaymentService", HandlerType: (*PaymentServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "Charge", Handler: _PaymentService_Charge_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // EmailServiceClient is the client API for EmailService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type EmailServiceClient interface { SendOrderConfirmation(ctx context.Context, in *SendOrderConfirmationRequest, opts ...grpc.CallOption) (*Empty, error) } type emailServiceClient struct { cc *grpc.ClientConn } func NewEmailServiceClient(cc *grpc.ClientConn) EmailServiceClient { return &emailServiceClient{cc} } func (c *emailServiceClient) SendOrderConfirmation(ctx context.Context, in *SendOrderConfirmationRequest, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) err := c.cc.Invoke(ctx, "/hipstershop.EmailService/SendOrderConfirmation", in, out, opts...) if err != nil { return nil, err } return out, nil } // EmailServiceServer is the server API for EmailService service. type EmailServiceServer interface { SendOrderConfirmation(context.Context, *SendOrderConfirmationRequest) (*Empty, error) } func RegisterEmailServiceServer(s *grpc.Server, srv EmailServiceServer) { s.RegisterService(&_EmailService_serviceDesc, srv) } func _EmailService_SendOrderConfirmation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(SendOrderConfirmationRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(EmailServiceServer).SendOrderConfirmation(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.EmailService/SendOrderConfirmation", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(EmailServiceServer).SendOrderConfirmation(ctx, req.(*SendOrderConfirmationRequest)) } return interceptor(ctx, in, info, handler) } var _EmailService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.EmailService", HandlerType: (*EmailServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "SendOrderConfirmation", Handler: _EmailService_SendOrderConfirmation_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // CheckoutServiceClient is the client API for CheckoutService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type CheckoutServiceClient interface { PlaceOrder(ctx context.Context, in *PlaceOrderRequest, opts ...grpc.CallOption) (*PlaceOrderResponse, error) } type checkoutServiceClient struct { cc *grpc.ClientConn } func NewCheckoutServiceClient(cc *grpc.ClientConn) CheckoutServiceClient { return &checkoutServiceClient{cc} } func (c *checkoutServiceClient) PlaceOrder(ctx context.Context, in *PlaceOrderRequest, opts ...grpc.CallOption) (*PlaceOrderResponse, error) { out := new(PlaceOrderResponse) err := c.cc.Invoke(ctx, "/hipstershop.CheckoutService/PlaceOrder", in, out, opts...) if err != nil { return nil, err } return out, nil } // CheckoutServiceServer is the server API for CheckoutService service. type CheckoutServiceServer interface { PlaceOrder(context.Context, *PlaceOrderRequest) (*PlaceOrderResponse, error) } func RegisterCheckoutServiceServer(s *grpc.Server, srv CheckoutServiceServer) { s.RegisterService(&_CheckoutService_serviceDesc, srv) } func _CheckoutService_PlaceOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(PlaceOrderRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CheckoutServiceServer).PlaceOrder(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CheckoutService/PlaceOrder", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CheckoutServiceServer).PlaceOrder(ctx, req.(*PlaceOrderRequest)) } return interceptor(ctx, in, info, handler) } var _CheckoutService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.CheckoutService", HandlerType: (*CheckoutServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "PlaceOrder", Handler: _CheckoutService_PlaceOrder_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // AdServiceClient is the client API for AdService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type AdServiceClient interface { GetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error) } type adServiceClient struct { cc *grpc.ClientConn } func NewAdServiceClient(cc *grpc.ClientConn) AdServiceClient { return &adServiceClient{cc} } func (c *adServiceClient) GetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error) { out := new(AdResponse) err := c.cc.Invoke(ctx, "/hipstershop.AdService/GetAds", in, out, opts...) if err != nil { return nil, err } return out, nil } // AdServiceServer is the server API for AdService service. type AdServiceServer interface { GetAds(context.Context, *AdRequest) (*AdResponse, error) } func RegisterAdServiceServer(s *grpc.Server, srv AdServiceServer) { s.RegisterService(&_AdService_serviceDesc, srv) } func _AdService_GetAds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AdRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(AdServiceServer).GetAds(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.AdService/GetAds", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(AdServiceServer).GetAds(ctx, req.(*AdRequest)) } return interceptor(ctx, in, info, handler) } var _AdService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.AdService", HandlerType: (*AdServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "GetAds", Handler: _AdService_GetAds_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } func init() { proto.RegisterFile("demo.proto", fileDescriptor_ca53982754088a9d) } var fileDescriptor_ca53982754088a9d = []byte{ // 1500 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xef, 0x72, 0x13, 0xb7, 0x16, 0xcf, 0x26, 0xb1, 0x1d, 0x1f, 0xc7, 0x4e, 0xa2, 0x9b, 0x04, 0xb3, 0x81, 0x10, 0x94, 0x81, 0x0b, 0x17, 0x08, 0x4c, 0xee, 0x9d, 0xe1, 0x03, 0xdc, 0xd2, 0x8c, 0xc9, 0x18, 0x4f, 0xa1, 0xd0, 0x0d, 0xe9, 0xd0, 0xa1, 0x53, 0xcf, 0xb2, 0x12, 0xf1, 0x96, 0xec, 0x6a, 0x91, 0xb4, 0x19, 0xcc, 0xc7, 0xf6, 0x01, 0xfa, 0x1e, 0x7d, 0x81, 0xce, 0xf4, 0x11, 0xfa, 0xbd, 0xaf, 0xd0, 0xe7, 0xe8, 0x48, 0xbb, 0xda, 0x7f, 0xb1, 0x13, 0xf8, 0xd2, 0x6f, 0xab, 0xa3, 0x9f, 0xce, 0xf9, 0xe9, 0xe8, 0xfc, 0xb3, 0x01, 0x08, 0x0d, 0xd8, 0x4e, 0xc4, 0x99, 0x64, 0xa8, 0x35, 0xf2, 0x23, 0x21, 0x29, 0x17, 0x23, 0x16, 0xe1, 0x7d, 0x58, 0xe8, 0xb9, 0x5c, 0x0e, 0x24, 0x0d, 0xd0, 0x65, 0x80, 0x88, 0x33, 0x12, 0x7b, 0x72, 0xe8, 0x93, 0xae, 0xb5, 0x65, 0xdd, 0x68, 0x3a, 0xcd, 0x54, 0x32, 0x20, 0xc8, 0x86, 0x85, 0xf7, 0xb1, 0x1b, 0x4a, 0x5f, 0x8e, 0xbb, 0xb3, 0x5b, 0xd6, 0x8d, 0x9a, 0x93, 0xad, 0xf1, 0x4b, 0xe8, 0xec, 0x11, 0xa2, 0xb4, 0x38, 0xf4, 0x7d, 0x4c, 0x85, 0x44, 0x17, 0xa0, 0x11, 0x0b, 0xca, 0x73, 0x4d, 0x75, 0xb5, 0x1c, 0x10, 0x74, 0x13, 0xe6, 0x7d, 0x49, 0x03, 0xad, 0xa2, 0xb5, 0xbb, 0xb6, 0x53, 0x60, 0xb3, 0x63, 0xa8, 0x38, 0x1a, 0x82, 0x6f, 0xc1, 0xf2, 0x7e, 0x10, 0xc9, 0xb1, 0x12, 0x9f, 0xa7, 0x17, 0xdf, 0x84, 0x4e, 0x9f, 0xca, 0x4f, 0x82, 0x3e, 0x85, 0x79, 0x85, 0x9b, 0xce, 0xf1, 0x16, 0xd4, 0x14, 0x01, 0xd1, 0x9d, 0xdd, 0x9a, 0x9b, 0x4e, 0x32, 0xc1, 0xe0, 0x06, 0xd4, 0x34, 0x4b, 0xfc, 0x2d, 0xd8, 0x4f, 0x7d, 0x21, 0x1d, 0xea, 0xb1, 0x20, 0xa0, 0x21, 0x71, 0xa5, 0xcf, 0x42, 0x71, 0xae, 0x43, 0xae, 0x40, 0x2b, 0x77, 0x7b, 0x62, 0xb2, 0xe9, 0x40, 0xe6, 0x77, 0x81, 0xbf, 0x80, 0x8d, 0x89, 0x7a, 0x45, 0xc4, 0x42, 0x41, 0xab, 0xe7, 0xad, 0x53, 0xe7, 0x7f, 0xb7, 0xa0, 0xf1, 0x22, 0x59, 0xa2, 0x0e, 0xcc, 0x66, 0x04, 0x66, 0x7d, 0x82, 0x10, 0xcc, 0x87, 0x6e, 0x40, 0xf5, 0x6b, 0x34, 0x1d, 0xfd, 0x8d, 0xb6, 0xa0, 0x45, 0xa8, 0xf0, 0xb8, 0x1f, 0x29, 0x43, 0xdd, 0x39, 0xbd, 0x55, 0x14, 0xa1, 0x2e, 0x34, 0x22, 0xdf, 0x93, 0x31, 0xa7, 0xdd, 0x79, 0xbd, 0x6b, 0x96, 0xe8, 0x2e, 0x34, 0x23, 0xee, 0x7b, 0x74, 0x18, 0x0b, 0xd2, 0xad, 0xe9, 0x27, 0x46, 0x25, 0xef, 0x3d, 0x63, 0x21, 0x1d, 0x3b, 0x0b, 0x1a, 0x74, 0x28, 0x08, 0xda, 0x04, 0xf0, 0x5c, 0x49, 0x8f, 0x18, 0xf7, 0xa9, 0xe8, 0xd6, 0x13, 0xf2, 0xb9, 0x04, 0x3f, 0x81, 0x55, 0x75, 0xf9, 0x94, 0x7f, 0x7e, 0xeb, 0x7b, 0xb0, 0x90, 0x5e, 0x31, 0xb9, 0x72, 0x6b, 0x77, 0xb5, 0x64, 0x27, 0x3d, 0xe0, 0x64, 0x28, 0xbc, 0x0d, 0x2b, 0x7d, 0x6a, 0x14, 0x99, 0x57, 0xa9, 0xf8, 0x03, 0xdf, 0x81, 0xb5, 0x03, 0xea, 0x72, 0x6f, 0x94, 0x1b, 0x4c, 0x80, 0xab, 0x50, 0x7b, 0x1f, 0x53, 0x3e, 0x4e, 0xb1, 0xc9, 0x02, 0x3f, 0x81, 0xf5, 0x2a, 0x3c, 0xe5, 0xb7, 0x03, 0x0d, 0x4e, 0x45, 0x7c, 0x7c, 0x0e, 0x3d, 0x03, 0xc2, 0x21, 0x2c, 0xf5, 0xa9, 0xfc, 0x26, 0x66, 0x92, 0x1a, 0x93, 0x3b, 0xd0, 0x70, 0x09, 0xe1, 0x54, 0x08, 0x6d, 0xb4, 0xaa, 0x62, 0x2f, 0xd9, 0x73, 0x0c, 0xe8, 0xf3, 0xa2, 0x76, 0x0f, 0x96, 0x73, 0x7b, 0x29, 0xe7, 0x3b, 0xb0, 0xe0, 0x31, 0x21, 0xf5, 0xdb, 0x59, 0x53, 0xdf, 0xae, 0xa1, 0x30, 0x87, 0x82, 0x60, 0x06, 0xcb, 0x07, 0x23, 0x3f, 0x7a, 0xce, 0x09, 0xe5, 0xff, 0x08, 0xe7, 0xff, 0xc1, 0x4a, 0xc1, 0x60, 0x1e, 0xfe, 0x92, 0xbb, 0xde, 0x3b, 0x3f, 0x3c, 0xca, 0x73, 0x0b, 0x8c, 0x68, 0x40, 0xf0, 0x2f, 0x16, 0x34, 0x52, 0xbb, 0xe8, 0x1a, 0x74, 0x84, 0xe4, 0x94, 0xca, 0x61, 0x91, 0x65, 0xd3, 0x69, 0x27, 0x52, 0x03, 0x43, 0x30, 0xef, 0x99, 0x32, 0xd7, 0x74, 0xf4, 0xb7, 0x0a, 0x00, 0x21, 0x5d, 0x49, 0xd3, 0x7c, 0x48, 0x16, 0x2a, 0x13, 0x3c, 0x16, 0x87, 0x92, 0x8f, 0x4d, 0x26, 0xa4, 0x4b, 0x74, 0x11, 0x16, 0x3e, 0xfa, 0xd1, 0xd0, 0x63, 0x84, 0xea, 0x44, 0xa8, 0x39, 0x8d, 0x8f, 0x7e, 0xd4, 0x63, 0x84, 0xe2, 0x57, 0x50, 0xd3, 0xae, 0x44, 0xdb, 0xd0, 0xf6, 0x62, 0xce, 0x69, 0xe8, 0x8d, 0x13, 0x60, 0xc2, 0x66, 0xd1, 0x08, 0x15, 0x5a, 0x19, 0x8e, 0x43, 0x5f, 0x0a, 0xcd, 0x66, 0xce, 0x49, 0x16, 0x4a, 0x1a, 0xba, 0x21, 0x13, 0x9a, 0x4e, 0xcd, 0x49, 0x16, 0xb8, 0x0f, 0x9b, 0x7d, 0x2a, 0x0f, 0xe2, 0x28, 0x62, 0x5c, 0x52, 0xd2, 0x4b, 0xf4, 0xf8, 0x34, 0x8f, 0xcb, 0x6b, 0xd0, 0x29, 0x99, 0x34, 0x05, 0xa3, 0x5d, 0xb4, 0x29, 0xf0, 0xf7, 0x70, 0xb1, 0x97, 0x09, 0xc2, 0x13, 0xca, 0x85, 0xcf, 0x42, 0xf3, 0xc8, 0xd7, 0x61, 0xfe, 0x2d, 0x67, 0xc1, 0x19, 0x31, 0xa2, 0xf7, 0x55, 0xc9, 0x93, 0x2c, 0xb9, 0x58, 0xe2, 0xc9, 0xba, 0x64, 0xda, 0x01, 0x7f, 0x59, 0xd0, 0xe9, 0x71, 0x4a, 0x7c, 0x55, 0xaf, 0xc9, 0x20, 0x7c, 0xcb, 0xd0, 0x6d, 0x40, 0x9e, 0x96, 0x0c, 0x3d, 0x97, 0x93, 0x61, 0x18, 0x07, 0x6f, 0x28, 0x4f, 0xfd, 0xb1, 0xec, 0x65, 0xd8, 0xaf, 0xb5, 0x1c, 0x5d, 0x87, 0xa5, 0x22, 0xda, 0x3b, 0x39, 0x49, 0x5b, 0x52, 0x3b, 0x87, 0xf6, 0x4e, 0x4e, 0xd0, 0xff, 0x61, 0xa3, 0x88, 0xa3, 0x1f, 0x22, 0x9f, 0xeb, 0xf2, 0x39, 0x1c, 0x53, 0x97, 0xa7, 0xbe, 0xeb, 0xe6, 0x67, 0xf6, 0x33, 0xc0, 0x77, 0xd4, 0xe5, 0xe8, 0x11, 0x5c, 0x9a, 0x72, 0x3c, 0x60, 0xa1, 0x1c, 0xe9, 0x27, 0xaf, 0x39, 0x17, 0x27, 0x9d, 0x7f, 0xa6, 0x00, 0x78, 0x0c, 0xed, 0xde, 0xc8, 0xe5, 0x47, 0x59, 0x4e, 0xff, 0x07, 0xea, 0x6e, 0xa0, 0x22, 0xe4, 0x0c, 0xe7, 0xa5, 0x08, 0xf4, 0x10, 0x5a, 0x05, 0xeb, 0x69, 0xc3, 0xdc, 0x28, 0x67, 0x48, 0xc9, 0x89, 0x0e, 0xe4, 0x4c, 0xf0, 0x7d, 0xe8, 0x18, 0xd3, 0xf9, 0xd3, 0x4b, 0xee, 0x86, 0xc2, 0xf5, 0xf4, 0x15, 0xb2, 0x64, 0x69, 0x17, 0xa4, 0x03, 0x82, 0x7f, 0x80, 0xa6, 0xce, 0x30, 0x3d, 0x13, 0x98, 0x6e, 0x6d, 0x9d, 0xdb, 0xad, 0x55, 0x54, 0xa8, 0xca, 0x90, 0xf2, 0x9c, 0x18, 0x15, 0x6a, 0x1f, 0xff, 0x34, 0x0b, 0x2d, 0x93, 0xc2, 0xf1, 0xb1, 0x54, 0x89, 0xc2, 0xd4, 0x32, 0x27, 0xd4, 0xd0, 0xeb, 0x01, 0x41, 0xf7, 0x60, 0x55, 0x8c, 0xfc, 0x28, 0x52, 0xb9, 0x5d, 0x4c, 0xf2, 0x24, 0x9a, 0x90, 0xd9, 0x7b, 0x99, 0x25, 0x3b, 0xba, 0x0f, 0xed, 0xec, 0x84, 0x66, 0x33, 0x37, 0x95, 0xcd, 0xa2, 0x01, 0xf6, 0x98, 0x90, 0xe8, 0x11, 0x2c, 0x67, 0x07, 0x4d, 0x6d, 0x98, 0x3f, 0xa3, 0x82, 0x2d, 0x19, 0xb4, 0xa9, 0x19, 0xb7, 0x4d, 0x25, 0xab, 0xe9, 0x4a, 0xb6, 0x5e, 0x3a, 0x95, 0x39, 0xd4, 0x94, 0x32, 0x02, 0x97, 0x0e, 0x68, 0x48, 0xb4, 0xbc, 0xc7, 0xc2, 0xb7, 0x3e, 0x0f, 0x74, 0xd8, 0x14, 0xda, 0x0d, 0x0d, 0x5c, 0xff, 0xd8, 0xb4, 0x1b, 0xbd, 0x40, 0x3b, 0x50, 0xd3, 0xae, 0x49, 0x7d, 0xdc, 0x3d, 0x6d, 0x23, 0xf1, 0xa9, 0x93, 0xc0, 0xf0, 0x9f, 0x16, 0xac, 0xbc, 0x38, 0x76, 0x3d, 0x5a, 0xaa, 0xd1, 0x53, 0x27, 0x91, 0x6d, 0x68, 0xeb, 0x0d, 0x53, 0x0a, 0x52, 0x3f, 0x2f, 0x2a, 0xa1, 0xa9, 0x06, 0xc5, 0x0a, 0x3f, 0xf7, 0x29, 0x15, 0x3e, 0xbb, 0x49, 0xad, 0x78, 0x93, 0x4a, 0x6c, 0xd7, 0x3f, 0x2f, 0xb6, 0x1f, 0x03, 0x2a, 0x5e, 0x2b, 0x6b, 0xb9, 0xa9, 0x77, 0xac, 0x4f, 0xf3, 0xce, 0x0e, 0x34, 0xf7, 0x88, 0x71, 0xca, 0x55, 0x58, 0xf4, 0x58, 0x28, 0xe9, 0x07, 0x39, 0x7c, 0x47, 0xc7, 0xa6, 0x2a, 0xb6, 0x52, 0xd9, 0x57, 0x74, 0x2c, 0xf0, 0x5d, 0x00, 0x85, 0x4f, 0xad, 0x5d, 0x85, 0x39, 0x97, 0x98, 0xe6, 0xbe, 0x54, 0xf1, 0x81, 0xa3, 0xf6, 0xf0, 0x03, 0x98, 0xdd, 0x23, 0x4a, 0xb3, 0x62, 0xce, 0xa9, 0x27, 0x87, 0x31, 0x37, 0x2f, 0xda, 0x32, 0xb2, 0x43, 0x7e, 0xac, 0xfa, 0x8d, 0xb2, 0x62, 0xfa, 0x8d, 0xfa, 0xde, 0xfd, 0xc3, 0x82, 0x96, 0xca, 0xb0, 0x03, 0xca, 0x4f, 0x7c, 0x8f, 0xa2, 0x87, 0xba, 0x8b, 0xe9, 0xa4, 0xdc, 0xa8, 0x7a, 0xbc, 0x30, 0x78, 0xdb, 0xe5, 0x50, 0x4f, 0x26, 0xd3, 0x19, 0xf4, 0x00, 0x1a, 0xe9, 0x74, 0x5c, 0x39, 0x5d, 0x9e, 0x99, 0xed, 0x95, 0x53, 0x19, 0x8e, 0x67, 0xd0, 0x97, 0xd0, 0xcc, 0xe6, 0x70, 0x74, 0xf9, 0xb4, 0xfe, 0xa2, 0x82, 0x89, 0xe6, 0x77, 0x7f, 0xb6, 0x60, 0xad, 0x3c, 0xbf, 0x9a, 0x6b, 0xfd, 0x08, 0xff, 0x9a, 0x30, 0xdc, 0xa2, 0x7f, 0x97, 0xd4, 0x4c, 0x1f, 0xab, 0xed, 0x1b, 0xe7, 0x03, 0x93, 0x07, 0x53, 0x2c, 0x66, 0x61, 0x2d, 0x1d, 0xbc, 0x7a, 0xae, 0x74, 0x8f, 0xd9, 0x91, 0x61, 0xd1, 0x87, 0xc5, 0xe2, 0x94, 0x89, 0x26, 0xdc, 0xc2, 0xbe, 0x7a, 0xca, 0x52, 0x75, 0xe8, 0xc3, 0x33, 0xe8, 0x31, 0x40, 0x3e, 0x64, 0xa2, 0xcd, 0xaa, 0xab, 0xcb, 0xd3, 0xa7, 0x3d, 0x71, 0x26, 0xc4, 0x33, 0xe8, 0x35, 0x74, 0xca, 0x63, 0x25, 0xc2, 0x25, 0xe4, 0xc4, 0x11, 0xd5, 0xde, 0x3e, 0x13, 0x93, 0x79, 0xe1, 0x57, 0x0b, 0x96, 0x0e, 0xd2, 0xe2, 0x65, 0xee, 0x3f, 0x80, 0x05, 0x33, 0x0d, 0xa2, 0x4b, 0x55, 0xd2, 0xc5, 0xa1, 0xd4, 0xbe, 0x3c, 0x65, 0x37, 0xf3, 0xc0, 0x53, 0x68, 0x66, 0x43, 0x5a, 0x25, 0x58, 0xaa, 0xd3, 0xa2, 0xbd, 0x39, 0x6d, 0x3b, 0x23, 0xfb, 0x9b, 0x05, 0x4b, 0xa6, 0xf4, 0x18, 0xb2, 0xaf, 0x61, 0x7d, 0xf2, 0x90, 0x33, 0xf1, 0xd9, 0x6e, 0x55, 0x09, 0x9f, 0x31, 0x1d, 0xe1, 0x19, 0xd4, 0x87, 0x46, 0x32, 0xf0, 0x48, 0x74, 0xbd, 0x9c, 0x0b, 0xd3, 0xc6, 0x21, 0x7b, 0x42, 0x73, 0xc1, 0x33, 0xbb, 0x87, 0xd0, 0x79, 0xe1, 0x8e, 0x03, 0x1a, 0x66, 0x19, 0xdc, 0x83, 0x7a, 0xd2, 0x91, 0x91, 0x5d, 0xd6, 0x5c, 0x9c, 0x10, 0xec, 0x8d, 0x89, 0x7b, 0x99, 0x43, 0x46, 0xb0, 0xb8, 0xaf, 0x2a, 0xa8, 0x51, 0xfa, 0x4a, 0xfd, 0x60, 0x99, 0xd0, 0x48, 0xd0, 0xcd, 0x4a, 0x34, 0x4c, 0x6f, 0x36, 0x53, 0x72, 0xf6, 0x0d, 0x2c, 0xf5, 0x46, 0xd4, 0x7b, 0xc7, 0xe2, 0xec, 0x06, 0xcf, 0x01, 0xf2, 0xba, 0x5b, 0x89, 0xee, 0x53, 0x7d, 0xc6, 0xbe, 0x32, 0x75, 0x3f, 0xbb, 0xcd, 0x13, 0x55, 0x82, 0x8d, 0xf6, 0x07, 0x50, 0xef, 0xab, 0x19, 0x5c, 0xa0, 0xf5, 0x6a, 0x39, 0x4d, 0x35, 0x5e, 0x38, 0x25, 0x37, 0x9a, 0xde, 0xd4, 0xf5, 0x9f, 0x1b, 0xff, 0xfd, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xb2, 0xa0, 0x6e, 0x6c, 0xea, 0x10, 0x00, 0x00, } ================================================ FILE: microservices-demo/src/productcatalogservice/genproto.sh ================================================ #!/bin/bash -eu # # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # [START gke_productcatalogservice_genproto] PATH=$PATH:$GOPATH/bin protodir=../../pb protoc --go_out=plugins=grpc:genproto -I $protodir $protodir/demo.proto # [END gke_productcatalogservice_genproto] ================================================ FILE: microservices-demo/src/productcatalogservice/go.mod ================================================ module github.com/GoogleCloudPlatform/microservices-demo/src/productcatalogservice go 1.18 require ( cloud.google.com/go/profiler v0.3.0 contrib.go.opencensus.io/exporter/jaeger v0.2.1 contrib.go.opencensus.io/exporter/stackdriver v0.13.12 github.com/golang/protobuf v1.5.2 github.com/google/go-cmp v0.5.8 github.com/sirupsen/logrus v1.8.1 go.opencensus.io v0.23.0 golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b google.golang.org/grpc v1.48.0 ) require ( cloud.google.com/go v0.100.2 // indirect cloud.google.com/go/compute v1.6.1 // indirect cloud.google.com/go/monitoring v1.1.0 // indirect cloud.google.com/go/trace v1.0.0 // indirect github.com/aws/aws-sdk-go v1.43.31 // indirect github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect github.com/cespare/xxhash/v2 v2.1.1 // indirect github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 // indirect github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 // indirect github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 // indirect github.com/envoyproxy/protoc-gen-validate v0.1.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/pprof v0.0.0-20220412212628-83db2b799d1f // indirect github.com/googleapis/gax-go/v2 v2.4.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/prometheus/prometheus v2.5.0+incompatible // indirect github.com/uber/jaeger-client-go v2.25.0+incompatible // indirect golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect golang.org/x/text v0.3.7 // indirect google.golang.org/api v0.78.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335 // indirect google.golang.org/protobuf v1.28.0 // indirect ) ================================================ FILE: microservices-demo/src/productcatalogservice/go.sum ================================================ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go v0.99.0 h1:y/cM2iqGgGi5D5DQZl6D9STN/3dR/Vx5Mp8s752oJTY= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= cloud.google.com/go/compute v1.5.0 h1:b1zWmYuuHz7gO9kDcM/EpHGr06UgsYNRpNJzI2kFiLM= cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= cloud.google.com/go/compute v1.6.1 h1:2sMmt8prCn7DPaG4Pmh0N3Inmc8cT8ae5k1M6VJ9Wqc= cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/monitoring v1.1.0 h1:ZnyNdf/XRcynMmKzRSNTOdOyYPs6G7do1l2D2hIvIKo= cloud.google.com/go/monitoring v1.1.0/go.mod h1:L81pzz7HKn14QCMaCs6NTQkdBnE87TElyanS95vIcl4= cloud.google.com/go/profiler v0.1.1 h1:seMHZtcgOwZXAOKDZuW2sN3u1yKjYG19dUkElb4mbcQ= cloud.google.com/go/profiler v0.1.1/go.mod h1:zG22vSCuJKJMvIlLpX3FhNjOsifaoLdPAYc4yLw5Iw4= cloud.google.com/go/profiler v0.3.0 h1:R6y/xAeifaUXxd2x6w+jIwKxoKl8Cv5HJvcvASTPWJo= cloud.google.com/go/profiler v0.3.0/go.mod h1:9wYk9eY4iZHsev8TQb61kh3wiOiSyz/xOYixWPzweCU= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= cloud.google.com/go/trace v1.0.0 h1:laKx2y7IWMjguCe5zZx6n7qLtREk4kyE69SXVC0VSN8= cloud.google.com/go/trace v1.0.0/go.mod h1:4iErSByzxkyHWzzlAj63/Gmjz0NH1ASqhJguHpGcr6A= contrib.go.opencensus.io/exporter/jaeger v0.2.1 h1:yGBYzYMewVL0yO9qqJv3Z5+IRhPdU7e9o/2oKpX4YvI= contrib.go.opencensus.io/exporter/jaeger v0.2.1/go.mod h1:Y8IsLgdxqh1QxYxPC5IgXVmBaeLUeQFfBeBi9PbeZd0= contrib.go.opencensus.io/exporter/stackdriver v0.13.10 h1:a9+GZPUe+ONKUwULjlEOucMMG0qfSCCenlji0Nhqbys= contrib.go.opencensus.io/exporter/stackdriver v0.13.10/go.mod h1:I5htMbyta491eUxufwwZPQdcKvvgzMB4O9ni41YnIM8= contrib.go.opencensus.io/exporter/stackdriver v0.13.12 h1:bjBKzIf7/TAkxd7L2utGaLM78bmUWlCval5K9UeElbY= contrib.go.opencensus.io/exporter/stackdriver v0.13.12/go.mod h1:mmxnWlrvrFdpiOHOhxBaVi1rkc0WOqhgfknj4Yg0SeQ= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/aws/aws-sdk-go v1.37.0 h1:GzFnhOIsrGyQ69s7VgqtrG2BG8v7X7vwB3Xpbd/DBBk= github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.43.31 h1:yJZIr8nMV1hXjAvvOLUFqZRJcHV7udPQBfhJqawDzI0= github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 h1:hzAQntlaYRkVSFEfj9OTWlVV1H155FMD8BTKktLv0QI= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 h1:zH8ljVhhq7yC0MIeUL/IviMtY8hx2mK8cN9wEYb8ggw= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021 h1:fP+fF0up6oPY49OrjPrhIJ8yQfdIM85NXMLkMg1EXVs= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 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.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= 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/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20211008130755-947d60d73cc0 h1:zHs+jv3LO743/zFGcByu2KmpbliCU2AhjcGgrdTwSG4= github.com/google/pprof v0.0.0-20211008130755-947d60d73cc0/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= github.com/google/pprof v0.0.0-20220412212628-83db2b799d1f h1:VrKTY4lquiy1oJzVZgXrauku9Jx9P+POv/gTLakG4Wk= github.com/google/pprof v0.0.0-20220412212628-83db2b799d1f/go.mod h1:Pt31oes+eGImORns3McJn8zHefuQl2rG8l6xQjGYB4U= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= github.com/googleapis/gax-go/v2 v2.2.0 h1:s7jOdKSaksJVOxE0Y/S32otcfiP+UQ0cL8/GTKaONwE= github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= github.com/googleapis/gax-go/v2 v2.4.0 h1:dS9eYAjhrE2RjmzYw2XAPvcXfmcQLtFEQWn0CR82awk= github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/prometheus v2.5.0+incompatible h1:7QPitgO2kOFG8ecuRn9O/4L9+10He72rVRJvMXrE9Hg= github.com/prometheus/prometheus v2.5.0+incompatible/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/uber/jaeger-client-go v2.25.0+incompatible h1:IxcNZ7WRY1Y3G4poYlx24szfsn/3LvK9QHCq9oQw8+U= github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 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.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220403103023-749bd193bc2b h1:vI32FkLJNAWtGD4BwkThwEy6XS7ZLLMHkSkYfF8M0W0= golang.org/x/net v0.0.0-20220403103023-749bd193bc2b/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220420153159-1850ba15e1be h1:yx80W7nvY5ySWpaU8UWaj5o9e23YgO9BRhQol7Lc+JI= golang.org/x/net v0.0.0-20220420153159-1850ba15e1be/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b h1:3ogNYyK4oIQdIKzTu68hQrr4iuVxF3AxKl9Aj/eDrw0= golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220805013720-a33c5aa5df48 h1:N9Vc/rorQUDes6B9CNdIxAn5jODGj2wzfrei2x4wNj4= golang.org/x/net v0.0.0-20220805013720-a33c5aa5df48/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220809012201-f428fae20770 h1:dIi4qVdvjZEjiMDv7vhokAZNGnz3kepwuXqFKYDdDMs= golang.org/x/net v0.0.0-20220809012201-f428fae20770/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220809184613-07c6da5e1ced h1:3dYNDff0VT5xj+mbj2XucFst9WKk6PdGOrb9n+SbIvw= golang.org/x/net v0.0.0-20220809184613-07c6da5e1ced/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E= golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/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-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886 h1:eJv7u3ksNXoLbGSKuv2s/SIO4tJVxc/A+MTpzxDgz/Q= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba h1:AyHWHCBVlIYI5rgEM3o+1PLd0sLPcIAoaUckGQMaWtw= golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E= google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= google.golang.org/api v0.61.0 h1:TXXKS1slM3b2bZNJwD5DV/Tp6/M2cLzLOLh9PjDhrw8= google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= google.golang.org/api v0.74.0 h1:ExR2D+5TYIrMphWgs5JCgwRhEDlPDXXrLwHHMgPHTXE= google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= google.golang.org/api v0.78.0 h1:5ewPyCwP43C3i8B6C2Kb+eVAevbnke2xR8VbcSWjS4I= google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210921142501-181ce0d877f6/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211018162055-cf77aa76bad2/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0 h1:c7yRRmuQiVMo+YppNj5MUREXUyc2lPo3DrtYMwaWQ28= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb h1:0m9wktIpOxGw+SSKmydXWB3Z3GTfcPP6+q75HCQa6HI= google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335 h1:2D0OT6tPVdrQTOnVe1VQjfJPTED6EZ7fdJ/f6Db6OsY= google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.43.0 h1:Eeu7bZtDZ2DpRCsLhUlcrLnvYaMK1Gz86a+hMVvELmM= google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.46.0 h1:oCjezcn6g6A75TGoKYBPgKmVBLexhYLM6MebdrPApP8= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= ================================================ FILE: microservices-demo/src/productcatalogservice/products.json ================================================ { "products": [ { "id": "OLJCESPC7Z", "name": "Sunglasses", "description": "Add a modern touch to your outfits with these sleek aviator sunglasses.", "picture": "/static/img/products/sunglasses.jpg", "priceUsd": { "currencyCode": "USD", "units": 19, "nanos": 990000000 }, "categories": ["accessories"] }, { "id": "66VCHSJNUP", "name": "Tank Top", "description": "Perfectly cropped cotton tank, with a scooped neckline.", "picture": "/static/img/products/tank-top.jpg", "priceUsd": { "currencyCode": "USD", "units": 18, "nanos": 990000000 }, "categories": ["clothing", "tops"] }, { "id": "1YMWWN1N4O", "name": "Watch", "description": "This gold-tone stainless steel watch will work with most of your outfits.", "picture": "/static/img/products/watch.jpg", "priceUsd": { "currencyCode": "USD", "units": 109, "nanos": 990000000 }, "categories": ["accessories"] }, { "id": "L9ECAV7KIM", "name": "Loafers", "description": "A neat addition to your summer wardrobe.", "picture": "/static/img/products/loafers.jpg", "priceUsd": { "currencyCode": "USD", "units": 89, "nanos": 990000000 }, "categories": ["footwear"] }, { "id": "2ZYFJ3GM2N", "name": "Hairdryer", "description": "This lightweight hairdryer has 3 heat and speed settings. It's perfect for travel.", "picture": "/static/img/products/hairdryer.jpg", "priceUsd": { "currencyCode": "USD", "units": 24, "nanos": 990000000 }, "categories": ["hair", "beauty"] }, { "id": "0PUK6V6EV0", "name": "Candle Holder", "description": "This small but intricate candle holder is an excellent gift.", "picture": "/static/img/products/candle-holder.jpg", "priceUsd": { "currencyCode": "USD", "units": 18, "nanos": 990000000 }, "categories": ["decor", "home"] }, { "id": "LS4PSXUNUM", "name": "Salt & Pepper Shakers", "description": "Add some flavor to your kitchen.", "picture": "/static/img/products/salt-and-pepper-shakers.jpg", "priceUsd": { "currencyCode": "USD", "units": 18, "nanos": 490000000 }, "categories": ["kitchen"] }, { "id": "9SIQT8TOJO", "name": "Bamboo Glass Jar", "description": "This bamboo glass jar can hold 57 oz (1.7 l) and is perfect for any kitchen.", "picture": "/static/img/products/bamboo-glass-jar.jpg", "priceUsd": { "currencyCode": "USD", "units": 5, "nanos": 490000000 }, "categories": ["kitchen"] }, { "id": "6E92ZMYYFZ", "name": "Mug", "description": "A simple mug with a mustard interior.", "picture": "/static/img/products/mug.jpg", "priceUsd": { "currencyCode": "USD", "units": 8, "nanos": 990000000 }, "categories": ["kitchen"] } ] } ================================================ FILE: microservices-demo/src/productcatalogservice/server.go ================================================ // Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "bytes" "context" "flag" "fmt" "io/ioutil" "net" "os" "os/signal" "strings" "sync" "syscall" "time" pb "github.com/GoogleCloudPlatform/microservices-demo/src/productcatalogservice/genproto" healthpb "google.golang.org/grpc/health/grpc_health_v1" "cloud.google.com/go/profiler" "contrib.go.opencensus.io/exporter/jaeger" "contrib.go.opencensus.io/exporter/stackdriver" "github.com/golang/protobuf/jsonpb" "github.com/sirupsen/logrus" // "go.opencensus.io/exporter/jaeger" "go.opencensus.io/plugin/ocgrpc" "go.opencensus.io/stats/view" "go.opencensus.io/trace" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) var ( cat pb.ListProductsResponse catalogMutex *sync.Mutex log *logrus.Logger extraLatency time.Duration port = "3550" reloadCatalog bool ) func init() { log = logrus.New() log.Formatter = &logrus.JSONFormatter{ FieldMap: logrus.FieldMap{ logrus.FieldKeyTime: "timestamp", logrus.FieldKeyLevel: "severity", logrus.FieldKeyMsg: "message", }, TimestampFormat: time.RFC3339Nano, } log.Out = os.Stdout catalogMutex = &sync.Mutex{} err := readCatalogFile(&cat) if err != nil { log.Warnf("could not parse product catalog") } } func main() { if os.Getenv("DISABLE_TRACING") == "" { log.Info("Tracing enabled.") go initTracing() } else { log.Info("Tracing disabled.") } if os.Getenv("DISABLE_PROFILER") == "" { log.Info("Profiling enabled.") go initProfiling("productcatalogservice", "1.0.0") } else { log.Info("Profiling disabled.") } flag.Parse() // set injected latency if s := os.Getenv("EXTRA_LATENCY"); s != "" { v, err := time.ParseDuration(s) if err != nil { log.Fatalf("failed to parse EXTRA_LATENCY (%s) as time.Duration: %+v", v, err) } extraLatency = v log.Infof("extra latency enabled (duration: %v)", extraLatency) } else { extraLatency = time.Duration(0) } sigs := make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGUSR1, syscall.SIGUSR2) go func() { for { sig := <-sigs log.Printf("Received signal: %s", sig) if sig == syscall.SIGUSR1 { reloadCatalog = true log.Infof("Enable catalog reloading") } else { reloadCatalog = false log.Infof("Disable catalog reloading") } } }() if os.Getenv("PORT") != "" { port = os.Getenv("PORT") } log.Infof("starting grpc server at :%s", port) run(port) select {} } func run(port string) string { l, err := net.Listen("tcp", fmt.Sprintf(":%s", port)) if err != nil { log.Fatal(err) } var srv *grpc.Server if os.Getenv("DISABLE_STATS") == "" { log.Info("Stats enabled.") srv = grpc.NewServer(grpc.StatsHandler(&ocgrpc.ServerHandler{})) } else { log.Info("Stats disabled.") srv = grpc.NewServer() } svc := &productCatalog{} pb.RegisterProductCatalogServiceServer(srv, svc) healthpb.RegisterHealthServer(srv, svc) go srv.Serve(l) return l.Addr().String() } func initJaegerTracing() { svcAddr := os.Getenv("JAEGER_SERVICE_ADDR") if svcAddr == "" { log.Info("jaeger initialization disabled.") return } // Register the Jaeger exporter to be able to retrieve // the collected spans. exporter, err := jaeger.NewExporter(jaeger.Options{ Endpoint: fmt.Sprintf("http://%s", svcAddr), Process: jaeger.Process{ ServiceName: "productcatalogservice", }, }) if err != nil { log.Fatal(err) } trace.RegisterExporter(exporter) log.Info("jaeger initialization completed.") } func initStats(exporter *stackdriver.Exporter) { view.SetReportingPeriod(60 * time.Second) view.RegisterExporter(exporter) if err := view.Register(ocgrpc.DefaultServerViews...); err != nil { log.Info("Error registering default server views") } else { log.Info("Registered default server views") } } func initStackdriverTracing() { // TODO(ahmetb) this method is duplicated in other microservices using Go // since they are not sharing packages. for i := 1; i <= 3; i++ { exporter, err := stackdriver.NewExporter(stackdriver.Options{}) if err != nil { log.Warnf("failed to initialize Stackdriver exporter: %+v", err) } else { trace.RegisterExporter(exporter) trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()}) log.Info("registered Stackdriver tracing") // Register the views to collect server stats. initStats(exporter) return } d := time.Second * 10 * time.Duration(i) log.Infof("sleeping %v to retry initializing Stackdriver exporter", d) time.Sleep(d) } log.Warn("could not initialize Stackdriver exporter after retrying, giving up") } func initTracing() { initJaegerTracing() initStackdriverTracing() } func initProfiling(service, version string) { // TODO(ahmetb) this method is duplicated in other microservices using Go // since they are not sharing packages. for i := 1; i <= 3; i++ { if err := profiler.Start(profiler.Config{ Service: service, ServiceVersion: version, // ProjectID must be set if not running on GCP. // ProjectID: "my-project", }); err != nil { log.Warnf("failed to start profiler: %+v", err) } else { log.Info("started Stackdriver profiler") return } d := time.Second * 10 * time.Duration(i) log.Infof("sleeping %v to retry initializing Stackdriver profiler", d) time.Sleep(d) } log.Warn("could not initialize Stackdriver profiler after retrying, giving up") } type productCatalog struct{} func readCatalogFile(catalog *pb.ListProductsResponse) error { catalogMutex.Lock() defer catalogMutex.Unlock() catalogJSON, err := ioutil.ReadFile("products.json") if err != nil { log.Fatalf("failed to open product catalog json file: %v", err) return err } if err := jsonpb.Unmarshal(bytes.NewReader(catalogJSON), catalog); err != nil { log.Warnf("failed to parse the catalog JSON: %v", err) return err } log.Info("successfully parsed product catalog json") return nil } func parseCatalog() []*pb.Product { if reloadCatalog || len(cat.Products) == 0 { err := readCatalogFile(&cat) if err != nil { return []*pb.Product{} } } return cat.Products } func (p *productCatalog) Check(ctx context.Context, req *healthpb.HealthCheckRequest) (*healthpb.HealthCheckResponse, error) { return &healthpb.HealthCheckResponse{Status: healthpb.HealthCheckResponse_SERVING}, nil } func (p *productCatalog) Watch(req *healthpb.HealthCheckRequest, ws healthpb.Health_WatchServer) error { return status.Errorf(codes.Unimplemented, "health check via Watch not implemented") } func (p *productCatalog) ListProducts(context.Context, *pb.Empty) (*pb.ListProductsResponse, error) { time.Sleep(extraLatency) return &pb.ListProductsResponse{Products: parseCatalog()}, nil } func (p *productCatalog) GetProduct(ctx context.Context, req *pb.GetProductRequest) (*pb.Product, error) { time.Sleep(extraLatency) var found *pb.Product for i := 0; i < len(parseCatalog()); i++ { if req.Id == parseCatalog()[i].Id { found = parseCatalog()[i] } } if found == nil { return nil, status.Errorf(codes.NotFound, "no product with ID %s", req.Id) } return found, nil } func (p *productCatalog) SearchProducts(ctx context.Context, req *pb.SearchProductsRequest) (*pb.SearchProductsResponse, error) { time.Sleep(extraLatency) // Intepret query as a substring match in name or description. var ps []*pb.Product for _, p := range parseCatalog() { if strings.Contains(strings.ToLower(p.Name), strings.ToLower(req.Query)) || strings.Contains(strings.ToLower(p.Description), strings.ToLower(req.Query)) { ps = append(ps, p) } } return &pb.SearchProductsResponse{Results: ps}, nil } ================================================ FILE: microservices-demo/src/productcatalogservice/server_test.go ================================================ // Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "context" "testing" pb "github.com/GoogleCloudPlatform/microservices-demo/src/productcatalogservice/genproto" "github.com/golang/protobuf/proto" "github.com/google/go-cmp/cmp" "go.opencensus.io/plugin/ocgrpc" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func TestServer(t *testing.T) { ctx := context.Background() addr := run(port) conn, err := grpc.DialContext(ctx, addr, grpc.WithInsecure(), grpc.WithStatsHandler(&ocgrpc.ClientHandler{})) if err != nil { t.Fatal(err) } defer conn.Close() client := pb.NewProductCatalogServiceClient(conn) res, err := client.ListProducts(ctx, &pb.Empty{}) if err != nil { t.Fatal(err) } if diff := cmp.Diff(res.Products, parseCatalog(), cmp.Comparer(proto.Equal)); diff != "" { t.Error(diff) } got, err := client.GetProduct(ctx, &pb.GetProductRequest{Id: "OLJCESPC7Z"}) if err != nil { t.Fatal(err) } if want := parseCatalog()[0]; !proto.Equal(got, want) { t.Errorf("got %v, want %v", got, want) } _, err = client.GetProduct(ctx, &pb.GetProductRequest{Id: "N/A"}) if got, want := status.Code(err), codes.NotFound; got != want { t.Errorf("got %s, want %s", got, want) } sres, err := client.SearchProducts(ctx, &pb.SearchProductsRequest{Query: "sunglasses"}) if err != nil { t.Fatal(err) } if diff := cmp.Diff(sres.Results, []*pb.Product{parseCatalog()[0]}, cmp.Comparer(proto.Equal)); diff != "" { t.Error(diff) } } ================================================ FILE: microservices-demo/src/recommendationservice/.gitignore ================================================ *.pyc ================================================ FILE: microservices-demo/src/recommendationservice/.python-version ================================================ 3.7 ================================================ FILE: microservices-demo/src/recommendationservice/Dockerfile ================================================ # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. FROM python:3.7-slim RUN apt-get update -qqy && \ apt-get -qqy install wget g++ && \ rm -rf /var/lib/apt/lists/* # show python logs as they occur ENV PYTHONUNBUFFERED=0 # download the grpc health probe RUN GRPC_HEALTH_PROBE_VERSION=v0.4.11 && \ wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \ chmod +x /bin/grpc_health_probe # get packages WORKDIR /recommendationservice COPY requirements.txt requirements.txt RUN pip install -r requirements.txt # add files into working directory COPY . . # set listen port ENV PORT "8080" EXPOSE 8080 ENTRYPOINT ["python", "/recommendationservice/recommendation_server.py"] ================================================ FILE: microservices-demo/src/recommendationservice/Procfile ================================================ web: python /recommendationservice/recommendation_server.py ================================================ FILE: microservices-demo/src/recommendationservice/client.py ================================================ #!/usr/bin/python # # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import sys import grpc import demo_pb2 import demo_pb2_grpc from opencensus.trace.tracer import Tracer from opencensus.trace.exporters import stackdriver_exporter from opencensus.trace.ext.grpc import client_interceptor from logger import getJSONLogger logger = getJSONLogger('recommendationservice-server') if __name__ == "__main__": # get port if len(sys.argv) > 1: port = sys.argv[1] else: port = "8080" try: exporter = stackdriver_exporter.StackdriverExporter() tracer = Tracer(exporter=exporter) tracer_interceptor = client_interceptor.OpenCensusClientInterceptor(tracer, host_port='localhost:'+port) except: tracer_interceptor = client_interceptor.OpenCensusClientInterceptor() # set up server stub channel = grpc.insecure_channel('localhost:'+port) channel = grpc.intercept_channel(channel, tracer_interceptor) stub = demo_pb2_grpc.RecommendationServiceStub(channel) # form request request = demo_pb2.ListRecommendationsRequest(user_id="test", product_ids=["test"]) # make call to server response = stub.ListRecommendations(request) logger.info(response) ================================================ FILE: microservices-demo/src/recommendationservice/demo_pb2.py ================================================ # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Generated by the protocol buffer compiler. DO NOT EDIT! # source: demo.proto import sys _b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from google.protobuf import reflection as _reflection from google.protobuf import symbol_database as _symbol_database from google.protobuf import descriptor_pb2 # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() DESCRIPTOR = _descriptor.FileDescriptor( name='demo.proto', package='hipstershop', syntax='proto3', serialized_pb=_b('\n\ndemo.proto\x12\x0bhipstershop\"0\n\x08\x43\x61rtItem\x12\x12\n\nproduct_id\x18\x01 \x01(\t\x12\x10\n\x08quantity\x18\x02 \x01(\x05\"F\n\x0e\x41\x64\x64ItemRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12#\n\x04item\x18\x02 \x01(\x0b\x32\x15.hipstershop.CartItem\"#\n\x10\x45mptyCartRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\"!\n\x0eGetCartRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\"=\n\x04\x43\x61rt\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12$\n\x05items\x18\x02 \x03(\x0b\x32\x15.hipstershop.CartItem\"\x07\n\x05\x45mpty\"B\n\x1aListRecommendationsRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12\x13\n\x0bproduct_ids\x18\x02 \x03(\t\"2\n\x1bListRecommendationsResponse\x12\x13\n\x0bproduct_ids\x18\x01 \x03(\t\"p\n\x07Product\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x0f\n\x07picture\x18\x04 \x01(\t\x12%\n\tprice_usd\x18\x05 \x01(\x0b\x32\x12.hipstershop.Money\">\n\x14ListProductsResponse\x12&\n\x08products\x18\x01 \x03(\x0b\x32\x14.hipstershop.Product\"\x1f\n\x11GetProductRequest\x12\n\n\x02id\x18\x01 \x01(\t\"&\n\x15SearchProductsRequest\x12\r\n\x05query\x18\x01 \x01(\t\"?\n\x16SearchProductsResponse\x12%\n\x07results\x18\x01 \x03(\x0b\x32\x14.hipstershop.Product\"^\n\x0fGetQuoteRequest\x12%\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x14.hipstershop.Address\x12$\n\x05items\x18\x02 \x03(\x0b\x32\x15.hipstershop.CartItem\"8\n\x10GetQuoteResponse\x12$\n\x08\x63ost_usd\x18\x01 \x01(\x0b\x32\x12.hipstershop.Money\"_\n\x10ShipOrderRequest\x12%\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x14.hipstershop.Address\x12$\n\x05items\x18\x02 \x03(\x0b\x32\x15.hipstershop.CartItem\"(\n\x11ShipOrderResponse\x12\x13\n\x0btracking_id\x18\x01 \x01(\t\"a\n\x07\x41\x64\x64ress\x12\x16\n\x0estreet_address\x18\x01 \x01(\t\x12\x0c\n\x04\x63ity\x18\x02 \x01(\t\x12\r\n\x05state\x18\x03 \x01(\t\x12\x0f\n\x07\x63ountry\x18\x04 \x01(\t\x12\x10\n\x08zip_code\x18\x05 \x01(\x05\"<\n\x05Money\x12\x15\n\rcurrency_code\x18\x01 \x01(\t\x12\r\n\x05units\x18\x02 \x01(\x03\x12\r\n\x05nanos\x18\x03 \x01(\x05\"8\n\x1eGetSupportedCurrenciesResponse\x12\x16\n\x0e\x63urrency_codes\x18\x01 \x03(\t\"N\n\x19\x43urrencyConversionRequest\x12 \n\x04\x66rom\x18\x01 \x01(\x0b\x32\x12.hipstershop.Money\x12\x0f\n\x07to_code\x18\x02 \x01(\t\"\x90\x01\n\x0e\x43reditCardInfo\x12\x1a\n\x12\x63redit_card_number\x18\x01 \x01(\t\x12\x17\n\x0f\x63redit_card_cvv\x18\x02 \x01(\x05\x12#\n\x1b\x63redit_card_expiration_year\x18\x03 \x01(\x05\x12$\n\x1c\x63redit_card_expiration_month\x18\x04 \x01(\x05\"e\n\rChargeRequest\x12\"\n\x06\x61mount\x18\x01 \x01(\x0b\x32\x12.hipstershop.Money\x12\x30\n\x0b\x63redit_card\x18\x02 \x01(\x0b\x32\x1b.hipstershop.CreditCardInfo\"(\n\x0e\x43hargeResponse\x12\x16\n\x0etransaction_id\x18\x01 \x01(\t\"R\n\tOrderItem\x12#\n\x04item\x18\x01 \x01(\x0b\x32\x15.hipstershop.CartItem\x12 \n\x04\x63ost\x18\x02 \x01(\x0b\x32\x12.hipstershop.Money\"\xbf\x01\n\x0bOrderResult\x12\x10\n\x08order_id\x18\x01 \x01(\t\x12\x1c\n\x14shipping_tracking_id\x18\x02 \x01(\t\x12)\n\rshipping_cost\x18\x03 \x01(\x0b\x32\x12.hipstershop.Money\x12.\n\x10shipping_address\x18\x04 \x01(\x0b\x32\x14.hipstershop.Address\x12%\n\x05items\x18\x05 \x03(\x0b\x32\x16.hipstershop.OrderItem\"V\n\x1cSendOrderConfirmationRequest\x12\r\n\x05\x65mail\x18\x01 \x01(\t\x12\'\n\x05order\x18\x02 \x01(\x0b\x32\x18.hipstershop.OrderResult\"\xa3\x01\n\x11PlaceOrderRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12\x15\n\ruser_currency\x18\x02 \x01(\t\x12%\n\x07\x61\x64\x64ress\x18\x03 \x01(\x0b\x32\x14.hipstershop.Address\x12\r\n\x05\x65mail\x18\x05 \x01(\t\x12\x30\n\x0b\x63redit_card\x18\x06 \x01(\x0b\x32\x1b.hipstershop.CreditCardInfo\"=\n\x12PlaceOrderResponse\x12\'\n\x05order\x18\x01 \x01(\x0b\x32\x18.hipstershop.OrderResult\"\"\n\nAdsRequest\x12\x14\n\x0c\x63ontext_keys\x18\x01 \x03(\t\"+\n\x0b\x41\x64sResponse\x12\x1c\n\x03\x61\x64s\x18\x01 \x03(\x0b\x32\x0f.hipstershop.Ad\"(\n\x02\x41\x64\x12\x14\n\x0credirect_url\x18\x01 \x01(\t\x12\x0c\n\x04text\x18\x02 \x01(\t2\xca\x01\n\x0b\x43\x61rtService\x12<\n\x07\x41\x64\x64Item\x12\x1b.hipstershop.AddItemRequest\x1a\x12.hipstershop.Empty\"\x00\x12;\n\x07GetCart\x12\x1b.hipstershop.GetCartRequest\x1a\x11.hipstershop.Cart\"\x00\x12@\n\tEmptyCart\x12\x1d.hipstershop.EmptyCartRequest\x1a\x12.hipstershop.Empty\"\x00\x32\x83\x01\n\x15RecommendationService\x12j\n\x13ListRecommendations\x12\'.hipstershop.ListRecommendationsRequest\x1a(.hipstershop.ListRecommendationsResponse\"\x00\x32\x83\x02\n\x15ProductCatalogService\x12G\n\x0cListProducts\x12\x12.hipstershop.Empty\x1a!.hipstershop.ListProductsResponse\"\x00\x12\x44\n\nGetProduct\x12\x1e.hipstershop.GetProductRequest\x1a\x14.hipstershop.Product\"\x00\x12[\n\x0eSearchProducts\x12\".hipstershop.SearchProductsRequest\x1a#.hipstershop.SearchProductsResponse\"\x00\x32\xaa\x01\n\x0fShippingService\x12I\n\x08GetQuote\x12\x1c.hipstershop.GetQuoteRequest\x1a\x1d.hipstershop.GetQuoteResponse\"\x00\x12L\n\tShipOrder\x12\x1d.hipstershop.ShipOrderRequest\x1a\x1e.hipstershop.ShipOrderResponse\"\x00\x32\xb7\x01\n\x0f\x43urrencyService\x12[\n\x16GetSupportedCurrencies\x12\x12.hipstershop.Empty\x1a+.hipstershop.GetSupportedCurrenciesResponse\"\x00\x12G\n\x07\x43onvert\x12&.hipstershop.CurrencyConversionRequest\x1a\x12.hipstershop.Money\"\x00\x32U\n\x0ePaymentService\x12\x43\n\x06\x43harge\x12\x1a.hipstershop.ChargeRequest\x1a\x1b.hipstershop.ChargeResponse\"\x00\x32h\n\x0c\x45mailService\x12X\n\x15SendOrderConfirmation\x12).hipstershop.SendOrderConfirmationRequest\x1a\x12.hipstershop.Empty\"\x00\x32\x62\n\x0f\x43heckoutService\x12O\n\nPlaceOrder\x12\x1e.hipstershop.PlaceOrderRequest\x1a\x1f.hipstershop.PlaceOrderResponse\"\x00\x32K\n\nAdsService\x12=\n\x06GetAds\x12\x17.hipstershop.AdsRequest\x1a\x18.hipstershop.AdsResponse\"\x00\x62\x06proto3') ) _CARTITEM = _descriptor.Descriptor( name='CartItem', full_name='hipstershop.CartItem', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='product_id', full_name='hipstershop.CartItem.product_id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='quantity', full_name='hipstershop.CartItem.quantity', index=1, number=2, type=5, cpp_type=1, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=27, serialized_end=75, ) _ADDITEMREQUEST = _descriptor.Descriptor( name='AddItemRequest', full_name='hipstershop.AddItemRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='user_id', full_name='hipstershop.AddItemRequest.user_id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='item', full_name='hipstershop.AddItemRequest.item', index=1, number=2, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=77, serialized_end=147, ) _EMPTYCARTREQUEST = _descriptor.Descriptor( name='EmptyCartRequest', full_name='hipstershop.EmptyCartRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='user_id', full_name='hipstershop.EmptyCartRequest.user_id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=149, serialized_end=184, ) _GETCARTREQUEST = _descriptor.Descriptor( name='GetCartRequest', full_name='hipstershop.GetCartRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='user_id', full_name='hipstershop.GetCartRequest.user_id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=186, serialized_end=219, ) _CART = _descriptor.Descriptor( name='Cart', full_name='hipstershop.Cart', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='user_id', full_name='hipstershop.Cart.user_id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='items', full_name='hipstershop.Cart.items', index=1, number=2, type=11, cpp_type=10, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=221, serialized_end=282, ) _EMPTY = _descriptor.Descriptor( name='Empty', full_name='hipstershop.Empty', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=284, serialized_end=291, ) _LISTRECOMMENDATIONSREQUEST = _descriptor.Descriptor( name='ListRecommendationsRequest', full_name='hipstershop.ListRecommendationsRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='user_id', full_name='hipstershop.ListRecommendationsRequest.user_id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='product_ids', full_name='hipstershop.ListRecommendationsRequest.product_ids', index=1, number=2, type=9, cpp_type=9, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=293, serialized_end=359, ) _LISTRECOMMENDATIONSRESPONSE = _descriptor.Descriptor( name='ListRecommendationsResponse', full_name='hipstershop.ListRecommendationsResponse', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='product_ids', full_name='hipstershop.ListRecommendationsResponse.product_ids', index=0, number=1, type=9, cpp_type=9, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=361, serialized_end=411, ) _PRODUCT = _descriptor.Descriptor( name='Product', full_name='hipstershop.Product', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='id', full_name='hipstershop.Product.id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='name', full_name='hipstershop.Product.name', index=1, number=2, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='description', full_name='hipstershop.Product.description', index=2, number=3, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='picture', full_name='hipstershop.Product.picture', index=3, number=4, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='price_usd', full_name='hipstershop.Product.price_usd', index=4, number=5, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=413, serialized_end=525, ) _LISTPRODUCTSRESPONSE = _descriptor.Descriptor( name='ListProductsResponse', full_name='hipstershop.ListProductsResponse', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='products', full_name='hipstershop.ListProductsResponse.products', index=0, number=1, type=11, cpp_type=10, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=527, serialized_end=589, ) _GETPRODUCTREQUEST = _descriptor.Descriptor( name='GetProductRequest', full_name='hipstershop.GetProductRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='id', full_name='hipstershop.GetProductRequest.id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=591, serialized_end=622, ) _SEARCHPRODUCTSREQUEST = _descriptor.Descriptor( name='SearchProductsRequest', full_name='hipstershop.SearchProductsRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='query', full_name='hipstershop.SearchProductsRequest.query', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=624, serialized_end=662, ) _SEARCHPRODUCTSRESPONSE = _descriptor.Descriptor( name='SearchProductsResponse', full_name='hipstershop.SearchProductsResponse', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='results', full_name='hipstershop.SearchProductsResponse.results', index=0, number=1, type=11, cpp_type=10, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=664, serialized_end=727, ) _GETQUOTEREQUEST = _descriptor.Descriptor( name='GetQuoteRequest', full_name='hipstershop.GetQuoteRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='address', full_name='hipstershop.GetQuoteRequest.address', index=0, number=1, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='items', full_name='hipstershop.GetQuoteRequest.items', index=1, number=2, type=11, cpp_type=10, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=729, serialized_end=823, ) _GETQUOTERESPONSE = _descriptor.Descriptor( name='GetQuoteResponse', full_name='hipstershop.GetQuoteResponse', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='cost_usd', full_name='hipstershop.GetQuoteResponse.cost_usd', index=0, number=1, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=825, serialized_end=881, ) _SHIPORDERREQUEST = _descriptor.Descriptor( name='ShipOrderRequest', full_name='hipstershop.ShipOrderRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='address', full_name='hipstershop.ShipOrderRequest.address', index=0, number=1, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='items', full_name='hipstershop.ShipOrderRequest.items', index=1, number=2, type=11, cpp_type=10, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=883, serialized_end=978, ) _SHIPORDERRESPONSE = _descriptor.Descriptor( name='ShipOrderResponse', full_name='hipstershop.ShipOrderResponse', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='tracking_id', full_name='hipstershop.ShipOrderResponse.tracking_id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=980, serialized_end=1020, ) _ADDRESS = _descriptor.Descriptor( name='Address', full_name='hipstershop.Address', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='street_address', full_name='hipstershop.Address.street_address', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='city', full_name='hipstershop.Address.city', index=1, number=2, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='state', full_name='hipstershop.Address.state', index=2, number=3, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='country', full_name='hipstershop.Address.country', index=3, number=4, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='zip_code', full_name='hipstershop.Address.zip_code', index=4, number=5, type=5, cpp_type=1, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=1022, serialized_end=1119, ) _MONEY = _descriptor.Descriptor( name='Money', full_name='hipstershop.Money', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='currency_code', full_name='hipstershop.Money.currency_code', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='units', full_name='hipstershop.Money.units', index=1, number=2, type=3, cpp_type=2, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='nanos', full_name='hipstershop.Money.nanos', index=2, number=3, type=5, cpp_type=1, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=1121, serialized_end=1181, ) _GETSUPPORTEDCURRENCIESRESPONSE = _descriptor.Descriptor( name='GetSupportedCurrenciesResponse', full_name='hipstershop.GetSupportedCurrenciesResponse', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='currency_codes', full_name='hipstershop.GetSupportedCurrenciesResponse.currency_codes', index=0, number=1, type=9, cpp_type=9, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=1183, serialized_end=1239, ) _CURRENCYCONVERSIONREQUEST = _descriptor.Descriptor( name='CurrencyConversionRequest', full_name='hipstershop.CurrencyConversionRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='from', full_name='hipstershop.CurrencyConversionRequest.from', index=0, number=1, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='to_code', full_name='hipstershop.CurrencyConversionRequest.to_code', index=1, number=2, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=1241, serialized_end=1319, ) _CREDITCARDINFO = _descriptor.Descriptor( name='CreditCardInfo', full_name='hipstershop.CreditCardInfo', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='credit_card_number', full_name='hipstershop.CreditCardInfo.credit_card_number', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='credit_card_cvv', full_name='hipstershop.CreditCardInfo.credit_card_cvv', index=1, number=2, type=5, cpp_type=1, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='credit_card_expiration_year', full_name='hipstershop.CreditCardInfo.credit_card_expiration_year', index=2, number=3, type=5, cpp_type=1, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='credit_card_expiration_month', full_name='hipstershop.CreditCardInfo.credit_card_expiration_month', index=3, number=4, type=5, cpp_type=1, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=1322, serialized_end=1466, ) _CHARGEREQUEST = _descriptor.Descriptor( name='ChargeRequest', full_name='hipstershop.ChargeRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='amount', full_name='hipstershop.ChargeRequest.amount', index=0, number=1, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='credit_card', full_name='hipstershop.ChargeRequest.credit_card', index=1, number=2, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=1468, serialized_end=1569, ) _CHARGERESPONSE = _descriptor.Descriptor( name='ChargeResponse', full_name='hipstershop.ChargeResponse', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='transaction_id', full_name='hipstershop.ChargeResponse.transaction_id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=1571, serialized_end=1611, ) _ORDERITEM = _descriptor.Descriptor( name='OrderItem', full_name='hipstershop.OrderItem', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='item', full_name='hipstershop.OrderItem.item', index=0, number=1, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='cost', full_name='hipstershop.OrderItem.cost', index=1, number=2, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=1613, serialized_end=1695, ) _ORDERRESULT = _descriptor.Descriptor( name='OrderResult', full_name='hipstershop.OrderResult', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='order_id', full_name='hipstershop.OrderResult.order_id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='shipping_tracking_id', full_name='hipstershop.OrderResult.shipping_tracking_id', index=1, number=2, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='shipping_cost', full_name='hipstershop.OrderResult.shipping_cost', index=2, number=3, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='shipping_address', full_name='hipstershop.OrderResult.shipping_address', index=3, number=4, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='items', full_name='hipstershop.OrderResult.items', index=4, number=5, type=11, cpp_type=10, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=1698, serialized_end=1889, ) _SENDORDERCONFIRMATIONREQUEST = _descriptor.Descriptor( name='SendOrderConfirmationRequest', full_name='hipstershop.SendOrderConfirmationRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='email', full_name='hipstershop.SendOrderConfirmationRequest.email', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='order', full_name='hipstershop.SendOrderConfirmationRequest.order', index=1, number=2, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=1891, serialized_end=1977, ) _PLACEORDERREQUEST = _descriptor.Descriptor( name='PlaceOrderRequest', full_name='hipstershop.PlaceOrderRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='user_id', full_name='hipstershop.PlaceOrderRequest.user_id', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='user_currency', full_name='hipstershop.PlaceOrderRequest.user_currency', index=1, number=2, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='address', full_name='hipstershop.PlaceOrderRequest.address', index=2, number=3, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='email', full_name='hipstershop.PlaceOrderRequest.email', index=3, number=5, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='credit_card', full_name='hipstershop.PlaceOrderRequest.credit_card', index=4, number=6, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=1980, serialized_end=2143, ) _PLACEORDERRESPONSE = _descriptor.Descriptor( name='PlaceOrderResponse', full_name='hipstershop.PlaceOrderResponse', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='order', full_name='hipstershop.PlaceOrderResponse.order', index=0, number=1, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=2145, serialized_end=2206, ) _ADSREQUEST = _descriptor.Descriptor( name='AdsRequest', full_name='hipstershop.AdsRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='context_keys', full_name='hipstershop.AdsRequest.context_keys', index=0, number=1, type=9, cpp_type=9, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=2208, serialized_end=2242, ) _ADSRESPONSE = _descriptor.Descriptor( name='AdsResponse', full_name='hipstershop.AdsResponse', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='ads', full_name='hipstershop.AdsResponse.ads', index=0, number=1, type=11, cpp_type=10, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=2244, serialized_end=2287, ) _AD = _descriptor.Descriptor( name='Ad', full_name='hipstershop.Ad', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='redirect_url', full_name='hipstershop.Ad.redirect_url', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='text', full_name='hipstershop.Ad.text', index=1, number=2, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=2289, serialized_end=2329, ) _ADDITEMREQUEST.fields_by_name['item'].message_type = _CARTITEM _CART.fields_by_name['items'].message_type = _CARTITEM _PRODUCT.fields_by_name['price_usd'].message_type = _MONEY _LISTPRODUCTSRESPONSE.fields_by_name['products'].message_type = _PRODUCT _SEARCHPRODUCTSRESPONSE.fields_by_name['results'].message_type = _PRODUCT _GETQUOTEREQUEST.fields_by_name['address'].message_type = _ADDRESS _GETQUOTEREQUEST.fields_by_name['items'].message_type = _CARTITEM _GETQUOTERESPONSE.fields_by_name['cost_usd'].message_type = _MONEY _SHIPORDERREQUEST.fields_by_name['address'].message_type = _ADDRESS _SHIPORDERREQUEST.fields_by_name['items'].message_type = _CARTITEM _CURRENCYCONVERSIONREQUEST.fields_by_name['from'].message_type = _MONEY _CHARGEREQUEST.fields_by_name['amount'].message_type = _MONEY _CHARGEREQUEST.fields_by_name['credit_card'].message_type = _CREDITCARDINFO _ORDERITEM.fields_by_name['item'].message_type = _CARTITEM _ORDERITEM.fields_by_name['cost'].message_type = _MONEY _ORDERRESULT.fields_by_name['shipping_cost'].message_type = _MONEY _ORDERRESULT.fields_by_name['shipping_address'].message_type = _ADDRESS _ORDERRESULT.fields_by_name['items'].message_type = _ORDERITEM _SENDORDERCONFIRMATIONREQUEST.fields_by_name['order'].message_type = _ORDERRESULT _PLACEORDERREQUEST.fields_by_name['address'].message_type = _ADDRESS _PLACEORDERREQUEST.fields_by_name['credit_card'].message_type = _CREDITCARDINFO _PLACEORDERRESPONSE.fields_by_name['order'].message_type = _ORDERRESULT _ADSRESPONSE.fields_by_name['ads'].message_type = _AD DESCRIPTOR.message_types_by_name['CartItem'] = _CARTITEM DESCRIPTOR.message_types_by_name['AddItemRequest'] = _ADDITEMREQUEST DESCRIPTOR.message_types_by_name['EmptyCartRequest'] = _EMPTYCARTREQUEST DESCRIPTOR.message_types_by_name['GetCartRequest'] = _GETCARTREQUEST DESCRIPTOR.message_types_by_name['Cart'] = _CART DESCRIPTOR.message_types_by_name['Empty'] = _EMPTY DESCRIPTOR.message_types_by_name['ListRecommendationsRequest'] = _LISTRECOMMENDATIONSREQUEST DESCRIPTOR.message_types_by_name['ListRecommendationsResponse'] = _LISTRECOMMENDATIONSRESPONSE DESCRIPTOR.message_types_by_name['Product'] = _PRODUCT DESCRIPTOR.message_types_by_name['ListProductsResponse'] = _LISTPRODUCTSRESPONSE DESCRIPTOR.message_types_by_name['GetProductRequest'] = _GETPRODUCTREQUEST DESCRIPTOR.message_types_by_name['SearchProductsRequest'] = _SEARCHPRODUCTSREQUEST DESCRIPTOR.message_types_by_name['SearchProductsResponse'] = _SEARCHPRODUCTSRESPONSE DESCRIPTOR.message_types_by_name['GetQuoteRequest'] = _GETQUOTEREQUEST DESCRIPTOR.message_types_by_name['GetQuoteResponse'] = _GETQUOTERESPONSE DESCRIPTOR.message_types_by_name['ShipOrderRequest'] = _SHIPORDERREQUEST DESCRIPTOR.message_types_by_name['ShipOrderResponse'] = _SHIPORDERRESPONSE DESCRIPTOR.message_types_by_name['Address'] = _ADDRESS DESCRIPTOR.message_types_by_name['Money'] = _MONEY DESCRIPTOR.message_types_by_name['GetSupportedCurrenciesResponse'] = _GETSUPPORTEDCURRENCIESRESPONSE DESCRIPTOR.message_types_by_name['CurrencyConversionRequest'] = _CURRENCYCONVERSIONREQUEST DESCRIPTOR.message_types_by_name['CreditCardInfo'] = _CREDITCARDINFO DESCRIPTOR.message_types_by_name['ChargeRequest'] = _CHARGEREQUEST DESCRIPTOR.message_types_by_name['ChargeResponse'] = _CHARGERESPONSE DESCRIPTOR.message_types_by_name['OrderItem'] = _ORDERITEM DESCRIPTOR.message_types_by_name['OrderResult'] = _ORDERRESULT DESCRIPTOR.message_types_by_name['SendOrderConfirmationRequest'] = _SENDORDERCONFIRMATIONREQUEST DESCRIPTOR.message_types_by_name['PlaceOrderRequest'] = _PLACEORDERREQUEST DESCRIPTOR.message_types_by_name['PlaceOrderResponse'] = _PLACEORDERRESPONSE DESCRIPTOR.message_types_by_name['AdsRequest'] = _ADSREQUEST DESCRIPTOR.message_types_by_name['AdsResponse'] = _ADSRESPONSE DESCRIPTOR.message_types_by_name['Ad'] = _AD _sym_db.RegisterFileDescriptor(DESCRIPTOR) CartItem = _reflection.GeneratedProtocolMessageType('CartItem', (_message.Message,), dict( DESCRIPTOR = _CARTITEM, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.CartItem) )) _sym_db.RegisterMessage(CartItem) AddItemRequest = _reflection.GeneratedProtocolMessageType('AddItemRequest', (_message.Message,), dict( DESCRIPTOR = _ADDITEMREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.AddItemRequest) )) _sym_db.RegisterMessage(AddItemRequest) EmptyCartRequest = _reflection.GeneratedProtocolMessageType('EmptyCartRequest', (_message.Message,), dict( DESCRIPTOR = _EMPTYCARTREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.EmptyCartRequest) )) _sym_db.RegisterMessage(EmptyCartRequest) GetCartRequest = _reflection.GeneratedProtocolMessageType('GetCartRequest', (_message.Message,), dict( DESCRIPTOR = _GETCARTREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.GetCartRequest) )) _sym_db.RegisterMessage(GetCartRequest) Cart = _reflection.GeneratedProtocolMessageType('Cart', (_message.Message,), dict( DESCRIPTOR = _CART, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.Cart) )) _sym_db.RegisterMessage(Cart) Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), dict( DESCRIPTOR = _EMPTY, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.Empty) )) _sym_db.RegisterMessage(Empty) ListRecommendationsRequest = _reflection.GeneratedProtocolMessageType('ListRecommendationsRequest', (_message.Message,), dict( DESCRIPTOR = _LISTRECOMMENDATIONSREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.ListRecommendationsRequest) )) _sym_db.RegisterMessage(ListRecommendationsRequest) ListRecommendationsResponse = _reflection.GeneratedProtocolMessageType('ListRecommendationsResponse', (_message.Message,), dict( DESCRIPTOR = _LISTRECOMMENDATIONSRESPONSE, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.ListRecommendationsResponse) )) _sym_db.RegisterMessage(ListRecommendationsResponse) Product = _reflection.GeneratedProtocolMessageType('Product', (_message.Message,), dict( DESCRIPTOR = _PRODUCT, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.Product) )) _sym_db.RegisterMessage(Product) ListProductsResponse = _reflection.GeneratedProtocolMessageType('ListProductsResponse', (_message.Message,), dict( DESCRIPTOR = _LISTPRODUCTSRESPONSE, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.ListProductsResponse) )) _sym_db.RegisterMessage(ListProductsResponse) GetProductRequest = _reflection.GeneratedProtocolMessageType('GetProductRequest', (_message.Message,), dict( DESCRIPTOR = _GETPRODUCTREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.GetProductRequest) )) _sym_db.RegisterMessage(GetProductRequest) SearchProductsRequest = _reflection.GeneratedProtocolMessageType('SearchProductsRequest', (_message.Message,), dict( DESCRIPTOR = _SEARCHPRODUCTSREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.SearchProductsRequest) )) _sym_db.RegisterMessage(SearchProductsRequest) SearchProductsResponse = _reflection.GeneratedProtocolMessageType('SearchProductsResponse', (_message.Message,), dict( DESCRIPTOR = _SEARCHPRODUCTSRESPONSE, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.SearchProductsResponse) )) _sym_db.RegisterMessage(SearchProductsResponse) GetQuoteRequest = _reflection.GeneratedProtocolMessageType('GetQuoteRequest', (_message.Message,), dict( DESCRIPTOR = _GETQUOTEREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.GetQuoteRequest) )) _sym_db.RegisterMessage(GetQuoteRequest) GetQuoteResponse = _reflection.GeneratedProtocolMessageType('GetQuoteResponse', (_message.Message,), dict( DESCRIPTOR = _GETQUOTERESPONSE, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.GetQuoteResponse) )) _sym_db.RegisterMessage(GetQuoteResponse) ShipOrderRequest = _reflection.GeneratedProtocolMessageType('ShipOrderRequest', (_message.Message,), dict( DESCRIPTOR = _SHIPORDERREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.ShipOrderRequest) )) _sym_db.RegisterMessage(ShipOrderRequest) ShipOrderResponse = _reflection.GeneratedProtocolMessageType('ShipOrderResponse', (_message.Message,), dict( DESCRIPTOR = _SHIPORDERRESPONSE, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.ShipOrderResponse) )) _sym_db.RegisterMessage(ShipOrderResponse) Address = _reflection.GeneratedProtocolMessageType('Address', (_message.Message,), dict( DESCRIPTOR = _ADDRESS, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.Address) )) _sym_db.RegisterMessage(Address) Money = _reflection.GeneratedProtocolMessageType('Money', (_message.Message,), dict( DESCRIPTOR = _MONEY, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.Money) )) _sym_db.RegisterMessage(Money) GetSupportedCurrenciesResponse = _reflection.GeneratedProtocolMessageType('GetSupportedCurrenciesResponse', (_message.Message,), dict( DESCRIPTOR = _GETSUPPORTEDCURRENCIESRESPONSE, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.GetSupportedCurrenciesResponse) )) _sym_db.RegisterMessage(GetSupportedCurrenciesResponse) CurrencyConversionRequest = _reflection.GeneratedProtocolMessageType('CurrencyConversionRequest', (_message.Message,), dict( DESCRIPTOR = _CURRENCYCONVERSIONREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.CurrencyConversionRequest) )) _sym_db.RegisterMessage(CurrencyConversionRequest) CreditCardInfo = _reflection.GeneratedProtocolMessageType('CreditCardInfo', (_message.Message,), dict( DESCRIPTOR = _CREDITCARDINFO, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.CreditCardInfo) )) _sym_db.RegisterMessage(CreditCardInfo) ChargeRequest = _reflection.GeneratedProtocolMessageType('ChargeRequest', (_message.Message,), dict( DESCRIPTOR = _CHARGEREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.ChargeRequest) )) _sym_db.RegisterMessage(ChargeRequest) ChargeResponse = _reflection.GeneratedProtocolMessageType('ChargeResponse', (_message.Message,), dict( DESCRIPTOR = _CHARGERESPONSE, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.ChargeResponse) )) _sym_db.RegisterMessage(ChargeResponse) OrderItem = _reflection.GeneratedProtocolMessageType('OrderItem', (_message.Message,), dict( DESCRIPTOR = _ORDERITEM, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.OrderItem) )) _sym_db.RegisterMessage(OrderItem) OrderResult = _reflection.GeneratedProtocolMessageType('OrderResult', (_message.Message,), dict( DESCRIPTOR = _ORDERRESULT, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.OrderResult) )) _sym_db.RegisterMessage(OrderResult) SendOrderConfirmationRequest = _reflection.GeneratedProtocolMessageType('SendOrderConfirmationRequest', (_message.Message,), dict( DESCRIPTOR = _SENDORDERCONFIRMATIONREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.SendOrderConfirmationRequest) )) _sym_db.RegisterMessage(SendOrderConfirmationRequest) PlaceOrderRequest = _reflection.GeneratedProtocolMessageType('PlaceOrderRequest', (_message.Message,), dict( DESCRIPTOR = _PLACEORDERREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.PlaceOrderRequest) )) _sym_db.RegisterMessage(PlaceOrderRequest) PlaceOrderResponse = _reflection.GeneratedProtocolMessageType('PlaceOrderResponse', (_message.Message,), dict( DESCRIPTOR = _PLACEORDERRESPONSE, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.PlaceOrderResponse) )) _sym_db.RegisterMessage(PlaceOrderResponse) AdsRequest = _reflection.GeneratedProtocolMessageType('AdsRequest', (_message.Message,), dict( DESCRIPTOR = _ADSREQUEST, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.AdsRequest) )) _sym_db.RegisterMessage(AdsRequest) AdsResponse = _reflection.GeneratedProtocolMessageType('AdsResponse', (_message.Message,), dict( DESCRIPTOR = _ADSRESPONSE, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.AdsResponse) )) _sym_db.RegisterMessage(AdsResponse) Ad = _reflection.GeneratedProtocolMessageType('Ad', (_message.Message,), dict( DESCRIPTOR = _AD, __module__ = 'demo_pb2' # @@protoc_insertion_point(class_scope:hipstershop.Ad) )) _sym_db.RegisterMessage(Ad) _CARTSERVICE = _descriptor.ServiceDescriptor( name='CartService', full_name='hipstershop.CartService', file=DESCRIPTOR, index=0, options=None, serialized_start=2332, serialized_end=2534, methods=[ _descriptor.MethodDescriptor( name='AddItem', full_name='hipstershop.CartService.AddItem', index=0, containing_service=None, input_type=_ADDITEMREQUEST, output_type=_EMPTY, options=None, ), _descriptor.MethodDescriptor( name='GetCart', full_name='hipstershop.CartService.GetCart', index=1, containing_service=None, input_type=_GETCARTREQUEST, output_type=_CART, options=None, ), _descriptor.MethodDescriptor( name='EmptyCart', full_name='hipstershop.CartService.EmptyCart', index=2, containing_service=None, input_type=_EMPTYCARTREQUEST, output_type=_EMPTY, options=None, ), ]) _sym_db.RegisterServiceDescriptor(_CARTSERVICE) DESCRIPTOR.services_by_name['CartService'] = _CARTSERVICE _RECOMMENDATIONSERVICE = _descriptor.ServiceDescriptor( name='RecommendationService', full_name='hipstershop.RecommendationService', file=DESCRIPTOR, index=1, options=None, serialized_start=2537, serialized_end=2668, methods=[ _descriptor.MethodDescriptor( name='ListRecommendations', full_name='hipstershop.RecommendationService.ListRecommendations', index=0, containing_service=None, input_type=_LISTRECOMMENDATIONSREQUEST, output_type=_LISTRECOMMENDATIONSRESPONSE, options=None, ), ]) _sym_db.RegisterServiceDescriptor(_RECOMMENDATIONSERVICE) DESCRIPTOR.services_by_name['RecommendationService'] = _RECOMMENDATIONSERVICE _PRODUCTCATALOGSERVICE = _descriptor.ServiceDescriptor( name='ProductCatalogService', full_name='hipstershop.ProductCatalogService', file=DESCRIPTOR, index=2, options=None, serialized_start=2671, serialized_end=2930, methods=[ _descriptor.MethodDescriptor( name='ListProducts', full_name='hipstershop.ProductCatalogService.ListProducts', index=0, containing_service=None, input_type=_EMPTY, output_type=_LISTPRODUCTSRESPONSE, options=None, ), _descriptor.MethodDescriptor( name='GetProduct', full_name='hipstershop.ProductCatalogService.GetProduct', index=1, containing_service=None, input_type=_GETPRODUCTREQUEST, output_type=_PRODUCT, options=None, ), _descriptor.MethodDescriptor( name='SearchProducts', full_name='hipstershop.ProductCatalogService.SearchProducts', index=2, containing_service=None, input_type=_SEARCHPRODUCTSREQUEST, output_type=_SEARCHPRODUCTSRESPONSE, options=None, ), ]) _sym_db.RegisterServiceDescriptor(_PRODUCTCATALOGSERVICE) DESCRIPTOR.services_by_name['ProductCatalogService'] = _PRODUCTCATALOGSERVICE _SHIPPINGSERVICE = _descriptor.ServiceDescriptor( name='ShippingService', full_name='hipstershop.ShippingService', file=DESCRIPTOR, index=3, options=None, serialized_start=2933, serialized_end=3103, methods=[ _descriptor.MethodDescriptor( name='GetQuote', full_name='hipstershop.ShippingService.GetQuote', index=0, containing_service=None, input_type=_GETQUOTEREQUEST, output_type=_GETQUOTERESPONSE, options=None, ), _descriptor.MethodDescriptor( name='ShipOrder', full_name='hipstershop.ShippingService.ShipOrder', index=1, containing_service=None, input_type=_SHIPORDERREQUEST, output_type=_SHIPORDERRESPONSE, options=None, ), ]) _sym_db.RegisterServiceDescriptor(_SHIPPINGSERVICE) DESCRIPTOR.services_by_name['ShippingService'] = _SHIPPINGSERVICE _CURRENCYSERVICE = _descriptor.ServiceDescriptor( name='CurrencyService', full_name='hipstershop.CurrencyService', file=DESCRIPTOR, index=4, options=None, serialized_start=3106, serialized_end=3289, methods=[ _descriptor.MethodDescriptor( name='GetSupportedCurrencies', full_name='hipstershop.CurrencyService.GetSupportedCurrencies', index=0, containing_service=None, input_type=_EMPTY, output_type=_GETSUPPORTEDCURRENCIESRESPONSE, options=None, ), _descriptor.MethodDescriptor( name='Convert', full_name='hipstershop.CurrencyService.Convert', index=1, containing_service=None, input_type=_CURRENCYCONVERSIONREQUEST, output_type=_MONEY, options=None, ), ]) _sym_db.RegisterServiceDescriptor(_CURRENCYSERVICE) DESCRIPTOR.services_by_name['CurrencyService'] = _CURRENCYSERVICE _PAYMENTSERVICE = _descriptor.ServiceDescriptor( name='PaymentService', full_name='hipstershop.PaymentService', file=DESCRIPTOR, index=5, options=None, serialized_start=3291, serialized_end=3376, methods=[ _descriptor.MethodDescriptor( name='Charge', full_name='hipstershop.PaymentService.Charge', index=0, containing_service=None, input_type=_CHARGEREQUEST, output_type=_CHARGERESPONSE, options=None, ), ]) _sym_db.RegisterServiceDescriptor(_PAYMENTSERVICE) DESCRIPTOR.services_by_name['PaymentService'] = _PAYMENTSERVICE _EMAILSERVICE = _descriptor.ServiceDescriptor( name='EmailService', full_name='hipstershop.EmailService', file=DESCRIPTOR, index=6, options=None, serialized_start=3378, serialized_end=3482, methods=[ _descriptor.MethodDescriptor( name='SendOrderConfirmation', full_name='hipstershop.EmailService.SendOrderConfirmation', index=0, containing_service=None, input_type=_SENDORDERCONFIRMATIONREQUEST, output_type=_EMPTY, options=None, ), ]) _sym_db.RegisterServiceDescriptor(_EMAILSERVICE) DESCRIPTOR.services_by_name['EmailService'] = _EMAILSERVICE _CHECKOUTSERVICE = _descriptor.ServiceDescriptor( name='CheckoutService', full_name='hipstershop.CheckoutService', file=DESCRIPTOR, index=7, options=None, serialized_start=3484, serialized_end=3582, methods=[ _descriptor.MethodDescriptor( name='PlaceOrder', full_name='hipstershop.CheckoutService.PlaceOrder', index=0, containing_service=None, input_type=_PLACEORDERREQUEST, output_type=_PLACEORDERRESPONSE, options=None, ), ]) _sym_db.RegisterServiceDescriptor(_CHECKOUTSERVICE) DESCRIPTOR.services_by_name['CheckoutService'] = _CHECKOUTSERVICE _ADSSERVICE = _descriptor.ServiceDescriptor( name='AdsService', full_name='hipstershop.AdsService', file=DESCRIPTOR, index=8, options=None, serialized_start=3584, serialized_end=3659, methods=[ _descriptor.MethodDescriptor( name='GetAds', full_name='hipstershop.AdsService.GetAds', index=0, containing_service=None, input_type=_ADSREQUEST, output_type=_ADSRESPONSE, options=None, ), ]) _sym_db.RegisterServiceDescriptor(_ADSSERVICE) DESCRIPTOR.services_by_name['AdsService'] = _ADSSERVICE # @@protoc_insertion_point(module_scope) ================================================ FILE: microservices-demo/src/recommendationservice/demo_pb2_grpc.py ================================================ # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! import grpc import demo_pb2 as demo__pb2 class CartServiceStub(object): """-----------------Cart service----------------- """ def __init__(self, channel): """Constructor. Args: channel: A grpc.Channel. """ self.AddItem = channel.unary_unary( '/hipstershop.CartService/AddItem', request_serializer=demo__pb2.AddItemRequest.SerializeToString, response_deserializer=demo__pb2.Empty.FromString, ) self.GetCart = channel.unary_unary( '/hipstershop.CartService/GetCart', request_serializer=demo__pb2.GetCartRequest.SerializeToString, response_deserializer=demo__pb2.Cart.FromString, ) self.EmptyCart = channel.unary_unary( '/hipstershop.CartService/EmptyCart', request_serializer=demo__pb2.EmptyCartRequest.SerializeToString, response_deserializer=demo__pb2.Empty.FromString, ) class CartServiceServicer(object): """-----------------Cart service----------------- """ def AddItem(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def GetCart(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def EmptyCart(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def add_CartServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'AddItem': grpc.unary_unary_rpc_method_handler( servicer.AddItem, request_deserializer=demo__pb2.AddItemRequest.FromString, response_serializer=demo__pb2.Empty.SerializeToString, ), 'GetCart': grpc.unary_unary_rpc_method_handler( servicer.GetCart, request_deserializer=demo__pb2.GetCartRequest.FromString, response_serializer=demo__pb2.Cart.SerializeToString, ), 'EmptyCart': grpc.unary_unary_rpc_method_handler( servicer.EmptyCart, request_deserializer=demo__pb2.EmptyCartRequest.FromString, response_serializer=demo__pb2.Empty.SerializeToString, ), } generic_handler = grpc.method_handlers_generic_handler( 'hipstershop.CartService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) class RecommendationServiceStub(object): """---------------Recommendation service---------- """ def __init__(self, channel): """Constructor. Args: channel: A grpc.Channel. """ self.ListRecommendations = channel.unary_unary( '/hipstershop.RecommendationService/ListRecommendations', request_serializer=demo__pb2.ListRecommendationsRequest.SerializeToString, response_deserializer=demo__pb2.ListRecommendationsResponse.FromString, ) class RecommendationServiceServicer(object): """---------------Recommendation service---------- """ def ListRecommendations(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def add_RecommendationServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'ListRecommendations': grpc.unary_unary_rpc_method_handler( servicer.ListRecommendations, request_deserializer=demo__pb2.ListRecommendationsRequest.FromString, response_serializer=demo__pb2.ListRecommendationsResponse.SerializeToString, ), } generic_handler = grpc.method_handlers_generic_handler( 'hipstershop.RecommendationService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) class ProductCatalogServiceStub(object): """---------------Product Catalog---------------- """ def __init__(self, channel): """Constructor. Args: channel: A grpc.Channel. """ self.ListProducts = channel.unary_unary( '/hipstershop.ProductCatalogService/ListProducts', request_serializer=demo__pb2.Empty.SerializeToString, response_deserializer=demo__pb2.ListProductsResponse.FromString, ) self.GetProduct = channel.unary_unary( '/hipstershop.ProductCatalogService/GetProduct', request_serializer=demo__pb2.GetProductRequest.SerializeToString, response_deserializer=demo__pb2.Product.FromString, ) self.SearchProducts = channel.unary_unary( '/hipstershop.ProductCatalogService/SearchProducts', request_serializer=demo__pb2.SearchProductsRequest.SerializeToString, response_deserializer=demo__pb2.SearchProductsResponse.FromString, ) class ProductCatalogServiceServicer(object): """---------------Product Catalog---------------- """ def ListProducts(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def GetProduct(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def SearchProducts(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def add_ProductCatalogServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'ListProducts': grpc.unary_unary_rpc_method_handler( servicer.ListProducts, request_deserializer=demo__pb2.Empty.FromString, response_serializer=demo__pb2.ListProductsResponse.SerializeToString, ), 'GetProduct': grpc.unary_unary_rpc_method_handler( servicer.GetProduct, request_deserializer=demo__pb2.GetProductRequest.FromString, response_serializer=demo__pb2.Product.SerializeToString, ), 'SearchProducts': grpc.unary_unary_rpc_method_handler( servicer.SearchProducts, request_deserializer=demo__pb2.SearchProductsRequest.FromString, response_serializer=demo__pb2.SearchProductsResponse.SerializeToString, ), } generic_handler = grpc.method_handlers_generic_handler( 'hipstershop.ProductCatalogService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) class ShippingServiceStub(object): """---------------Shipping Service---------- """ def __init__(self, channel): """Constructor. Args: channel: A grpc.Channel. """ self.GetQuote = channel.unary_unary( '/hipstershop.ShippingService/GetQuote', request_serializer=demo__pb2.GetQuoteRequest.SerializeToString, response_deserializer=demo__pb2.GetQuoteResponse.FromString, ) self.ShipOrder = channel.unary_unary( '/hipstershop.ShippingService/ShipOrder', request_serializer=demo__pb2.ShipOrderRequest.SerializeToString, response_deserializer=demo__pb2.ShipOrderResponse.FromString, ) class ShippingServiceServicer(object): """---------------Shipping Service---------- """ def GetQuote(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def ShipOrder(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def add_ShippingServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'GetQuote': grpc.unary_unary_rpc_method_handler( servicer.GetQuote, request_deserializer=demo__pb2.GetQuoteRequest.FromString, response_serializer=demo__pb2.GetQuoteResponse.SerializeToString, ), 'ShipOrder': grpc.unary_unary_rpc_method_handler( servicer.ShipOrder, request_deserializer=demo__pb2.ShipOrderRequest.FromString, response_serializer=demo__pb2.ShipOrderResponse.SerializeToString, ), } generic_handler = grpc.method_handlers_generic_handler( 'hipstershop.ShippingService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) class CurrencyServiceStub(object): """-----------------Currency service----------------- """ def __init__(self, channel): """Constructor. Args: channel: A grpc.Channel. """ self.GetSupportedCurrencies = channel.unary_unary( '/hipstershop.CurrencyService/GetSupportedCurrencies', request_serializer=demo__pb2.Empty.SerializeToString, response_deserializer=demo__pb2.GetSupportedCurrenciesResponse.FromString, ) self.Convert = channel.unary_unary( '/hipstershop.CurrencyService/Convert', request_serializer=demo__pb2.CurrencyConversionRequest.SerializeToString, response_deserializer=demo__pb2.Money.FromString, ) class CurrencyServiceServicer(object): """-----------------Currency service----------------- """ def GetSupportedCurrencies(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def Convert(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def add_CurrencyServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'GetSupportedCurrencies': grpc.unary_unary_rpc_method_handler( servicer.GetSupportedCurrencies, request_deserializer=demo__pb2.Empty.FromString, response_serializer=demo__pb2.GetSupportedCurrenciesResponse.SerializeToString, ), 'Convert': grpc.unary_unary_rpc_method_handler( servicer.Convert, request_deserializer=demo__pb2.CurrencyConversionRequest.FromString, response_serializer=demo__pb2.Money.SerializeToString, ), } generic_handler = grpc.method_handlers_generic_handler( 'hipstershop.CurrencyService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) class PaymentServiceStub(object): """-------------Payment service----------------- """ def __init__(self, channel): """Constructor. Args: channel: A grpc.Channel. """ self.Charge = channel.unary_unary( '/hipstershop.PaymentService/Charge', request_serializer=demo__pb2.ChargeRequest.SerializeToString, response_deserializer=demo__pb2.ChargeResponse.FromString, ) class PaymentServiceServicer(object): """-------------Payment service----------------- """ def Charge(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def add_PaymentServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'Charge': grpc.unary_unary_rpc_method_handler( servicer.Charge, request_deserializer=demo__pb2.ChargeRequest.FromString, response_serializer=demo__pb2.ChargeResponse.SerializeToString, ), } generic_handler = grpc.method_handlers_generic_handler( 'hipstershop.PaymentService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) class EmailServiceStub(object): """-------------Email service----------------- """ def __init__(self, channel): """Constructor. Args: channel: A grpc.Channel. """ self.SendOrderConfirmation = channel.unary_unary( '/hipstershop.EmailService/SendOrderConfirmation', request_serializer=demo__pb2.SendOrderConfirmationRequest.SerializeToString, response_deserializer=demo__pb2.Empty.FromString, ) class EmailServiceServicer(object): """-------------Email service----------------- """ def SendOrderConfirmation(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def add_EmailServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'SendOrderConfirmation': grpc.unary_unary_rpc_method_handler( servicer.SendOrderConfirmation, request_deserializer=demo__pb2.SendOrderConfirmationRequest.FromString, response_serializer=demo__pb2.Empty.SerializeToString, ), } generic_handler = grpc.method_handlers_generic_handler( 'hipstershop.EmailService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) class CheckoutServiceStub(object): """-------------Checkout service----------------- """ def __init__(self, channel): """Constructor. Args: channel: A grpc.Channel. """ self.PlaceOrder = channel.unary_unary( '/hipstershop.CheckoutService/PlaceOrder', request_serializer=demo__pb2.PlaceOrderRequest.SerializeToString, response_deserializer=demo__pb2.PlaceOrderResponse.FromString, ) class CheckoutServiceServicer(object): """-------------Checkout service----------------- """ def PlaceOrder(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def add_CheckoutServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'PlaceOrder': grpc.unary_unary_rpc_method_handler( servicer.PlaceOrder, request_deserializer=demo__pb2.PlaceOrderRequest.FromString, response_serializer=demo__pb2.PlaceOrderResponse.SerializeToString, ), } generic_handler = grpc.method_handlers_generic_handler( 'hipstershop.CheckoutService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) class AdsServiceStub(object): """------------Ads service------------------ """ def __init__(self, channel): """Constructor. Args: channel: A grpc.Channel. """ self.GetAds = channel.unary_unary( '/hipstershop.AdsService/GetAds', request_serializer=demo__pb2.AdsRequest.SerializeToString, response_deserializer=demo__pb2.AdsResponse.FromString, ) class AdsServiceServicer(object): """------------Ads service------------------ """ def GetAds(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def add_AdsServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'GetAds': grpc.unary_unary_rpc_method_handler( servicer.GetAds, request_deserializer=demo__pb2.AdsRequest.FromString, response_serializer=demo__pb2.AdsResponse.SerializeToString, ), } generic_handler = grpc.method_handlers_generic_handler( 'hipstershop.AdsService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) ================================================ FILE: microservices-demo/src/recommendationservice/genproto.sh ================================================ #!/bin/bash -eu # # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # [START gke_recommendationservice_genproto] # script to compile python protos # # requires gRPC tools: # pip install -r requirements.txt python -m grpc_tools.protoc -I../../pb --python_out=. --grpc_python_out=. ../../pb/demo.proto # [END gke_recommendationservice_genproto] ================================================ FILE: microservices-demo/src/recommendationservice/logger.py ================================================ #!/usr/bin/python # # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import logging import sys from pythonjsonlogger import jsonlogger # TODO(yoshifumi) this class is duplicated since other Python services are # not sharing the modules for logging. class CustomJsonFormatter(jsonlogger.JsonFormatter): def add_fields(self, log_record, record, message_dict): super(CustomJsonFormatter, self).add_fields(log_record, record, message_dict) if not log_record.get('timestamp'): log_record['timestamp'] = record.created if log_record.get('severity'): log_record['severity'] = log_record['severity'].upper() else: log_record['severity'] = record.levelname def getJSONLogger(name): logger = logging.getLogger(name) handler = logging.StreamHandler(sys.stdout) formatter = CustomJsonFormatter('(timestamp) (severity) (name) (message)') handler.setFormatter(formatter) logger.addHandler(handler) logger.setLevel(logging.INFO) logger.propagate = False return logger ================================================ FILE: microservices-demo/src/recommendationservice/pytest.ini ================================================ [pytest] testpaths = tests console_output_style = classic ================================================ FILE: microservices-demo/src/recommendationservice/recommendation_server.py ================================================ #!/usr/bin/python # # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os import random import time import traceback from concurrent import futures import googleclouddebugger import googlecloudprofiler from google.auth.exceptions import DefaultCredentialsError import grpc from opencensus.ext.stackdriver import trace_exporter as stackdriver_exporter from opencensus.ext.grpc import server_interceptor from opencensus.trace import samplers from opencensus.common.transports.async_ import AsyncTransport import demo_pb2 import demo_pb2_grpc from grpc_health.v1 import health_pb2 from grpc_health.v1 import health_pb2_grpc from logger import getJSONLogger logger = getJSONLogger('recommendationservice-server') def initStackdriverProfiling(): project_id = None try: project_id = os.environ["GCP_PROJECT_ID"] except KeyError: # Environment variable not set pass for retry in range(1,4): try: if project_id: googlecloudprofiler.start(service='recommendation_server', service_version='1.0.0', verbose=0, project_id=project_id) else: googlecloudprofiler.start(service='recommendation_server', service_version='1.0.0', verbose=0) logger.info("Successfully started Stackdriver Profiler.") return except (BaseException) as exc: logger.info("Unable to start Stackdriver Profiler Python agent. " + str(exc)) if (retry < 4): logger.info("Sleeping %d seconds to retry Stackdriver Profiler agent initialization"%(retry*10)) time.sleep (1) else: logger.warning("Could not initialize Stackdriver Profiler after retrying, giving up") return class RecommendationService(demo_pb2_grpc.RecommendationServiceServicer): def ListRecommendations(self, request, context): max_responses = 5 # fetch list of products from product catalog stub cat_response = product_catalog_stub.ListProducts(demo_pb2.Empty()) product_ids = [x.id for x in cat_response.products] filtered_products = list(set(product_ids)-set(request.product_ids)) num_products = len(filtered_products) num_return = min(max_responses, num_products) # sample list of indicies to return indices = random.sample(range(num_products), num_return) # fetch product ids from indices prod_list = [filtered_products[i] for i in indices] logger.info("[Recv ListRecommendations] product_ids={}".format(prod_list)) # build and return response response = demo_pb2.ListRecommendationsResponse() response.product_ids.extend(prod_list) return response def Check(self, request, context): return health_pb2.HealthCheckResponse( status=health_pb2.HealthCheckResponse.SERVING) def Watch(self, request, context): return health_pb2.HealthCheckResponse( status=health_pb2.HealthCheckResponse.UNIMPLEMENTED) if __name__ == "__main__": logger.info("initializing recommendationservice") try: if "DISABLE_PROFILER" in os.environ: raise KeyError() else: logger.info("Profiler enabled.") initStackdriverProfiling() except KeyError: logger.info("Profiler disabled.") try: if "DISABLE_TRACING" in os.environ: raise KeyError() else: logger.info("Tracing enabled.") sampler = samplers.AlwaysOnSampler() exporter = stackdriver_exporter.StackdriverExporter( project_id=os.environ.get('GCP_PROJECT_ID'), transport=AsyncTransport) tracer_interceptor = server_interceptor.OpenCensusServerInterceptor(sampler, exporter) except (KeyError, DefaultCredentialsError): logger.info("Tracing disabled.") tracer_interceptor = server_interceptor.OpenCensusServerInterceptor() except Exception as e: logger.warn(f"Exception on Cloud Trace setup: {traceback.format_exc()}, tracing disabled.") tracer_interceptor = server_interceptor.OpenCensusServerInterceptor() try: if "DISABLE_DEBUGGER" in os.environ: raise KeyError() else: logger.info("Debugger enabled.") try: googleclouddebugger.enable( module='recommendationserver', version='1.0.0' ) except (Exception, DefaultCredentialsError): logger.error("Could not enable debugger") logger.error(traceback.print_exc()) pass except (Exception, DefaultCredentialsError): logger.info("Debugger disabled.") port = os.environ.get('PORT', "8080") catalog_addr = os.environ.get('PRODUCT_CATALOG_SERVICE_ADDR', '') if catalog_addr == "": raise Exception('PRODUCT_CATALOG_SERVICE_ADDR environment variable not set') logger.info("product catalog address: " + catalog_addr) channel = grpc.insecure_channel(catalog_addr) product_catalog_stub = demo_pb2_grpc.ProductCatalogServiceStub(channel) # create gRPC server server = grpc.server(futures.ThreadPoolExecutor(max_workers=10), interceptors=(tracer_interceptor,)) # add class to gRPC server service = RecommendationService() demo_pb2_grpc.add_RecommendationServiceServicer_to_server(service, server) health_pb2_grpc.add_HealthServicer_to_server(service, server) # start server logger.info("listening on port: " + port) server.add_insecure_port('[::]:'+port) server.start() # keep alive try: while True: time.sleep(10000) except KeyboardInterrupt: server.stop(0) ================================================ FILE: microservices-demo/src/recommendationservice/requirements.in ================================================ google-api-core==2.8.2 google-python-cloud-debugger==3.1 google-cloud-profiler==4.0.0 grpcio-health-checking==1.47.0 grpcio==1.47.0 opencensus==0.9.0 opencensus-ext-stackdriver==0.8.0 opencensus-ext-grpc==0.7.2 python-json-logger==2.0.4 requests==2.28.1 rsa==4.8 pyyaml==6.0 protobuf==3.20.1 # transitive dependency, move when google-api is bumped safely pytest==7.1.3 ================================================ FILE: microservices-demo/src/recommendationservice/requirements.txt ================================================ # # This file is autogenerated by pip-compile with python 3.7 # To update, run: # # pip-compile --output-file=requirements.txt requirements.in # attrs==22.1.0 # via pytest cachecontrol==0.12.11 # via firebase-admin cachetools==5.2.0 # via google-auth certifi==2022.6.15 # via requests charset-normalizer==2.1.1 # via requests firebase-admin==5.2.0 # via google-python-cloud-debugger google-api-core[grpc]==2.8.2 # via # -r requirements.in # firebase-admin # google-api-python-client # google-cloud-core # google-cloud-firestore # google-cloud-monitoring # google-cloud-storage # google-cloud-trace # google-python-cloud-debugger # opencensus google-api-python-client==2.58.0 # via # firebase-admin # google-cloud-profiler # google-python-cloud-debugger google-auth==2.11.0 # via # google-api-core # google-api-python-client # google-auth-httplib2 # google-cloud-core # google-cloud-profiler # google-cloud-storage # google-python-cloud-debugger google-auth-httplib2==0.1.0 # via # google-api-python-client # google-cloud-profiler # google-python-cloud-debugger google-cloud-core==2.3.2 # via # google-cloud-firestore # google-cloud-storage # google-cloud-trace google-cloud-firestore==2.6.1 # via firebase-admin google-cloud-monitoring==2.11.1 # via opencensus-ext-stackdriver google-cloud-profiler==4.0.0 # via -r requirements.in google-cloud-storage==2.5.0 # via firebase-admin google-cloud-trace==0.24.2 # via opencensus-ext-stackdriver google-crc32c==1.3.0 # via google-resumable-media google-python-cloud-debugger==3.1 # via -r requirements.in google-resumable-media==2.3.3 # via google-cloud-storage googleapis-common-protos==1.56.4 # via # google-api-core # grpcio-status grpcio==1.47.0 # via # -r requirements.in # google-api-core # grpcio-health-checking # grpcio-status # opencensus-ext-grpc grpcio-health-checking==1.47.0 # via -r requirements.in grpcio-status==1.47.0 # via google-api-core httplib2==0.20.4 # via # google-api-python-client # google-auth-httplib2 idna==2.10 # via requests iniconfig==1.1.1 # via pytest msgpack==1.0.4 # via cachecontrol opencensus==0.9.0 # via # -r requirements.in # opencensus-ext-grpc # opencensus-ext-stackdriver opencensus-context==0.1.3 # via opencensus opencensus-ext-grpc==0.7.2 # via -r requirements.in opencensus-ext-stackdriver==0.8.0 # via -r requirements.in packaging==21.3 # via pytest pluggy==1.0.0 # via pytest proto-plus==1.22.1 # via # google-cloud-firestore # google-cloud-monitoring protobuf==3.20.1 # via # -r requirements.in # google-api-core # google-cloud-firestore # google-cloud-monitoring # google-cloud-profiler # google-cloud-trace # googleapis-common-protos # grpcio-health-checking # grpcio-status # proto-plus py==1.11.0 # via pytest pyasn1==0.4.8 # via # pyasn1-modules # rsa pyasn1-modules==0.2.8 # via google-auth pyparsing==2.4.7 # via httplib2 pytest==7.1.3 # via -r requirements.in python-json-logger==2.0.4 # via -r requirements.in pyyaml==6.0 # via # -r requirements.in # google-python-cloud-debugger requests==2.28.1 # via # -r requirements.in # cachecontrol # google-api-core # google-cloud-profiler # google-cloud-storage rsa==4.8 # via # -r requirements.in # google-auth six==1.16.0 # via # google-auth # google-auth-httplib2 # grpcio tomli==2.0.1 # via pytest uritemplate==3.0.1 # via google-api-python-client urllib3==1.26.12 # via requests ================================================ FILE: microservices-demo/src/recommendationservice/tests/test_sample.py ================================================ def func(x): return x + 1 def test_answer(): assert func(3) == 4 ================================================ FILE: microservices-demo/src/shippingservice/.dockerignore ================================================ vendor/ ================================================ FILE: microservices-demo/src/shippingservice/Dockerfile ================================================ # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. FROM golang:1.18.4-alpine as builder RUN apk add --no-cache ca-certificates git RUN apk add build-base WORKDIR /src # restore dependencies COPY go.mod go.sum ./ RUN go mod download COPY . . # Skaffold passes in debug-oriented compiler flags ARG SKAFFOLD_GO_GCFLAGS RUN go build -gcflags="${SKAFFOLD_GO_GCFLAGS}" -o /go/bin/shippingservice . FROM alpine as release RUN apk add --no-cache ca-certificates RUN GRPC_HEALTH_PROBE_VERSION=v0.4.11 && \ wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \ chmod +x /bin/grpc_health_probe WORKDIR /src COPY --from=builder /go/bin/shippingservice /src/shippingservice ENV APP_PORT=50051 # Definition of this variable is used by 'skaffold debug' to identify a golang binary. # Default behavior - a failure prints a stack trace for the current goroutine. # See https://golang.org/pkg/runtime/ ENV GOTRACEBACK=single EXPOSE 50051 ENTRYPOINT ["/src/shippingservice"] ================================================ FILE: microservices-demo/src/shippingservice/README.md ================================================ # Shipping Service The Shipping service provides price quote, tracking IDs, and the impression of order fulfillment & shipping processes. ## Local Run the following command to restore dependencies to `vendor/` directory: dep ensure --vendor-only ## Build From `src/shippingservice`, run: ``` docker build ./ ``` ## Test ``` go test . ``` ================================================ FILE: microservices-demo/src/shippingservice/genproto/demo.pb.go ================================================ // Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go. DO NOT EDIT. // source: demo.proto package hipstershop import ( fmt "fmt" proto "github.com/golang/protobuf/proto" math "math" ) import ( context "golang.org/x/net/context" grpc "google.golang.org/grpc" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package type CartItem struct { ProductId string `protobuf:"bytes,1,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` Quantity int32 `protobuf:"varint,2,opt,name=quantity,proto3" json:"quantity,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *CartItem) Reset() { *m = CartItem{} } func (m *CartItem) String() string { return proto.CompactTextString(m) } func (*CartItem) ProtoMessage() {} func (*CartItem) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{0} } func (m *CartItem) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CartItem.Unmarshal(m, b) } func (m *CartItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CartItem.Marshal(b, m, deterministic) } func (m *CartItem) XXX_Merge(src proto.Message) { xxx_messageInfo_CartItem.Merge(m, src) } func (m *CartItem) XXX_Size() int { return xxx_messageInfo_CartItem.Size(m) } func (m *CartItem) XXX_DiscardUnknown() { xxx_messageInfo_CartItem.DiscardUnknown(m) } var xxx_messageInfo_CartItem proto.InternalMessageInfo func (m *CartItem) GetProductId() string { if m != nil { return m.ProductId } return "" } func (m *CartItem) GetQuantity() int32 { if m != nil { return m.Quantity } return 0 } type AddItemRequest struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` Item *CartItem `protobuf:"bytes,2,opt,name=item,proto3" json:"item,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *AddItemRequest) Reset() { *m = AddItemRequest{} } func (m *AddItemRequest) String() string { return proto.CompactTextString(m) } func (*AddItemRequest) ProtoMessage() {} func (*AddItemRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{1} } func (m *AddItemRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AddItemRequest.Unmarshal(m, b) } func (m *AddItemRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_AddItemRequest.Marshal(b, m, deterministic) } func (m *AddItemRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_AddItemRequest.Merge(m, src) } func (m *AddItemRequest) XXX_Size() int { return xxx_messageInfo_AddItemRequest.Size(m) } func (m *AddItemRequest) XXX_DiscardUnknown() { xxx_messageInfo_AddItemRequest.DiscardUnknown(m) } var xxx_messageInfo_AddItemRequest proto.InternalMessageInfo func (m *AddItemRequest) GetUserId() string { if m != nil { return m.UserId } return "" } func (m *AddItemRequest) GetItem() *CartItem { if m != nil { return m.Item } return nil } type EmptyCartRequest struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *EmptyCartRequest) Reset() { *m = EmptyCartRequest{} } func (m *EmptyCartRequest) String() string { return proto.CompactTextString(m) } func (*EmptyCartRequest) ProtoMessage() {} func (*EmptyCartRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{2} } func (m *EmptyCartRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_EmptyCartRequest.Unmarshal(m, b) } func (m *EmptyCartRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_EmptyCartRequest.Marshal(b, m, deterministic) } func (m *EmptyCartRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_EmptyCartRequest.Merge(m, src) } func (m *EmptyCartRequest) XXX_Size() int { return xxx_messageInfo_EmptyCartRequest.Size(m) } func (m *EmptyCartRequest) XXX_DiscardUnknown() { xxx_messageInfo_EmptyCartRequest.DiscardUnknown(m) } var xxx_messageInfo_EmptyCartRequest proto.InternalMessageInfo func (m *EmptyCartRequest) GetUserId() string { if m != nil { return m.UserId } return "" } type GetCartRequest struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *GetCartRequest) Reset() { *m = GetCartRequest{} } func (m *GetCartRequest) String() string { return proto.CompactTextString(m) } func (*GetCartRequest) ProtoMessage() {} func (*GetCartRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{3} } func (m *GetCartRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetCartRequest.Unmarshal(m, b) } func (m *GetCartRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetCartRequest.Marshal(b, m, deterministic) } func (m *GetCartRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_GetCartRequest.Merge(m, src) } func (m *GetCartRequest) XXX_Size() int { return xxx_messageInfo_GetCartRequest.Size(m) } func (m *GetCartRequest) XXX_DiscardUnknown() { xxx_messageInfo_GetCartRequest.DiscardUnknown(m) } var xxx_messageInfo_GetCartRequest proto.InternalMessageInfo func (m *GetCartRequest) GetUserId() string { if m != nil { return m.UserId } return "" } type Cart struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Cart) Reset() { *m = Cart{} } func (m *Cart) String() string { return proto.CompactTextString(m) } func (*Cart) ProtoMessage() {} func (*Cart) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{4} } func (m *Cart) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Cart.Unmarshal(m, b) } func (m *Cart) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Cart.Marshal(b, m, deterministic) } func (m *Cart) XXX_Merge(src proto.Message) { xxx_messageInfo_Cart.Merge(m, src) } func (m *Cart) XXX_Size() int { return xxx_messageInfo_Cart.Size(m) } func (m *Cart) XXX_DiscardUnknown() { xxx_messageInfo_Cart.DiscardUnknown(m) } var xxx_messageInfo_Cart proto.InternalMessageInfo func (m *Cart) GetUserId() string { if m != nil { return m.UserId } return "" } func (m *Cart) GetItems() []*CartItem { if m != nil { return m.Items } return nil } type Empty struct { XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Empty) Reset() { *m = Empty{} } func (m *Empty) String() string { return proto.CompactTextString(m) } func (*Empty) ProtoMessage() {} func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{5} } func (m *Empty) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Empty.Unmarshal(m, b) } func (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Empty.Marshal(b, m, deterministic) } func (m *Empty) XXX_Merge(src proto.Message) { xxx_messageInfo_Empty.Merge(m, src) } func (m *Empty) XXX_Size() int { return xxx_messageInfo_Empty.Size(m) } func (m *Empty) XXX_DiscardUnknown() { xxx_messageInfo_Empty.DiscardUnknown(m) } var xxx_messageInfo_Empty proto.InternalMessageInfo type ListRecommendationsRequest struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` ProductIds []string `protobuf:"bytes,2,rep,name=product_ids,json=productIds,proto3" json:"product_ids,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ListRecommendationsRequest) Reset() { *m = ListRecommendationsRequest{} } func (m *ListRecommendationsRequest) String() string { return proto.CompactTextString(m) } func (*ListRecommendationsRequest) ProtoMessage() {} func (*ListRecommendationsRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{6} } func (m *ListRecommendationsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ListRecommendationsRequest.Unmarshal(m, b) } func (m *ListRecommendationsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ListRecommendationsRequest.Marshal(b, m, deterministic) } func (m *ListRecommendationsRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_ListRecommendationsRequest.Merge(m, src) } func (m *ListRecommendationsRequest) XXX_Size() int { return xxx_messageInfo_ListRecommendationsRequest.Size(m) } func (m *ListRecommendationsRequest) XXX_DiscardUnknown() { xxx_messageInfo_ListRecommendationsRequest.DiscardUnknown(m) } var xxx_messageInfo_ListRecommendationsRequest proto.InternalMessageInfo func (m *ListRecommendationsRequest) GetUserId() string { if m != nil { return m.UserId } return "" } func (m *ListRecommendationsRequest) GetProductIds() []string { if m != nil { return m.ProductIds } return nil } type ListRecommendationsResponse struct { ProductIds []string `protobuf:"bytes,1,rep,name=product_ids,json=productIds,proto3" json:"product_ids,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ListRecommendationsResponse) Reset() { *m = ListRecommendationsResponse{} } func (m *ListRecommendationsResponse) String() string { return proto.CompactTextString(m) } func (*ListRecommendationsResponse) ProtoMessage() {} func (*ListRecommendationsResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{7} } func (m *ListRecommendationsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ListRecommendationsResponse.Unmarshal(m, b) } func (m *ListRecommendationsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ListRecommendationsResponse.Marshal(b, m, deterministic) } func (m *ListRecommendationsResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_ListRecommendationsResponse.Merge(m, src) } func (m *ListRecommendationsResponse) XXX_Size() int { return xxx_messageInfo_ListRecommendationsResponse.Size(m) } func (m *ListRecommendationsResponse) XXX_DiscardUnknown() { xxx_messageInfo_ListRecommendationsResponse.DiscardUnknown(m) } var xxx_messageInfo_ListRecommendationsResponse proto.InternalMessageInfo func (m *ListRecommendationsResponse) GetProductIds() []string { if m != nil { return m.ProductIds } return nil } type Product struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` Picture string `protobuf:"bytes,4,opt,name=picture,proto3" json:"picture,omitempty"` PriceUsd *Money `protobuf:"bytes,5,opt,name=price_usd,json=priceUsd,proto3" json:"price_usd,omitempty"` // Categories such as "clothing" or "kitchen" that can be used to look up // other related products. Categories []string `protobuf:"bytes,6,rep,name=categories,proto3" json:"categories,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Product) Reset() { *m = Product{} } func (m *Product) String() string { return proto.CompactTextString(m) } func (*Product) ProtoMessage() {} func (*Product) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{8} } func (m *Product) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Product.Unmarshal(m, b) } func (m *Product) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Product.Marshal(b, m, deterministic) } func (m *Product) XXX_Merge(src proto.Message) { xxx_messageInfo_Product.Merge(m, src) } func (m *Product) XXX_Size() int { return xxx_messageInfo_Product.Size(m) } func (m *Product) XXX_DiscardUnknown() { xxx_messageInfo_Product.DiscardUnknown(m) } var xxx_messageInfo_Product proto.InternalMessageInfo func (m *Product) GetId() string { if m != nil { return m.Id } return "" } func (m *Product) GetName() string { if m != nil { return m.Name } return "" } func (m *Product) GetDescription() string { if m != nil { return m.Description } return "" } func (m *Product) GetPicture() string { if m != nil { return m.Picture } return "" } func (m *Product) GetPriceUsd() *Money { if m != nil { return m.PriceUsd } return nil } func (m *Product) GetCategories() []string { if m != nil { return m.Categories } return nil } type ListProductsResponse struct { Products []*Product `protobuf:"bytes,1,rep,name=products,proto3" json:"products,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ListProductsResponse) Reset() { *m = ListProductsResponse{} } func (m *ListProductsResponse) String() string { return proto.CompactTextString(m) } func (*ListProductsResponse) ProtoMessage() {} func (*ListProductsResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{9} } func (m *ListProductsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ListProductsResponse.Unmarshal(m, b) } func (m *ListProductsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ListProductsResponse.Marshal(b, m, deterministic) } func (m *ListProductsResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_ListProductsResponse.Merge(m, src) } func (m *ListProductsResponse) XXX_Size() int { return xxx_messageInfo_ListProductsResponse.Size(m) } func (m *ListProductsResponse) XXX_DiscardUnknown() { xxx_messageInfo_ListProductsResponse.DiscardUnknown(m) } var xxx_messageInfo_ListProductsResponse proto.InternalMessageInfo func (m *ListProductsResponse) GetProducts() []*Product { if m != nil { return m.Products } return nil } type GetProductRequest struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *GetProductRequest) Reset() { *m = GetProductRequest{} } func (m *GetProductRequest) String() string { return proto.CompactTextString(m) } func (*GetProductRequest) ProtoMessage() {} func (*GetProductRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{10} } func (m *GetProductRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetProductRequest.Unmarshal(m, b) } func (m *GetProductRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetProductRequest.Marshal(b, m, deterministic) } func (m *GetProductRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_GetProductRequest.Merge(m, src) } func (m *GetProductRequest) XXX_Size() int { return xxx_messageInfo_GetProductRequest.Size(m) } func (m *GetProductRequest) XXX_DiscardUnknown() { xxx_messageInfo_GetProductRequest.DiscardUnknown(m) } var xxx_messageInfo_GetProductRequest proto.InternalMessageInfo func (m *GetProductRequest) GetId() string { if m != nil { return m.Id } return "" } type SearchProductsRequest struct { Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *SearchProductsRequest) Reset() { *m = SearchProductsRequest{} } func (m *SearchProductsRequest) String() string { return proto.CompactTextString(m) } func (*SearchProductsRequest) ProtoMessage() {} func (*SearchProductsRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{11} } func (m *SearchProductsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SearchProductsRequest.Unmarshal(m, b) } func (m *SearchProductsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SearchProductsRequest.Marshal(b, m, deterministic) } func (m *SearchProductsRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_SearchProductsRequest.Merge(m, src) } func (m *SearchProductsRequest) XXX_Size() int { return xxx_messageInfo_SearchProductsRequest.Size(m) } func (m *SearchProductsRequest) XXX_DiscardUnknown() { xxx_messageInfo_SearchProductsRequest.DiscardUnknown(m) } var xxx_messageInfo_SearchProductsRequest proto.InternalMessageInfo func (m *SearchProductsRequest) GetQuery() string { if m != nil { return m.Query } return "" } type SearchProductsResponse struct { Results []*Product `protobuf:"bytes,1,rep,name=results,proto3" json:"results,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *SearchProductsResponse) Reset() { *m = SearchProductsResponse{} } func (m *SearchProductsResponse) String() string { return proto.CompactTextString(m) } func (*SearchProductsResponse) ProtoMessage() {} func (*SearchProductsResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{12} } func (m *SearchProductsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SearchProductsResponse.Unmarshal(m, b) } func (m *SearchProductsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SearchProductsResponse.Marshal(b, m, deterministic) } func (m *SearchProductsResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_SearchProductsResponse.Merge(m, src) } func (m *SearchProductsResponse) XXX_Size() int { return xxx_messageInfo_SearchProductsResponse.Size(m) } func (m *SearchProductsResponse) XXX_DiscardUnknown() { xxx_messageInfo_SearchProductsResponse.DiscardUnknown(m) } var xxx_messageInfo_SearchProductsResponse proto.InternalMessageInfo func (m *SearchProductsResponse) GetResults() []*Product { if m != nil { return m.Results } return nil } type GetQuoteRequest struct { Address *Address `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *GetQuoteRequest) Reset() { *m = GetQuoteRequest{} } func (m *GetQuoteRequest) String() string { return proto.CompactTextString(m) } func (*GetQuoteRequest) ProtoMessage() {} func (*GetQuoteRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{13} } func (m *GetQuoteRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetQuoteRequest.Unmarshal(m, b) } func (m *GetQuoteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetQuoteRequest.Marshal(b, m, deterministic) } func (m *GetQuoteRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_GetQuoteRequest.Merge(m, src) } func (m *GetQuoteRequest) XXX_Size() int { return xxx_messageInfo_GetQuoteRequest.Size(m) } func (m *GetQuoteRequest) XXX_DiscardUnknown() { xxx_messageInfo_GetQuoteRequest.DiscardUnknown(m) } var xxx_messageInfo_GetQuoteRequest proto.InternalMessageInfo func (m *GetQuoteRequest) GetAddress() *Address { if m != nil { return m.Address } return nil } func (m *GetQuoteRequest) GetItems() []*CartItem { if m != nil { return m.Items } return nil } type GetQuoteResponse struct { CostUsd *Money `protobuf:"bytes,1,opt,name=cost_usd,json=costUsd,proto3" json:"cost_usd,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *GetQuoteResponse) Reset() { *m = GetQuoteResponse{} } func (m *GetQuoteResponse) String() string { return proto.CompactTextString(m) } func (*GetQuoteResponse) ProtoMessage() {} func (*GetQuoteResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{14} } func (m *GetQuoteResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetQuoteResponse.Unmarshal(m, b) } func (m *GetQuoteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetQuoteResponse.Marshal(b, m, deterministic) } func (m *GetQuoteResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_GetQuoteResponse.Merge(m, src) } func (m *GetQuoteResponse) XXX_Size() int { return xxx_messageInfo_GetQuoteResponse.Size(m) } func (m *GetQuoteResponse) XXX_DiscardUnknown() { xxx_messageInfo_GetQuoteResponse.DiscardUnknown(m) } var xxx_messageInfo_GetQuoteResponse proto.InternalMessageInfo func (m *GetQuoteResponse) GetCostUsd() *Money { if m != nil { return m.CostUsd } return nil } type ShipOrderRequest struct { Address *Address `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ShipOrderRequest) Reset() { *m = ShipOrderRequest{} } func (m *ShipOrderRequest) String() string { return proto.CompactTextString(m) } func (*ShipOrderRequest) ProtoMessage() {} func (*ShipOrderRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{15} } func (m *ShipOrderRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ShipOrderRequest.Unmarshal(m, b) } func (m *ShipOrderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ShipOrderRequest.Marshal(b, m, deterministic) } func (m *ShipOrderRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_ShipOrderRequest.Merge(m, src) } func (m *ShipOrderRequest) XXX_Size() int { return xxx_messageInfo_ShipOrderRequest.Size(m) } func (m *ShipOrderRequest) XXX_DiscardUnknown() { xxx_messageInfo_ShipOrderRequest.DiscardUnknown(m) } var xxx_messageInfo_ShipOrderRequest proto.InternalMessageInfo func (m *ShipOrderRequest) GetAddress() *Address { if m != nil { return m.Address } return nil } func (m *ShipOrderRequest) GetItems() []*CartItem { if m != nil { return m.Items } return nil } type ShipOrderResponse struct { TrackingId string `protobuf:"bytes,1,opt,name=tracking_id,json=trackingId,proto3" json:"tracking_id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ShipOrderResponse) Reset() { *m = ShipOrderResponse{} } func (m *ShipOrderResponse) String() string { return proto.CompactTextString(m) } func (*ShipOrderResponse) ProtoMessage() {} func (*ShipOrderResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{16} } func (m *ShipOrderResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ShipOrderResponse.Unmarshal(m, b) } func (m *ShipOrderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ShipOrderResponse.Marshal(b, m, deterministic) } func (m *ShipOrderResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_ShipOrderResponse.Merge(m, src) } func (m *ShipOrderResponse) XXX_Size() int { return xxx_messageInfo_ShipOrderResponse.Size(m) } func (m *ShipOrderResponse) XXX_DiscardUnknown() { xxx_messageInfo_ShipOrderResponse.DiscardUnknown(m) } var xxx_messageInfo_ShipOrderResponse proto.InternalMessageInfo func (m *ShipOrderResponse) GetTrackingId() string { if m != nil { return m.TrackingId } return "" } type Address struct { StreetAddress string `protobuf:"bytes,1,opt,name=street_address,json=streetAddress,proto3" json:"street_address,omitempty"` City string `protobuf:"bytes,2,opt,name=city,proto3" json:"city,omitempty"` State string `protobuf:"bytes,3,opt,name=state,proto3" json:"state,omitempty"` Country string `protobuf:"bytes,4,opt,name=country,proto3" json:"country,omitempty"` ZipCode int32 `protobuf:"varint,5,opt,name=zip_code,json=zipCode,proto3" json:"zip_code,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Address) Reset() { *m = Address{} } func (m *Address) String() string { return proto.CompactTextString(m) } func (*Address) ProtoMessage() {} func (*Address) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{17} } func (m *Address) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Address.Unmarshal(m, b) } func (m *Address) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Address.Marshal(b, m, deterministic) } func (m *Address) XXX_Merge(src proto.Message) { xxx_messageInfo_Address.Merge(m, src) } func (m *Address) XXX_Size() int { return xxx_messageInfo_Address.Size(m) } func (m *Address) XXX_DiscardUnknown() { xxx_messageInfo_Address.DiscardUnknown(m) } var xxx_messageInfo_Address proto.InternalMessageInfo func (m *Address) GetStreetAddress() string { if m != nil { return m.StreetAddress } return "" } func (m *Address) GetCity() string { if m != nil { return m.City } return "" } func (m *Address) GetState() string { if m != nil { return m.State } return "" } func (m *Address) GetCountry() string { if m != nil { return m.Country } return "" } func (m *Address) GetZipCode() int32 { if m != nil { return m.ZipCode } return 0 } // Represents an amount of money with its currency type. type Money struct { // The 3-letter currency code defined in ISO 4217. CurrencyCode string `protobuf:"bytes,1,opt,name=currency_code,json=currencyCode,proto3" json:"currency_code,omitempty"` // The whole units of the amount. // For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar. Units int64 `protobuf:"varint,2,opt,name=units,proto3" json:"units,omitempty"` // Number of nano (10^-9) units of the amount. // The value must be between -999,999,999 and +999,999,999 inclusive. // If `units` is positive, `nanos` must be positive or zero. // If `units` is zero, `nanos` can be positive, zero, or negative. // If `units` is negative, `nanos` must be negative or zero. // For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000. Nanos int32 `protobuf:"varint,3,opt,name=nanos,proto3" json:"nanos,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Money) Reset() { *m = Money{} } func (m *Money) String() string { return proto.CompactTextString(m) } func (*Money) ProtoMessage() {} func (*Money) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{18} } func (m *Money) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Money.Unmarshal(m, b) } func (m *Money) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Money.Marshal(b, m, deterministic) } func (m *Money) XXX_Merge(src proto.Message) { xxx_messageInfo_Money.Merge(m, src) } func (m *Money) XXX_Size() int { return xxx_messageInfo_Money.Size(m) } func (m *Money) XXX_DiscardUnknown() { xxx_messageInfo_Money.DiscardUnknown(m) } var xxx_messageInfo_Money proto.InternalMessageInfo func (m *Money) GetCurrencyCode() string { if m != nil { return m.CurrencyCode } return "" } func (m *Money) GetUnits() int64 { if m != nil { return m.Units } return 0 } func (m *Money) GetNanos() int32 { if m != nil { return m.Nanos } return 0 } type GetSupportedCurrenciesResponse struct { // The 3-letter currency code defined in ISO 4217. CurrencyCodes []string `protobuf:"bytes,1,rep,name=currency_codes,json=currencyCodes,proto3" json:"currency_codes,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *GetSupportedCurrenciesResponse) Reset() { *m = GetSupportedCurrenciesResponse{} } func (m *GetSupportedCurrenciesResponse) String() string { return proto.CompactTextString(m) } func (*GetSupportedCurrenciesResponse) ProtoMessage() {} func (*GetSupportedCurrenciesResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{19} } func (m *GetSupportedCurrenciesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSupportedCurrenciesResponse.Unmarshal(m, b) } func (m *GetSupportedCurrenciesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetSupportedCurrenciesResponse.Marshal(b, m, deterministic) } func (m *GetSupportedCurrenciesResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_GetSupportedCurrenciesResponse.Merge(m, src) } func (m *GetSupportedCurrenciesResponse) XXX_Size() int { return xxx_messageInfo_GetSupportedCurrenciesResponse.Size(m) } func (m *GetSupportedCurrenciesResponse) XXX_DiscardUnknown() { xxx_messageInfo_GetSupportedCurrenciesResponse.DiscardUnknown(m) } var xxx_messageInfo_GetSupportedCurrenciesResponse proto.InternalMessageInfo func (m *GetSupportedCurrenciesResponse) GetCurrencyCodes() []string { if m != nil { return m.CurrencyCodes } return nil } type CurrencyConversionRequest struct { From *Money `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"` // The 3-letter currency code defined in ISO 4217. ToCode string `protobuf:"bytes,2,opt,name=to_code,json=toCode,proto3" json:"to_code,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *CurrencyConversionRequest) Reset() { *m = CurrencyConversionRequest{} } func (m *CurrencyConversionRequest) String() string { return proto.CompactTextString(m) } func (*CurrencyConversionRequest) ProtoMessage() {} func (*CurrencyConversionRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{20} } func (m *CurrencyConversionRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CurrencyConversionRequest.Unmarshal(m, b) } func (m *CurrencyConversionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CurrencyConversionRequest.Marshal(b, m, deterministic) } func (m *CurrencyConversionRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_CurrencyConversionRequest.Merge(m, src) } func (m *CurrencyConversionRequest) XXX_Size() int { return xxx_messageInfo_CurrencyConversionRequest.Size(m) } func (m *CurrencyConversionRequest) XXX_DiscardUnknown() { xxx_messageInfo_CurrencyConversionRequest.DiscardUnknown(m) } var xxx_messageInfo_CurrencyConversionRequest proto.InternalMessageInfo func (m *CurrencyConversionRequest) GetFrom() *Money { if m != nil { return m.From } return nil } func (m *CurrencyConversionRequest) GetToCode() string { if m != nil { return m.ToCode } return "" } type CreditCardInfo struct { CreditCardNumber string `protobuf:"bytes,1,opt,name=credit_card_number,json=creditCardNumber,proto3" json:"credit_card_number,omitempty"` CreditCardCvv int32 `protobuf:"varint,2,opt,name=credit_card_cvv,json=creditCardCvv,proto3" json:"credit_card_cvv,omitempty"` CreditCardExpirationYear int32 `protobuf:"varint,3,opt,name=credit_card_expiration_year,json=creditCardExpirationYear,proto3" json:"credit_card_expiration_year,omitempty"` CreditCardExpirationMonth int32 `protobuf:"varint,4,opt,name=credit_card_expiration_month,json=creditCardExpirationMonth,proto3" json:"credit_card_expiration_month,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *CreditCardInfo) Reset() { *m = CreditCardInfo{} } func (m *CreditCardInfo) String() string { return proto.CompactTextString(m) } func (*CreditCardInfo) ProtoMessage() {} func (*CreditCardInfo) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{21} } func (m *CreditCardInfo) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CreditCardInfo.Unmarshal(m, b) } func (m *CreditCardInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CreditCardInfo.Marshal(b, m, deterministic) } func (m *CreditCardInfo) XXX_Merge(src proto.Message) { xxx_messageInfo_CreditCardInfo.Merge(m, src) } func (m *CreditCardInfo) XXX_Size() int { return xxx_messageInfo_CreditCardInfo.Size(m) } func (m *CreditCardInfo) XXX_DiscardUnknown() { xxx_messageInfo_CreditCardInfo.DiscardUnknown(m) } var xxx_messageInfo_CreditCardInfo proto.InternalMessageInfo func (m *CreditCardInfo) GetCreditCardNumber() string { if m != nil { return m.CreditCardNumber } return "" } func (m *CreditCardInfo) GetCreditCardCvv() int32 { if m != nil { return m.CreditCardCvv } return 0 } func (m *CreditCardInfo) GetCreditCardExpirationYear() int32 { if m != nil { return m.CreditCardExpirationYear } return 0 } func (m *CreditCardInfo) GetCreditCardExpirationMonth() int32 { if m != nil { return m.CreditCardExpirationMonth } return 0 } type ChargeRequest struct { Amount *Money `protobuf:"bytes,1,opt,name=amount,proto3" json:"amount,omitempty"` CreditCard *CreditCardInfo `protobuf:"bytes,2,opt,name=credit_card,json=creditCard,proto3" json:"credit_card,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ChargeRequest) Reset() { *m = ChargeRequest{} } func (m *ChargeRequest) String() string { return proto.CompactTextString(m) } func (*ChargeRequest) ProtoMessage() {} func (*ChargeRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{22} } func (m *ChargeRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ChargeRequest.Unmarshal(m, b) } func (m *ChargeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ChargeRequest.Marshal(b, m, deterministic) } func (m *ChargeRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_ChargeRequest.Merge(m, src) } func (m *ChargeRequest) XXX_Size() int { return xxx_messageInfo_ChargeRequest.Size(m) } func (m *ChargeRequest) XXX_DiscardUnknown() { xxx_messageInfo_ChargeRequest.DiscardUnknown(m) } var xxx_messageInfo_ChargeRequest proto.InternalMessageInfo func (m *ChargeRequest) GetAmount() *Money { if m != nil { return m.Amount } return nil } func (m *ChargeRequest) GetCreditCard() *CreditCardInfo { if m != nil { return m.CreditCard } return nil } type ChargeResponse struct { TransactionId string `protobuf:"bytes,1,opt,name=transaction_id,json=transactionId,proto3" json:"transaction_id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ChargeResponse) Reset() { *m = ChargeResponse{} } func (m *ChargeResponse) String() string { return proto.CompactTextString(m) } func (*ChargeResponse) ProtoMessage() {} func (*ChargeResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{23} } func (m *ChargeResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ChargeResponse.Unmarshal(m, b) } func (m *ChargeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ChargeResponse.Marshal(b, m, deterministic) } func (m *ChargeResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_ChargeResponse.Merge(m, src) } func (m *ChargeResponse) XXX_Size() int { return xxx_messageInfo_ChargeResponse.Size(m) } func (m *ChargeResponse) XXX_DiscardUnknown() { xxx_messageInfo_ChargeResponse.DiscardUnknown(m) } var xxx_messageInfo_ChargeResponse proto.InternalMessageInfo func (m *ChargeResponse) GetTransactionId() string { if m != nil { return m.TransactionId } return "" } type OrderItem struct { Item *CartItem `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` Cost *Money `protobuf:"bytes,2,opt,name=cost,proto3" json:"cost,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *OrderItem) Reset() { *m = OrderItem{} } func (m *OrderItem) String() string { return proto.CompactTextString(m) } func (*OrderItem) ProtoMessage() {} func (*OrderItem) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{24} } func (m *OrderItem) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_OrderItem.Unmarshal(m, b) } func (m *OrderItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_OrderItem.Marshal(b, m, deterministic) } func (m *OrderItem) XXX_Merge(src proto.Message) { xxx_messageInfo_OrderItem.Merge(m, src) } func (m *OrderItem) XXX_Size() int { return xxx_messageInfo_OrderItem.Size(m) } func (m *OrderItem) XXX_DiscardUnknown() { xxx_messageInfo_OrderItem.DiscardUnknown(m) } var xxx_messageInfo_OrderItem proto.InternalMessageInfo func (m *OrderItem) GetItem() *CartItem { if m != nil { return m.Item } return nil } func (m *OrderItem) GetCost() *Money { if m != nil { return m.Cost } return nil } type OrderResult struct { OrderId string `protobuf:"bytes,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` ShippingTrackingId string `protobuf:"bytes,2,opt,name=shipping_tracking_id,json=shippingTrackingId,proto3" json:"shipping_tracking_id,omitempty"` ShippingCost *Money `protobuf:"bytes,3,opt,name=shipping_cost,json=shippingCost,proto3" json:"shipping_cost,omitempty"` ShippingAddress *Address `protobuf:"bytes,4,opt,name=shipping_address,json=shippingAddress,proto3" json:"shipping_address,omitempty"` Items []*OrderItem `protobuf:"bytes,5,rep,name=items,proto3" json:"items,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *OrderResult) Reset() { *m = OrderResult{} } func (m *OrderResult) String() string { return proto.CompactTextString(m) } func (*OrderResult) ProtoMessage() {} func (*OrderResult) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{25} } func (m *OrderResult) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_OrderResult.Unmarshal(m, b) } func (m *OrderResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_OrderResult.Marshal(b, m, deterministic) } func (m *OrderResult) XXX_Merge(src proto.Message) { xxx_messageInfo_OrderResult.Merge(m, src) } func (m *OrderResult) XXX_Size() int { return xxx_messageInfo_OrderResult.Size(m) } func (m *OrderResult) XXX_DiscardUnknown() { xxx_messageInfo_OrderResult.DiscardUnknown(m) } var xxx_messageInfo_OrderResult proto.InternalMessageInfo func (m *OrderResult) GetOrderId() string { if m != nil { return m.OrderId } return "" } func (m *OrderResult) GetShippingTrackingId() string { if m != nil { return m.ShippingTrackingId } return "" } func (m *OrderResult) GetShippingCost() *Money { if m != nil { return m.ShippingCost } return nil } func (m *OrderResult) GetShippingAddress() *Address { if m != nil { return m.ShippingAddress } return nil } func (m *OrderResult) GetItems() []*OrderItem { if m != nil { return m.Items } return nil } type SendOrderConfirmationRequest struct { Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` Order *OrderResult `protobuf:"bytes,2,opt,name=order,proto3" json:"order,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *SendOrderConfirmationRequest) Reset() { *m = SendOrderConfirmationRequest{} } func (m *SendOrderConfirmationRequest) String() string { return proto.CompactTextString(m) } func (*SendOrderConfirmationRequest) ProtoMessage() {} func (*SendOrderConfirmationRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{26} } func (m *SendOrderConfirmationRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SendOrderConfirmationRequest.Unmarshal(m, b) } func (m *SendOrderConfirmationRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SendOrderConfirmationRequest.Marshal(b, m, deterministic) } func (m *SendOrderConfirmationRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_SendOrderConfirmationRequest.Merge(m, src) } func (m *SendOrderConfirmationRequest) XXX_Size() int { return xxx_messageInfo_SendOrderConfirmationRequest.Size(m) } func (m *SendOrderConfirmationRequest) XXX_DiscardUnknown() { xxx_messageInfo_SendOrderConfirmationRequest.DiscardUnknown(m) } var xxx_messageInfo_SendOrderConfirmationRequest proto.InternalMessageInfo func (m *SendOrderConfirmationRequest) GetEmail() string { if m != nil { return m.Email } return "" } func (m *SendOrderConfirmationRequest) GetOrder() *OrderResult { if m != nil { return m.Order } return nil } type PlaceOrderRequest struct { UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` UserCurrency string `protobuf:"bytes,2,opt,name=user_currency,json=userCurrency,proto3" json:"user_currency,omitempty"` Address *Address `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"` Email string `protobuf:"bytes,5,opt,name=email,proto3" json:"email,omitempty"` CreditCard *CreditCardInfo `protobuf:"bytes,6,opt,name=credit_card,json=creditCard,proto3" json:"credit_card,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *PlaceOrderRequest) Reset() { *m = PlaceOrderRequest{} } func (m *PlaceOrderRequest) String() string { return proto.CompactTextString(m) } func (*PlaceOrderRequest) ProtoMessage() {} func (*PlaceOrderRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{27} } func (m *PlaceOrderRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PlaceOrderRequest.Unmarshal(m, b) } func (m *PlaceOrderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PlaceOrderRequest.Marshal(b, m, deterministic) } func (m *PlaceOrderRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_PlaceOrderRequest.Merge(m, src) } func (m *PlaceOrderRequest) XXX_Size() int { return xxx_messageInfo_PlaceOrderRequest.Size(m) } func (m *PlaceOrderRequest) XXX_DiscardUnknown() { xxx_messageInfo_PlaceOrderRequest.DiscardUnknown(m) } var xxx_messageInfo_PlaceOrderRequest proto.InternalMessageInfo func (m *PlaceOrderRequest) GetUserId() string { if m != nil { return m.UserId } return "" } func (m *PlaceOrderRequest) GetUserCurrency() string { if m != nil { return m.UserCurrency } return "" } func (m *PlaceOrderRequest) GetAddress() *Address { if m != nil { return m.Address } return nil } func (m *PlaceOrderRequest) GetEmail() string { if m != nil { return m.Email } return "" } func (m *PlaceOrderRequest) GetCreditCard() *CreditCardInfo { if m != nil { return m.CreditCard } return nil } type PlaceOrderResponse struct { Order *OrderResult `protobuf:"bytes,1,opt,name=order,proto3" json:"order,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *PlaceOrderResponse) Reset() { *m = PlaceOrderResponse{} } func (m *PlaceOrderResponse) String() string { return proto.CompactTextString(m) } func (*PlaceOrderResponse) ProtoMessage() {} func (*PlaceOrderResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{28} } func (m *PlaceOrderResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PlaceOrderResponse.Unmarshal(m, b) } func (m *PlaceOrderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PlaceOrderResponse.Marshal(b, m, deterministic) } func (m *PlaceOrderResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_PlaceOrderResponse.Merge(m, src) } func (m *PlaceOrderResponse) XXX_Size() int { return xxx_messageInfo_PlaceOrderResponse.Size(m) } func (m *PlaceOrderResponse) XXX_DiscardUnknown() { xxx_messageInfo_PlaceOrderResponse.DiscardUnknown(m) } var xxx_messageInfo_PlaceOrderResponse proto.InternalMessageInfo func (m *PlaceOrderResponse) GetOrder() *OrderResult { if m != nil { return m.Order } return nil } type AdRequest struct { // List of important key words from the current page describing the context. ContextKeys []string `protobuf:"bytes,1,rep,name=context_keys,json=contextKeys,proto3" json:"context_keys,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *AdRequest) Reset() { *m = AdRequest{} } func (m *AdRequest) String() string { return proto.CompactTextString(m) } func (*AdRequest) ProtoMessage() {} func (*AdRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{29} } func (m *AdRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AdRequest.Unmarshal(m, b) } func (m *AdRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_AdRequest.Marshal(b, m, deterministic) } func (m *AdRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_AdRequest.Merge(m, src) } func (m *AdRequest) XXX_Size() int { return xxx_messageInfo_AdRequest.Size(m) } func (m *AdRequest) XXX_DiscardUnknown() { xxx_messageInfo_AdRequest.DiscardUnknown(m) } var xxx_messageInfo_AdRequest proto.InternalMessageInfo func (m *AdRequest) GetContextKeys() []string { if m != nil { return m.ContextKeys } return nil } type AdResponse struct { Ads []*Ad `protobuf:"bytes,1,rep,name=ads,proto3" json:"ads,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *AdResponse) Reset() { *m = AdResponse{} } func (m *AdResponse) String() string { return proto.CompactTextString(m) } func (*AdResponse) ProtoMessage() {} func (*AdResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{30} } func (m *AdResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AdResponse.Unmarshal(m, b) } func (m *AdResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_AdResponse.Marshal(b, m, deterministic) } func (m *AdResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_AdResponse.Merge(m, src) } func (m *AdResponse) XXX_Size() int { return xxx_messageInfo_AdResponse.Size(m) } func (m *AdResponse) XXX_DiscardUnknown() { xxx_messageInfo_AdResponse.DiscardUnknown(m) } var xxx_messageInfo_AdResponse proto.InternalMessageInfo func (m *AdResponse) GetAds() []*Ad { if m != nil { return m.Ads } return nil } type Ad struct { // url to redirect to when an ad is clicked. RedirectUrl string `protobuf:"bytes,1,opt,name=redirect_url,json=redirectUrl,proto3" json:"redirect_url,omitempty"` // short advertisement text to display. Text string `protobuf:"bytes,2,opt,name=text,proto3" json:"text,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Ad) Reset() { *m = Ad{} } func (m *Ad) String() string { return proto.CompactTextString(m) } func (*Ad) ProtoMessage() {} func (*Ad) Descriptor() ([]byte, []int) { return fileDescriptor_ca53982754088a9d, []int{31} } func (m *Ad) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Ad.Unmarshal(m, b) } func (m *Ad) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Ad.Marshal(b, m, deterministic) } func (m *Ad) XXX_Merge(src proto.Message) { xxx_messageInfo_Ad.Merge(m, src) } func (m *Ad) XXX_Size() int { return xxx_messageInfo_Ad.Size(m) } func (m *Ad) XXX_DiscardUnknown() { xxx_messageInfo_Ad.DiscardUnknown(m) } var xxx_messageInfo_Ad proto.InternalMessageInfo func (m *Ad) GetRedirectUrl() string { if m != nil { return m.RedirectUrl } return "" } func (m *Ad) GetText() string { if m != nil { return m.Text } return "" } func init() { proto.RegisterType((*CartItem)(nil), "hipstershop.CartItem") proto.RegisterType((*AddItemRequest)(nil), "hipstershop.AddItemRequest") proto.RegisterType((*EmptyCartRequest)(nil), "hipstershop.EmptyCartRequest") proto.RegisterType((*GetCartRequest)(nil), "hipstershop.GetCartRequest") proto.RegisterType((*Cart)(nil), "hipstershop.Cart") proto.RegisterType((*Empty)(nil), "hipstershop.Empty") proto.RegisterType((*ListRecommendationsRequest)(nil), "hipstershop.ListRecommendationsRequest") proto.RegisterType((*ListRecommendationsResponse)(nil), "hipstershop.ListRecommendationsResponse") proto.RegisterType((*Product)(nil), "hipstershop.Product") proto.RegisterType((*ListProductsResponse)(nil), "hipstershop.ListProductsResponse") proto.RegisterType((*GetProductRequest)(nil), "hipstershop.GetProductRequest") proto.RegisterType((*SearchProductsRequest)(nil), "hipstershop.SearchProductsRequest") proto.RegisterType((*SearchProductsResponse)(nil), "hipstershop.SearchProductsResponse") proto.RegisterType((*GetQuoteRequest)(nil), "hipstershop.GetQuoteRequest") proto.RegisterType((*GetQuoteResponse)(nil), "hipstershop.GetQuoteResponse") proto.RegisterType((*ShipOrderRequest)(nil), "hipstershop.ShipOrderRequest") proto.RegisterType((*ShipOrderResponse)(nil), "hipstershop.ShipOrderResponse") proto.RegisterType((*Address)(nil), "hipstershop.Address") proto.RegisterType((*Money)(nil), "hipstershop.Money") proto.RegisterType((*GetSupportedCurrenciesResponse)(nil), "hipstershop.GetSupportedCurrenciesResponse") proto.RegisterType((*CurrencyConversionRequest)(nil), "hipstershop.CurrencyConversionRequest") proto.RegisterType((*CreditCardInfo)(nil), "hipstershop.CreditCardInfo") proto.RegisterType((*ChargeRequest)(nil), "hipstershop.ChargeRequest") proto.RegisterType((*ChargeResponse)(nil), "hipstershop.ChargeResponse") proto.RegisterType((*OrderItem)(nil), "hipstershop.OrderItem") proto.RegisterType((*OrderResult)(nil), "hipstershop.OrderResult") proto.RegisterType((*SendOrderConfirmationRequest)(nil), "hipstershop.SendOrderConfirmationRequest") proto.RegisterType((*PlaceOrderRequest)(nil), "hipstershop.PlaceOrderRequest") proto.RegisterType((*PlaceOrderResponse)(nil), "hipstershop.PlaceOrderResponse") proto.RegisterType((*AdRequest)(nil), "hipstershop.AdRequest") proto.RegisterType((*AdResponse)(nil), "hipstershop.AdResponse") proto.RegisterType((*Ad)(nil), "hipstershop.Ad") } // Reference imports to suppress errors if they are not otherwise used. var _ context.Context var _ grpc.ClientConn // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. const _ = grpc.SupportPackageIsVersion4 // CartServiceClient is the client API for CartService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type CartServiceClient interface { AddItem(ctx context.Context, in *AddItemRequest, opts ...grpc.CallOption) (*Empty, error) GetCart(ctx context.Context, in *GetCartRequest, opts ...grpc.CallOption) (*Cart, error) EmptyCart(ctx context.Context, in *EmptyCartRequest, opts ...grpc.CallOption) (*Empty, error) } type cartServiceClient struct { cc *grpc.ClientConn } func NewCartServiceClient(cc *grpc.ClientConn) CartServiceClient { return &cartServiceClient{cc} } func (c *cartServiceClient) AddItem(ctx context.Context, in *AddItemRequest, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) err := c.cc.Invoke(ctx, "/hipstershop.CartService/AddItem", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *cartServiceClient) GetCart(ctx context.Context, in *GetCartRequest, opts ...grpc.CallOption) (*Cart, error) { out := new(Cart) err := c.cc.Invoke(ctx, "/hipstershop.CartService/GetCart", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *cartServiceClient) EmptyCart(ctx context.Context, in *EmptyCartRequest, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) err := c.cc.Invoke(ctx, "/hipstershop.CartService/EmptyCart", in, out, opts...) if err != nil { return nil, err } return out, nil } // CartServiceServer is the server API for CartService service. type CartServiceServer interface { AddItem(context.Context, *AddItemRequest) (*Empty, error) GetCart(context.Context, *GetCartRequest) (*Cart, error) EmptyCart(context.Context, *EmptyCartRequest) (*Empty, error) } func RegisterCartServiceServer(s *grpc.Server, srv CartServiceServer) { s.RegisterService(&_CartService_serviceDesc, srv) } func _CartService_AddItem_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AddItemRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CartServiceServer).AddItem(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CartService/AddItem", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CartServiceServer).AddItem(ctx, req.(*AddItemRequest)) } return interceptor(ctx, in, info, handler) } func _CartService_GetCart_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetCartRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CartServiceServer).GetCart(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CartService/GetCart", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CartServiceServer).GetCart(ctx, req.(*GetCartRequest)) } return interceptor(ctx, in, info, handler) } func _CartService_EmptyCart_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(EmptyCartRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CartServiceServer).EmptyCart(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CartService/EmptyCart", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CartServiceServer).EmptyCart(ctx, req.(*EmptyCartRequest)) } return interceptor(ctx, in, info, handler) } var _CartService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.CartService", HandlerType: (*CartServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "AddItem", Handler: _CartService_AddItem_Handler, }, { MethodName: "GetCart", Handler: _CartService_GetCart_Handler, }, { MethodName: "EmptyCart", Handler: _CartService_EmptyCart_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // RecommendationServiceClient is the client API for RecommendationService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type RecommendationServiceClient interface { ListRecommendations(ctx context.Context, in *ListRecommendationsRequest, opts ...grpc.CallOption) (*ListRecommendationsResponse, error) } type recommendationServiceClient struct { cc *grpc.ClientConn } func NewRecommendationServiceClient(cc *grpc.ClientConn) RecommendationServiceClient { return &recommendationServiceClient{cc} } func (c *recommendationServiceClient) ListRecommendations(ctx context.Context, in *ListRecommendationsRequest, opts ...grpc.CallOption) (*ListRecommendationsResponse, error) { out := new(ListRecommendationsResponse) err := c.cc.Invoke(ctx, "/hipstershop.RecommendationService/ListRecommendations", in, out, opts...) if err != nil { return nil, err } return out, nil } // RecommendationServiceServer is the server API for RecommendationService service. type RecommendationServiceServer interface { ListRecommendations(context.Context, *ListRecommendationsRequest) (*ListRecommendationsResponse, error) } func RegisterRecommendationServiceServer(s *grpc.Server, srv RecommendationServiceServer) { s.RegisterService(&_RecommendationService_serviceDesc, srv) } func _RecommendationService_ListRecommendations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListRecommendationsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(RecommendationServiceServer).ListRecommendations(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.RecommendationService/ListRecommendations", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(RecommendationServiceServer).ListRecommendations(ctx, req.(*ListRecommendationsRequest)) } return interceptor(ctx, in, info, handler) } var _RecommendationService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.RecommendationService", HandlerType: (*RecommendationServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "ListRecommendations", Handler: _RecommendationService_ListRecommendations_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // ProductCatalogServiceClient is the client API for ProductCatalogService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type ProductCatalogServiceClient interface { ListProducts(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ListProductsResponse, error) GetProduct(ctx context.Context, in *GetProductRequest, opts ...grpc.CallOption) (*Product, error) SearchProducts(ctx context.Context, in *SearchProductsRequest, opts ...grpc.CallOption) (*SearchProductsResponse, error) } type productCatalogServiceClient struct { cc *grpc.ClientConn } func NewProductCatalogServiceClient(cc *grpc.ClientConn) ProductCatalogServiceClient { return &productCatalogServiceClient{cc} } func (c *productCatalogServiceClient) ListProducts(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ListProductsResponse, error) { out := new(ListProductsResponse) err := c.cc.Invoke(ctx, "/hipstershop.ProductCatalogService/ListProducts", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *productCatalogServiceClient) GetProduct(ctx context.Context, in *GetProductRequest, opts ...grpc.CallOption) (*Product, error) { out := new(Product) err := c.cc.Invoke(ctx, "/hipstershop.ProductCatalogService/GetProduct", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *productCatalogServiceClient) SearchProducts(ctx context.Context, in *SearchProductsRequest, opts ...grpc.CallOption) (*SearchProductsResponse, error) { out := new(SearchProductsResponse) err := c.cc.Invoke(ctx, "/hipstershop.ProductCatalogService/SearchProducts", in, out, opts...) if err != nil { return nil, err } return out, nil } // ProductCatalogServiceServer is the server API for ProductCatalogService service. type ProductCatalogServiceServer interface { ListProducts(context.Context, *Empty) (*ListProductsResponse, error) GetProduct(context.Context, *GetProductRequest) (*Product, error) SearchProducts(context.Context, *SearchProductsRequest) (*SearchProductsResponse, error) } func RegisterProductCatalogServiceServer(s *grpc.Server, srv ProductCatalogServiceServer) { s.RegisterService(&_ProductCatalogService_serviceDesc, srv) } func _ProductCatalogService_ListProducts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(Empty) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(ProductCatalogServiceServer).ListProducts(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.ProductCatalogService/ListProducts", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ProductCatalogServiceServer).ListProducts(ctx, req.(*Empty)) } return interceptor(ctx, in, info, handler) } func _ProductCatalogService_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.(ProductCatalogServiceServer).GetProduct(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.ProductCatalogService/GetProduct", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ProductCatalogServiceServer).GetProduct(ctx, req.(*GetProductRequest)) } return interceptor(ctx, in, info, handler) } func _ProductCatalogService_SearchProducts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(SearchProductsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(ProductCatalogServiceServer).SearchProducts(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.ProductCatalogService/SearchProducts", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ProductCatalogServiceServer).SearchProducts(ctx, req.(*SearchProductsRequest)) } return interceptor(ctx, in, info, handler) } var _ProductCatalogService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.ProductCatalogService", HandlerType: (*ProductCatalogServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "ListProducts", Handler: _ProductCatalogService_ListProducts_Handler, }, { MethodName: "GetProduct", Handler: _ProductCatalogService_GetProduct_Handler, }, { MethodName: "SearchProducts", Handler: _ProductCatalogService_SearchProducts_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // ShippingServiceClient is the client API for ShippingService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type ShippingServiceClient interface { GetQuote(ctx context.Context, in *GetQuoteRequest, opts ...grpc.CallOption) (*GetQuoteResponse, error) ShipOrder(ctx context.Context, in *ShipOrderRequest, opts ...grpc.CallOption) (*ShipOrderResponse, error) } type shippingServiceClient struct { cc *grpc.ClientConn } func NewShippingServiceClient(cc *grpc.ClientConn) ShippingServiceClient { return &shippingServiceClient{cc} } func (c *shippingServiceClient) GetQuote(ctx context.Context, in *GetQuoteRequest, opts ...grpc.CallOption) (*GetQuoteResponse, error) { out := new(GetQuoteResponse) err := c.cc.Invoke(ctx, "/hipstershop.ShippingService/GetQuote", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *shippingServiceClient) ShipOrder(ctx context.Context, in *ShipOrderRequest, opts ...grpc.CallOption) (*ShipOrderResponse, error) { out := new(ShipOrderResponse) err := c.cc.Invoke(ctx, "/hipstershop.ShippingService/ShipOrder", in, out, opts...) if err != nil { return nil, err } return out, nil } // ShippingServiceServer is the server API for ShippingService service. type ShippingServiceServer interface { GetQuote(context.Context, *GetQuoteRequest) (*GetQuoteResponse, error) ShipOrder(context.Context, *ShipOrderRequest) (*ShipOrderResponse, error) } func RegisterShippingServiceServer(s *grpc.Server, srv ShippingServiceServer) { s.RegisterService(&_ShippingService_serviceDesc, srv) } func _ShippingService_GetQuote_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetQuoteRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(ShippingServiceServer).GetQuote(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.ShippingService/GetQuote", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ShippingServiceServer).GetQuote(ctx, req.(*GetQuoteRequest)) } return interceptor(ctx, in, info, handler) } func _ShippingService_ShipOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ShipOrderRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(ShippingServiceServer).ShipOrder(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.ShippingService/ShipOrder", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ShippingServiceServer).ShipOrder(ctx, req.(*ShipOrderRequest)) } return interceptor(ctx, in, info, handler) } var _ShippingService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.ShippingService", HandlerType: (*ShippingServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "GetQuote", Handler: _ShippingService_GetQuote_Handler, }, { MethodName: "ShipOrder", Handler: _ShippingService_ShipOrder_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // CurrencyServiceClient is the client API for CurrencyService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type CurrencyServiceClient interface { GetSupportedCurrencies(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetSupportedCurrenciesResponse, error) Convert(ctx context.Context, in *CurrencyConversionRequest, opts ...grpc.CallOption) (*Money, error) } type currencyServiceClient struct { cc *grpc.ClientConn } func NewCurrencyServiceClient(cc *grpc.ClientConn) CurrencyServiceClient { return ¤cyServiceClient{cc} } func (c *currencyServiceClient) GetSupportedCurrencies(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetSupportedCurrenciesResponse, error) { out := new(GetSupportedCurrenciesResponse) err := c.cc.Invoke(ctx, "/hipstershop.CurrencyService/GetSupportedCurrencies", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *currencyServiceClient) Convert(ctx context.Context, in *CurrencyConversionRequest, opts ...grpc.CallOption) (*Money, error) { out := new(Money) err := c.cc.Invoke(ctx, "/hipstershop.CurrencyService/Convert", in, out, opts...) if err != nil { return nil, err } return out, nil } // CurrencyServiceServer is the server API for CurrencyService service. type CurrencyServiceServer interface { GetSupportedCurrencies(context.Context, *Empty) (*GetSupportedCurrenciesResponse, error) Convert(context.Context, *CurrencyConversionRequest) (*Money, error) } func RegisterCurrencyServiceServer(s *grpc.Server, srv CurrencyServiceServer) { s.RegisterService(&_CurrencyService_serviceDesc, srv) } func _CurrencyService_GetSupportedCurrencies_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(Empty) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CurrencyServiceServer).GetSupportedCurrencies(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CurrencyService/GetSupportedCurrencies", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CurrencyServiceServer).GetSupportedCurrencies(ctx, req.(*Empty)) } return interceptor(ctx, in, info, handler) } func _CurrencyService_Convert_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CurrencyConversionRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CurrencyServiceServer).Convert(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CurrencyService/Convert", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CurrencyServiceServer).Convert(ctx, req.(*CurrencyConversionRequest)) } return interceptor(ctx, in, info, handler) } var _CurrencyService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.CurrencyService", HandlerType: (*CurrencyServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "GetSupportedCurrencies", Handler: _CurrencyService_GetSupportedCurrencies_Handler, }, { MethodName: "Convert", Handler: _CurrencyService_Convert_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // PaymentServiceClient is the client API for PaymentService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type PaymentServiceClient interface { Charge(ctx context.Context, in *ChargeRequest, opts ...grpc.CallOption) (*ChargeResponse, error) } type paymentServiceClient struct { cc *grpc.ClientConn } func NewPaymentServiceClient(cc *grpc.ClientConn) PaymentServiceClient { return &paymentServiceClient{cc} } func (c *paymentServiceClient) Charge(ctx context.Context, in *ChargeRequest, opts ...grpc.CallOption) (*ChargeResponse, error) { out := new(ChargeResponse) err := c.cc.Invoke(ctx, "/hipstershop.PaymentService/Charge", in, out, opts...) if err != nil { return nil, err } return out, nil } // PaymentServiceServer is the server API for PaymentService service. type PaymentServiceServer interface { Charge(context.Context, *ChargeRequest) (*ChargeResponse, error) } func RegisterPaymentServiceServer(s *grpc.Server, srv PaymentServiceServer) { s.RegisterService(&_PaymentService_serviceDesc, srv) } func _PaymentService_Charge_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ChargeRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(PaymentServiceServer).Charge(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.PaymentService/Charge", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(PaymentServiceServer).Charge(ctx, req.(*ChargeRequest)) } return interceptor(ctx, in, info, handler) } var _PaymentService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.PaymentService", HandlerType: (*PaymentServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "Charge", Handler: _PaymentService_Charge_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // EmailServiceClient is the client API for EmailService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type EmailServiceClient interface { SendOrderConfirmation(ctx context.Context, in *SendOrderConfirmationRequest, opts ...grpc.CallOption) (*Empty, error) } type emailServiceClient struct { cc *grpc.ClientConn } func NewEmailServiceClient(cc *grpc.ClientConn) EmailServiceClient { return &emailServiceClient{cc} } func (c *emailServiceClient) SendOrderConfirmation(ctx context.Context, in *SendOrderConfirmationRequest, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) err := c.cc.Invoke(ctx, "/hipstershop.EmailService/SendOrderConfirmation", in, out, opts...) if err != nil { return nil, err } return out, nil } // EmailServiceServer is the server API for EmailService service. type EmailServiceServer interface { SendOrderConfirmation(context.Context, *SendOrderConfirmationRequest) (*Empty, error) } func RegisterEmailServiceServer(s *grpc.Server, srv EmailServiceServer) { s.RegisterService(&_EmailService_serviceDesc, srv) } func _EmailService_SendOrderConfirmation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(SendOrderConfirmationRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(EmailServiceServer).SendOrderConfirmation(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.EmailService/SendOrderConfirmation", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(EmailServiceServer).SendOrderConfirmation(ctx, req.(*SendOrderConfirmationRequest)) } return interceptor(ctx, in, info, handler) } var _EmailService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.EmailService", HandlerType: (*EmailServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "SendOrderConfirmation", Handler: _EmailService_SendOrderConfirmation_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // CheckoutServiceClient is the client API for CheckoutService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type CheckoutServiceClient interface { PlaceOrder(ctx context.Context, in *PlaceOrderRequest, opts ...grpc.CallOption) (*PlaceOrderResponse, error) } type checkoutServiceClient struct { cc *grpc.ClientConn } func NewCheckoutServiceClient(cc *grpc.ClientConn) CheckoutServiceClient { return &checkoutServiceClient{cc} } func (c *checkoutServiceClient) PlaceOrder(ctx context.Context, in *PlaceOrderRequest, opts ...grpc.CallOption) (*PlaceOrderResponse, error) { out := new(PlaceOrderResponse) err := c.cc.Invoke(ctx, "/hipstershop.CheckoutService/PlaceOrder", in, out, opts...) if err != nil { return nil, err } return out, nil } // CheckoutServiceServer is the server API for CheckoutService service. type CheckoutServiceServer interface { PlaceOrder(context.Context, *PlaceOrderRequest) (*PlaceOrderResponse, error) } func RegisterCheckoutServiceServer(s *grpc.Server, srv CheckoutServiceServer) { s.RegisterService(&_CheckoutService_serviceDesc, srv) } func _CheckoutService_PlaceOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(PlaceOrderRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(CheckoutServiceServer).PlaceOrder(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.CheckoutService/PlaceOrder", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CheckoutServiceServer).PlaceOrder(ctx, req.(*PlaceOrderRequest)) } return interceptor(ctx, in, info, handler) } var _CheckoutService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.CheckoutService", HandlerType: (*CheckoutServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "PlaceOrder", Handler: _CheckoutService_PlaceOrder_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } // AdServiceClient is the client API for AdService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type AdServiceClient interface { GetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error) } type adServiceClient struct { cc *grpc.ClientConn } func NewAdServiceClient(cc *grpc.ClientConn) AdServiceClient { return &adServiceClient{cc} } func (c *adServiceClient) GetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error) { out := new(AdResponse) err := c.cc.Invoke(ctx, "/hipstershop.AdService/GetAds", in, out, opts...) if err != nil { return nil, err } return out, nil } // AdServiceServer is the server API for AdService service. type AdServiceServer interface { GetAds(context.Context, *AdRequest) (*AdResponse, error) } func RegisterAdServiceServer(s *grpc.Server, srv AdServiceServer) { s.RegisterService(&_AdService_serviceDesc, srv) } func _AdService_GetAds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AdRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(AdServiceServer).GetAds(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/hipstershop.AdService/GetAds", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(AdServiceServer).GetAds(ctx, req.(*AdRequest)) } return interceptor(ctx, in, info, handler) } var _AdService_serviceDesc = grpc.ServiceDesc{ ServiceName: "hipstershop.AdService", HandlerType: (*AdServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "GetAds", Handler: _AdService_GetAds_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "demo.proto", } func init() { proto.RegisterFile("demo.proto", fileDescriptor_ca53982754088a9d) } var fileDescriptor_ca53982754088a9d = []byte{ // 1500 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xef, 0x72, 0x13, 0xb7, 0x16, 0xcf, 0x26, 0xb1, 0x1d, 0x1f, 0xc7, 0x4e, 0xa2, 0x9b, 0x04, 0xb3, 0x81, 0x10, 0x94, 0x81, 0x0b, 0x17, 0x08, 0x4c, 0xee, 0x9d, 0xe1, 0x03, 0xdc, 0xd2, 0x8c, 0xc9, 0x18, 0x4f, 0xa1, 0xd0, 0x0d, 0xe9, 0xd0, 0xa1, 0x53, 0xcf, 0xb2, 0x12, 0xf1, 0x96, 0xec, 0x6a, 0x91, 0xb4, 0x19, 0xcc, 0xc7, 0xf6, 0x01, 0xfa, 0x1e, 0x7d, 0x81, 0xce, 0xf4, 0x11, 0xfa, 0xbd, 0xaf, 0xd0, 0xe7, 0xe8, 0x48, 0xbb, 0xda, 0x7f, 0xb1, 0x13, 0xf8, 0xd2, 0x6f, 0xab, 0xa3, 0x9f, 0xce, 0xf9, 0xe9, 0xe8, 0xfc, 0xb3, 0x01, 0x08, 0x0d, 0xd8, 0x4e, 0xc4, 0x99, 0x64, 0xa8, 0x35, 0xf2, 0x23, 0x21, 0x29, 0x17, 0x23, 0x16, 0xe1, 0x7d, 0x58, 0xe8, 0xb9, 0x5c, 0x0e, 0x24, 0x0d, 0xd0, 0x65, 0x80, 0x88, 0x33, 0x12, 0x7b, 0x72, 0xe8, 0x93, 0xae, 0xb5, 0x65, 0xdd, 0x68, 0x3a, 0xcd, 0x54, 0x32, 0x20, 0xc8, 0x86, 0x85, 0xf7, 0xb1, 0x1b, 0x4a, 0x5f, 0x8e, 0xbb, 0xb3, 0x5b, 0xd6, 0x8d, 0x9a, 0x93, 0xad, 0xf1, 0x4b, 0xe8, 0xec, 0x11, 0xa2, 0xb4, 0x38, 0xf4, 0x7d, 0x4c, 0x85, 0x44, 0x17, 0xa0, 0x11, 0x0b, 0xca, 0x73, 0x4d, 0x75, 0xb5, 0x1c, 0x10, 0x74, 0x13, 0xe6, 0x7d, 0x49, 0x03, 0xad, 0xa2, 0xb5, 0xbb, 0xb6, 0x53, 0x60, 0xb3, 0x63, 0xa8, 0x38, 0x1a, 0x82, 0x6f, 0xc1, 0xf2, 0x7e, 0x10, 0xc9, 0xb1, 0x12, 0x9f, 0xa7, 0x17, 0xdf, 0x84, 0x4e, 0x9f, 0xca, 0x4f, 0x82, 0x3e, 0x85, 0x79, 0x85, 0x9b, 0xce, 0xf1, 0x16, 0xd4, 0x14, 0x01, 0xd1, 0x9d, 0xdd, 0x9a, 0x9b, 0x4e, 0x32, 0xc1, 0xe0, 0x06, 0xd4, 0x34, 0x4b, 0xfc, 0x2d, 0xd8, 0x4f, 0x7d, 0x21, 0x1d, 0xea, 0xb1, 0x20, 0xa0, 0x21, 0x71, 0xa5, 0xcf, 0x42, 0x71, 0xae, 0x43, 0xae, 0x40, 0x2b, 0x77, 0x7b, 0x62, 0xb2, 0xe9, 0x40, 0xe6, 0x77, 0x81, 0xbf, 0x80, 0x8d, 0x89, 0x7a, 0x45, 0xc4, 0x42, 0x41, 0xab, 0xe7, 0xad, 0x53, 0xe7, 0x7f, 0xb7, 0xa0, 0xf1, 0x22, 0x59, 0xa2, 0x0e, 0xcc, 0x66, 0x04, 0x66, 0x7d, 0x82, 0x10, 0xcc, 0x87, 0x6e, 0x40, 0xf5, 0x6b, 0x34, 0x1d, 0xfd, 0x8d, 0xb6, 0xa0, 0x45, 0xa8, 0xf0, 0xb8, 0x1f, 0x29, 0x43, 0xdd, 0x39, 0xbd, 0x55, 0x14, 0xa1, 0x2e, 0x34, 0x22, 0xdf, 0x93, 0x31, 0xa7, 0xdd, 0x79, 0xbd, 0x6b, 0x96, 0xe8, 0x2e, 0x34, 0x23, 0xee, 0x7b, 0x74, 0x18, 0x0b, 0xd2, 0xad, 0xe9, 0x27, 0x46, 0x25, 0xef, 0x3d, 0x63, 0x21, 0x1d, 0x3b, 0x0b, 0x1a, 0x74, 0x28, 0x08, 0xda, 0x04, 0xf0, 0x5c, 0x49, 0x8f, 0x18, 0xf7, 0xa9, 0xe8, 0xd6, 0x13, 0xf2, 0xb9, 0x04, 0x3f, 0x81, 0x55, 0x75, 0xf9, 0x94, 0x7f, 0x7e, 0xeb, 0x7b, 0xb0, 0x90, 0x5e, 0x31, 0xb9, 0x72, 0x6b, 0x77, 0xb5, 0x64, 0x27, 0x3d, 0xe0, 0x64, 0x28, 0xbc, 0x0d, 0x2b, 0x7d, 0x6a, 0x14, 0x99, 0x57, 0xa9, 0xf8, 0x03, 0xdf, 0x81, 0xb5, 0x03, 0xea, 0x72, 0x6f, 0x94, 0x1b, 0x4c, 0x80, 0xab, 0x50, 0x7b, 0x1f, 0x53, 0x3e, 0x4e, 0xb1, 0xc9, 0x02, 0x3f, 0x81, 0xf5, 0x2a, 0x3c, 0xe5, 0xb7, 0x03, 0x0d, 0x4e, 0x45, 0x7c, 0x7c, 0x0e, 0x3d, 0x03, 0xc2, 0x21, 0x2c, 0xf5, 0xa9, 0xfc, 0x26, 0x66, 0x92, 0x1a, 0x93, 0x3b, 0xd0, 0x70, 0x09, 0xe1, 0x54, 0x08, 0x6d, 0xb4, 0xaa, 0x62, 0x2f, 0xd9, 0x73, 0x0c, 0xe8, 0xf3, 0xa2, 0x76, 0x0f, 0x96, 0x73, 0x7b, 0x29, 0xe7, 0x3b, 0xb0, 0xe0, 0x31, 0x21, 0xf5, 0xdb, 0x59, 0x53, 0xdf, 0xae, 0xa1, 0x30, 0x87, 0x82, 0x60, 0x06, 0xcb, 0x07, 0x23, 0x3f, 0x7a, 0xce, 0x09, 0xe5, 0xff, 0x08, 0xe7, 0xff, 0xc1, 0x4a, 0xc1, 0x60, 0x1e, 0xfe, 0x92, 0xbb, 0xde, 0x3b, 0x3f, 0x3c, 0xca, 0x73, 0x0b, 0x8c, 0x68, 0x40, 0xf0, 0x2f, 0x16, 0x34, 0x52, 0xbb, 0xe8, 0x1a, 0x74, 0x84, 0xe4, 0x94, 0xca, 0x61, 0x91, 0x65, 0xd3, 0x69, 0x27, 0x52, 0x03, 0x43, 0x30, 0xef, 0x99, 0x32, 0xd7, 0x74, 0xf4, 0xb7, 0x0a, 0x00, 0x21, 0x5d, 0x49, 0xd3, 0x7c, 0x48, 0x16, 0x2a, 0x13, 0x3c, 0x16, 0x87, 0x92, 0x8f, 0x4d, 0x26, 0xa4, 0x4b, 0x74, 0x11, 0x16, 0x3e, 0xfa, 0xd1, 0xd0, 0x63, 0x84, 0xea, 0x44, 0xa8, 0x39, 0x8d, 0x8f, 0x7e, 0xd4, 0x63, 0x84, 0xe2, 0x57, 0x50, 0xd3, 0xae, 0x44, 0xdb, 0xd0, 0xf6, 0x62, 0xce, 0x69, 0xe8, 0x8d, 0x13, 0x60, 0xc2, 0x66, 0xd1, 0x08, 0x15, 0x5a, 0x19, 0x8e, 0x43, 0x5f, 0x0a, 0xcd, 0x66, 0xce, 0x49, 0x16, 0x4a, 0x1a, 0xba, 0x21, 0x13, 0x9a, 0x4e, 0xcd, 0x49, 0x16, 0xb8, 0x0f, 0x9b, 0x7d, 0x2a, 0x0f, 0xe2, 0x28, 0x62, 0x5c, 0x52, 0xd2, 0x4b, 0xf4, 0xf8, 0x34, 0x8f, 0xcb, 0x6b, 0xd0, 0x29, 0x99, 0x34, 0x05, 0xa3, 0x5d, 0xb4, 0x29, 0xf0, 0xf7, 0x70, 0xb1, 0x97, 0x09, 0xc2, 0x13, 0xca, 0x85, 0xcf, 0x42, 0xf3, 0xc8, 0xd7, 0x61, 0xfe, 0x2d, 0x67, 0xc1, 0x19, 0x31, 0xa2, 0xf7, 0x55, 0xc9, 0x93, 0x2c, 0xb9, 0x58, 0xe2, 0xc9, 0xba, 0x64, 0xda, 0x01, 0x7f, 0x59, 0xd0, 0xe9, 0x71, 0x4a, 0x7c, 0x55, 0xaf, 0xc9, 0x20, 0x7c, 0xcb, 0xd0, 0x6d, 0x40, 0x9e, 0x96, 0x0c, 0x3d, 0x97, 0x93, 0x61, 0x18, 0x07, 0x6f, 0x28, 0x4f, 0xfd, 0xb1, 0xec, 0x65, 0xd8, 0xaf, 0xb5, 0x1c, 0x5d, 0x87, 0xa5, 0x22, 0xda, 0x3b, 0x39, 0x49, 0x5b, 0x52, 0x3b, 0x87, 0xf6, 0x4e, 0x4e, 0xd0, 0xff, 0x61, 0xa3, 0x88, 0xa3, 0x1f, 0x22, 0x9f, 0xeb, 0xf2, 0x39, 0x1c, 0x53, 0x97, 0xa7, 0xbe, 0xeb, 0xe6, 0x67, 0xf6, 0x33, 0xc0, 0x77, 0xd4, 0xe5, 0xe8, 0x11, 0x5c, 0x9a, 0x72, 0x3c, 0x60, 0xa1, 0x1c, 0xe9, 0x27, 0xaf, 0x39, 0x17, 0x27, 0x9d, 0x7f, 0xa6, 0x00, 0x78, 0x0c, 0xed, 0xde, 0xc8, 0xe5, 0x47, 0x59, 0x4e, 0xff, 0x07, 0xea, 0x6e, 0xa0, 0x22, 0xe4, 0x0c, 0xe7, 0xa5, 0x08, 0xf4, 0x10, 0x5a, 0x05, 0xeb, 0x69, 0xc3, 0xdc, 0x28, 0x67, 0x48, 0xc9, 0x89, 0x0e, 0xe4, 0x4c, 0xf0, 0x7d, 0xe8, 0x18, 0xd3, 0xf9, 0xd3, 0x4b, 0xee, 0x86, 0xc2, 0xf5, 0xf4, 0x15, 0xb2, 0x64, 0x69, 0x17, 0xa4, 0x03, 0x82, 0x7f, 0x80, 0xa6, 0xce, 0x30, 0x3d, 0x13, 0x98, 0x6e, 0x6d, 0x9d, 0xdb, 0xad, 0x55, 0x54, 0xa8, 0xca, 0x90, 0xf2, 0x9c, 0x18, 0x15, 0x6a, 0x1f, 0xff, 0x34, 0x0b, 0x2d, 0x93, 0xc2, 0xf1, 0xb1, 0x54, 0x89, 0xc2, 0xd4, 0x32, 0x27, 0xd4, 0xd0, 0xeb, 0x01, 0x41, 0xf7, 0x60, 0x55, 0x8c, 0xfc, 0x28, 0x52, 0xb9, 0x5d, 0x4c, 0xf2, 0x24, 0x9a, 0x90, 0xd9, 0x7b, 0x99, 0x25, 0x3b, 0xba, 0x0f, 0xed, 0xec, 0x84, 0x66, 0x33, 0x37, 0x95, 0xcd, 0xa2, 0x01, 0xf6, 0x98, 0x90, 0xe8, 0x11, 0x2c, 0x67, 0x07, 0x4d, 0x6d, 0x98, 0x3f, 0xa3, 0x82, 0x2d, 0x19, 0xb4, 0xa9, 0x19, 0xb7, 0x4d, 0x25, 0xab, 0xe9, 0x4a, 0xb6, 0x5e, 0x3a, 0x95, 0x39, 0xd4, 0x94, 0x32, 0x02, 0x97, 0x0e, 0x68, 0x48, 0xb4, 0xbc, 0xc7, 0xc2, 0xb7, 0x3e, 0x0f, 0x74, 0xd8, 0x14, 0xda, 0x0d, 0x0d, 0x5c, 0xff, 0xd8, 0xb4, 0x1b, 0xbd, 0x40, 0x3b, 0x50, 0xd3, 0xae, 0x49, 0x7d, 0xdc, 0x3d, 0x6d, 0x23, 0xf1, 0xa9, 0x93, 0xc0, 0xf0, 0x9f, 0x16, 0xac, 0xbc, 0x38, 0x76, 0x3d, 0x5a, 0xaa, 0xd1, 0x53, 0x27, 0x91, 0x6d, 0x68, 0xeb, 0x0d, 0x53, 0x0a, 0x52, 0x3f, 0x2f, 0x2a, 0xa1, 0xa9, 0x06, 0xc5, 0x0a, 0x3f, 0xf7, 0x29, 0x15, 0x3e, 0xbb, 0x49, 0xad, 0x78, 0x93, 0x4a, 0x6c, 0xd7, 0x3f, 0x2f, 0xb6, 0x1f, 0x03, 0x2a, 0x5e, 0x2b, 0x6b, 0xb9, 0xa9, 0x77, 0xac, 0x4f, 0xf3, 0xce, 0x0e, 0x34, 0xf7, 0x88, 0x71, 0xca, 0x55, 0x58, 0xf4, 0x58, 0x28, 0xe9, 0x07, 0x39, 0x7c, 0x47, 0xc7, 0xa6, 0x2a, 0xb6, 0x52, 0xd9, 0x57, 0x74, 0x2c, 0xf0, 0x5d, 0x00, 0x85, 0x4f, 0xad, 0x5d, 0x85, 0x39, 0x97, 0x98, 0xe6, 0xbe, 0x54, 0xf1, 0x81, 0xa3, 0xf6, 0xf0, 0x03, 0x98, 0xdd, 0x23, 0x4a, 0xb3, 0x62, 0xce, 0xa9, 0x27, 0x87, 0x31, 0x37, 0x2f, 0xda, 0x32, 0xb2, 0x43, 0x7e, 0xac, 0xfa, 0x8d, 0xb2, 0x62, 0xfa, 0x8d, 0xfa, 0xde, 0xfd, 0xc3, 0x82, 0x96, 0xca, 0xb0, 0x03, 0xca, 0x4f, 0x7c, 0x8f, 0xa2, 0x87, 0xba, 0x8b, 0xe9, 0xa4, 0xdc, 0xa8, 0x7a, 0xbc, 0x30, 0x78, 0xdb, 0xe5, 0x50, 0x4f, 0x26, 0xd3, 0x19, 0xf4, 0x00, 0x1a, 0xe9, 0x74, 0x5c, 0x39, 0x5d, 0x9e, 0x99, 0xed, 0x95, 0x53, 0x19, 0x8e, 0x67, 0xd0, 0x97, 0xd0, 0xcc, 0xe6, 0x70, 0x74, 0xf9, 0xb4, 0xfe, 0xa2, 0x82, 0x89, 0xe6, 0x77, 0x7f, 0xb6, 0x60, 0xad, 0x3c, 0xbf, 0x9a, 0x6b, 0xfd, 0x08, 0xff, 0x9a, 0x30, 0xdc, 0xa2, 0x7f, 0x97, 0xd4, 0x4c, 0x1f, 0xab, 0xed, 0x1b, 0xe7, 0x03, 0x93, 0x07, 0x53, 0x2c, 0x66, 0x61, 0x2d, 0x1d, 0xbc, 0x7a, 0xae, 0x74, 0x8f, 0xd9, 0x91, 0x61, 0xd1, 0x87, 0xc5, 0xe2, 0x94, 0x89, 0x26, 0xdc, 0xc2, 0xbe, 0x7a, 0xca, 0x52, 0x75, 0xe8, 0xc3, 0x33, 0xe8, 0x31, 0x40, 0x3e, 0x64, 0xa2, 0xcd, 0xaa, 0xab, 0xcb, 0xd3, 0xa7, 0x3d, 0x71, 0x26, 0xc4, 0x33, 0xe8, 0x35, 0x74, 0xca, 0x63, 0x25, 0xc2, 0x25, 0xe4, 0xc4, 0x11, 0xd5, 0xde, 0x3e, 0x13, 0x93, 0x79, 0xe1, 0x57, 0x0b, 0x96, 0x0e, 0xd2, 0xe2, 0x65, 0xee, 0x3f, 0x80, 0x05, 0x33, 0x0d, 0xa2, 0x4b, 0x55, 0xd2, 0xc5, 0xa1, 0xd4, 0xbe, 0x3c, 0x65, 0x37, 0xf3, 0xc0, 0x53, 0x68, 0x66, 0x43, 0x5a, 0x25, 0x58, 0xaa, 0xd3, 0xa2, 0xbd, 0x39, 0x6d, 0x3b, 0x23, 0xfb, 0x9b, 0x05, 0x4b, 0xa6, 0xf4, 0x18, 0xb2, 0xaf, 0x61, 0x7d, 0xf2, 0x90, 0x33, 0xf1, 0xd9, 0x6e, 0x55, 0x09, 0x9f, 0x31, 0x1d, 0xe1, 0x19, 0xd4, 0x87, 0x46, 0x32, 0xf0, 0x48, 0x74, 0xbd, 0x9c, 0x0b, 0xd3, 0xc6, 0x21, 0x7b, 0x42, 0x73, 0xc1, 0x33, 0xbb, 0x87, 0xd0, 0x79, 0xe1, 0x8e, 0x03, 0x1a, 0x66, 0x19, 0xdc, 0x83, 0x7a, 0xd2, 0x91, 0x91, 0x5d, 0xd6, 0x5c, 0x9c, 0x10, 0xec, 0x8d, 0x89, 0x7b, 0x99, 0x43, 0x46, 0xb0, 0xb8, 0xaf, 0x2a, 0xa8, 0x51, 0xfa, 0x4a, 0xfd, 0x60, 0x99, 0xd0, 0x48, 0xd0, 0xcd, 0x4a, 0x34, 0x4c, 0x6f, 0x36, 0x53, 0x72, 0xf6, 0x0d, 0x2c, 0xf5, 0x46, 0xd4, 0x7b, 0xc7, 0xe2, 0xec, 0x06, 0xcf, 0x01, 0xf2, 0xba, 0x5b, 0x89, 0xee, 0x53, 0x7d, 0xc6, 0xbe, 0x32, 0x75, 0x3f, 0xbb, 0xcd, 0x13, 0x55, 0x82, 0x8d, 0xf6, 0x07, 0x50, 0xef, 0xab, 0x19, 0x5c, 0xa0, 0xf5, 0x6a, 0x39, 0x4d, 0x35, 0x5e, 0x38, 0x25, 0x37, 0x9a, 0xde, 0xd4, 0xf5, 0x9f, 0x1b, 0xff, 0xfd, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xb2, 0xa0, 0x6e, 0x6c, 0xea, 0x10, 0x00, 0x00, } ================================================ FILE: microservices-demo/src/shippingservice/genproto.sh ================================================ #!/bin/bash -eu # # Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # [START gke_shippingservice_genproto] PATH=$PATH:$GOPATH/bin protodir=../../pb protoc --go_out=plugins=grpc:genproto -I $protodir $protodir/demo.proto # [END gke_shippingservice_genproto] ================================================ FILE: microservices-demo/src/shippingservice/go.mod ================================================ module github.com/GoogleCloudPlatform/microservices-demo/src/shippingservice go 1.18 require ( cloud.google.com/go/profiler v0.3.0 contrib.go.opencensus.io/exporter/jaeger v0.2.1 contrib.go.opencensus.io/exporter/stackdriver v0.13.12 github.com/golang/protobuf v1.5.2 github.com/sirupsen/logrus v1.8.1 go.opencensus.io v0.23.0 golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b google.golang.org/grpc v1.48.0 ) require ( cloud.google.com/go v0.100.2 // indirect cloud.google.com/go/compute v1.6.1 // indirect cloud.google.com/go/monitoring v1.1.0 // indirect cloud.google.com/go/trace v1.0.0 // indirect github.com/aws/aws-sdk-go v1.43.31 // indirect github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect github.com/cespare/xxhash/v2 v2.1.1 // indirect github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 // indirect github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 // indirect github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 // indirect github.com/envoyproxy/protoc-gen-validate v0.1.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/go-cmp v0.5.8 // indirect github.com/google/pprof v0.0.0-20220412212628-83db2b799d1f // indirect github.com/googleapis/gax-go/v2 v2.4.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/prometheus/prometheus v2.5.0+incompatible // indirect github.com/uber/jaeger-client-go v2.25.0+incompatible // indirect golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect golang.org/x/text v0.3.7 // indirect google.golang.org/api v0.78.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335 // indirect google.golang.org/protobuf v1.28.0 // indirect ) ================================================ FILE: microservices-demo/src/shippingservice/go.sum ================================================ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go v0.99.0 h1:y/cM2iqGgGi5D5DQZl6D9STN/3dR/Vx5Mp8s752oJTY= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= cloud.google.com/go/compute v1.5.0 h1:b1zWmYuuHz7gO9kDcM/EpHGr06UgsYNRpNJzI2kFiLM= cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= cloud.google.com/go/compute v1.6.1 h1:2sMmt8prCn7DPaG4Pmh0N3Inmc8cT8ae5k1M6VJ9Wqc= cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/monitoring v1.1.0 h1:ZnyNdf/XRcynMmKzRSNTOdOyYPs6G7do1l2D2hIvIKo= cloud.google.com/go/monitoring v1.1.0/go.mod h1:L81pzz7HKn14QCMaCs6NTQkdBnE87TElyanS95vIcl4= cloud.google.com/go/profiler v0.1.1 h1:seMHZtcgOwZXAOKDZuW2sN3u1yKjYG19dUkElb4mbcQ= cloud.google.com/go/profiler v0.1.1/go.mod h1:zG22vSCuJKJMvIlLpX3FhNjOsifaoLdPAYc4yLw5Iw4= cloud.google.com/go/profiler v0.3.0 h1:R6y/xAeifaUXxd2x6w+jIwKxoKl8Cv5HJvcvASTPWJo= cloud.google.com/go/profiler v0.3.0/go.mod h1:9wYk9eY4iZHsev8TQb61kh3wiOiSyz/xOYixWPzweCU= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= cloud.google.com/go/trace v1.0.0 h1:laKx2y7IWMjguCe5zZx6n7qLtREk4kyE69SXVC0VSN8= cloud.google.com/go/trace v1.0.0/go.mod h1:4iErSByzxkyHWzzlAj63/Gmjz0NH1ASqhJguHpGcr6A= contrib.go.opencensus.io/exporter/jaeger v0.2.1 h1:yGBYzYMewVL0yO9qqJv3Z5+IRhPdU7e9o/2oKpX4YvI= contrib.go.opencensus.io/exporter/jaeger v0.2.1/go.mod h1:Y8IsLgdxqh1QxYxPC5IgXVmBaeLUeQFfBeBi9PbeZd0= contrib.go.opencensus.io/exporter/stackdriver v0.13.10 h1:a9+GZPUe+ONKUwULjlEOucMMG0qfSCCenlji0Nhqbys= contrib.go.opencensus.io/exporter/stackdriver v0.13.10/go.mod h1:I5htMbyta491eUxufwwZPQdcKvvgzMB4O9ni41YnIM8= contrib.go.opencensus.io/exporter/stackdriver v0.13.12 h1:bjBKzIf7/TAkxd7L2utGaLM78bmUWlCval5K9UeElbY= contrib.go.opencensus.io/exporter/stackdriver v0.13.12/go.mod h1:mmxnWlrvrFdpiOHOhxBaVi1rkc0WOqhgfknj4Yg0SeQ= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/aws/aws-sdk-go v1.37.0 h1:GzFnhOIsrGyQ69s7VgqtrG2BG8v7X7vwB3Xpbd/DBBk= github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.43.31 h1:yJZIr8nMV1hXjAvvOLUFqZRJcHV7udPQBfhJqawDzI0= github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 h1:hzAQntlaYRkVSFEfj9OTWlVV1H155FMD8BTKktLv0QI= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 h1:zH8ljVhhq7yC0MIeUL/IviMtY8hx2mK8cN9wEYb8ggw= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021 h1:fP+fF0up6oPY49OrjPrhIJ8yQfdIM85NXMLkMg1EXVs= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 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.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= 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/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20211008130755-947d60d73cc0 h1:zHs+jv3LO743/zFGcByu2KmpbliCU2AhjcGgrdTwSG4= github.com/google/pprof v0.0.0-20211008130755-947d60d73cc0/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= github.com/google/pprof v0.0.0-20220412212628-83db2b799d1f h1:VrKTY4lquiy1oJzVZgXrauku9Jx9P+POv/gTLakG4Wk= github.com/google/pprof v0.0.0-20220412212628-83db2b799d1f/go.mod h1:Pt31oes+eGImORns3McJn8zHefuQl2rG8l6xQjGYB4U= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= github.com/googleapis/gax-go/v2 v2.2.0 h1:s7jOdKSaksJVOxE0Y/S32otcfiP+UQ0cL8/GTKaONwE= github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= github.com/googleapis/gax-go/v2 v2.4.0 h1:dS9eYAjhrE2RjmzYw2XAPvcXfmcQLtFEQWn0CR82awk= github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/prometheus v2.5.0+incompatible h1:7QPitgO2kOFG8ecuRn9O/4L9+10He72rVRJvMXrE9Hg= github.com/prometheus/prometheus v2.5.0+incompatible/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/uber/jaeger-client-go v2.25.0+incompatible h1:IxcNZ7WRY1Y3G4poYlx24szfsn/3LvK9QHCq9oQw8+U= github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 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.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220403103023-749bd193bc2b h1:vI32FkLJNAWtGD4BwkThwEy6XS7ZLLMHkSkYfF8M0W0= golang.org/x/net v0.0.0-20220403103023-749bd193bc2b/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220420153159-1850ba15e1be h1:yx80W7nvY5ySWpaU8UWaj5o9e23YgO9BRhQol7Lc+JI= golang.org/x/net v0.0.0-20220420153159-1850ba15e1be/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b h1:3ogNYyK4oIQdIKzTu68hQrr4iuVxF3AxKl9Aj/eDrw0= golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220805013720-a33c5aa5df48 h1:N9Vc/rorQUDes6B9CNdIxAn5jODGj2wzfrei2x4wNj4= golang.org/x/net v0.0.0-20220805013720-a33c5aa5df48/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220809012201-f428fae20770 h1:dIi4qVdvjZEjiMDv7vhokAZNGnz3kepwuXqFKYDdDMs= golang.org/x/net v0.0.0-20220809012201-f428fae20770/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220809184613-07c6da5e1ced h1:3dYNDff0VT5xj+mbj2XucFst9WKk6PdGOrb9n+SbIvw= golang.org/x/net v0.0.0-20220809184613-07c6da5e1ced/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E= golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/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-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886 h1:eJv7u3ksNXoLbGSKuv2s/SIO4tJVxc/A+MTpzxDgz/Q= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba h1:AyHWHCBVlIYI5rgEM3o+1PLd0sLPcIAoaUckGQMaWtw= golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E= google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= google.golang.org/api v0.61.0 h1:TXXKS1slM3b2bZNJwD5DV/Tp6/M2cLzLOLh9PjDhrw8= google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= google.golang.org/api v0.74.0 h1:ExR2D+5TYIrMphWgs5JCgwRhEDlPDXXrLwHHMgPHTXE= google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= google.golang.org/api v0.78.0 h1:5ewPyCwP43C3i8B6C2Kb+eVAevbnke2xR8VbcSWjS4I= google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210921142501-181ce0d877f6/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211018162055-cf77aa76bad2/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0 h1:c7yRRmuQiVMo+YppNj5MUREXUyc2lPo3DrtYMwaWQ28= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb h1:0m9wktIpOxGw+SSKmydXWB3Z3GTfcPP6+q75HCQa6HI= google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335 h1:2D0OT6tPVdrQTOnVe1VQjfJPTED6EZ7fdJ/f6Db6OsY= google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.43.0 h1:Eeu7bZtDZ2DpRCsLhUlcrLnvYaMK1Gz86a+hMVvELmM= google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.46.0 h1:oCjezcn6g6A75TGoKYBPgKmVBLexhYLM6MebdrPApP8= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= ================================================ FILE: microservices-demo/src/shippingservice/main.go ================================================ // Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "fmt" "net" "os" "time" "cloud.google.com/go/profiler" "contrib.go.opencensus.io/exporter/jaeger" "contrib.go.opencensus.io/exporter/stackdriver" "github.com/sirupsen/logrus" "go.opencensus.io/plugin/ocgrpc" "go.opencensus.io/stats/view" "go.opencensus.io/trace" "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/reflection" "google.golang.org/grpc/status" pb "github.com/GoogleCloudPlatform/microservices-demo/src/shippingservice/genproto" healthpb "google.golang.org/grpc/health/grpc_health_v1" ) const ( defaultPort = "50051" ) var log *logrus.Logger func init() { log = logrus.New() log.Level = logrus.DebugLevel log.Formatter = &logrus.JSONFormatter{ FieldMap: logrus.FieldMap{ logrus.FieldKeyTime: "timestamp", logrus.FieldKeyLevel: "severity", logrus.FieldKeyMsg: "message", }, TimestampFormat: time.RFC3339Nano, } log.Out = os.Stdout } func main() { if os.Getenv("DISABLE_TRACING") == "" { log.Info("Tracing enabled.") go initTracing() } else { log.Info("Tracing disabled.") } if os.Getenv("DISABLE_PROFILER") == "" { log.Info("Profiling enabled.") go initProfiling("shippingservice", "1.0.0") } else { log.Info("Profiling disabled.") } port := defaultPort if value, ok := os.LookupEnv("PORT"); ok { port = value } port = fmt.Sprintf(":%s", port) lis, err := net.Listen("tcp", port) if err != nil { log.Fatalf("failed to listen: %v", err) } var srv *grpc.Server if os.Getenv("DISABLE_STATS") == "" { log.Info("Stats enabled.") srv = grpc.NewServer(grpc.StatsHandler(&ocgrpc.ServerHandler{})) } else { log.Info("Stats disabled.") srv = grpc.NewServer() } svc := &server{} pb.RegisterShippingServiceServer(srv, svc) healthpb.RegisterHealthServer(srv, svc) log.Infof("Shipping Service listening on port %s", port) // Register reflection service on gRPC server. reflection.Register(srv) if err := srv.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } } // server controls RPC service responses. type server struct{} // Check is for health checking. func (s *server) Check(ctx context.Context, req *healthpb.HealthCheckRequest) (*healthpb.HealthCheckResponse, error) { return &healthpb.HealthCheckResponse{Status: healthpb.HealthCheckResponse_SERVING}, nil } func (s *server) Watch(req *healthpb.HealthCheckRequest, ws healthpb.Health_WatchServer) error { return status.Errorf(codes.Unimplemented, "health check via Watch not implemented") } // GetQuote produces a shipping quote (cost) in USD. func (s *server) GetQuote(ctx context.Context, in *pb.GetQuoteRequest) (*pb.GetQuoteResponse, error) { log.Info("[GetQuote] received request") defer log.Info("[GetQuote] completed request") // 1. Generate a quote based on the total number of items to be shipped. quote := CreateQuoteFromCount(0) // 2. Generate a response. return &pb.GetQuoteResponse{ CostUsd: &pb.Money{ CurrencyCode: "USD", Units: int64(quote.Dollars), Nanos: int32(quote.Cents * 10000000)}, }, nil } // ShipOrder mocks that the requested items will be shipped. // It supplies a tracking ID for notional lookup of shipment delivery status. func (s *server) ShipOrder(ctx context.Context, in *pb.ShipOrderRequest) (*pb.ShipOrderResponse, error) { log.Info("[ShipOrder] received request") defer log.Info("[ShipOrder] completed request") // 1. Create a Tracking ID baseAddress := fmt.Sprintf("%s, %s, %s", in.Address.StreetAddress, in.Address.City, in.Address.State) id := CreateTrackingId(baseAddress) // 2. Generate a response. return &pb.ShipOrderResponse{ TrackingId: id, }, nil } func initJaegerTracing() { svcAddr := os.Getenv("JAEGER_SERVICE_ADDR") if svcAddr == "" { log.Info("jaeger initialization disabled.") return } // Register the Jaeger exporter to be able to retrieve // the collected spans. exporter, err := jaeger.NewExporter(jaeger.Options{ Endpoint: fmt.Sprintf("http://%s", svcAddr), Process: jaeger.Process{ ServiceName: "shippingservice", }, }) if err != nil { log.Fatal(err) } trace.RegisterExporter(exporter) log.Info("jaeger initialization completed.") } func initStats(exporter *stackdriver.Exporter) { view.SetReportingPeriod(60 * time.Second) view.RegisterExporter(exporter) if err := view.Register(ocgrpc.DefaultServerViews...); err != nil { log.Warn("Error registering default server views") } else { log.Info("Registered default server views") } } func initStackdriverTracing() { // TODO(ahmetb) this method is duplicated in other microservices using Go // since they are not sharing packages. for i := 1; i <= 3; i++ { exporter, err := stackdriver.NewExporter(stackdriver.Options{}) if err != nil { log.Warnf("failed to initialize Stackdriver exporter: %+v", err) } else { trace.RegisterExporter(exporter) trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()}) log.Info("registered Stackdriver tracing") // Register the views to collect server stats. initStats(exporter) return } d := time.Second * 10 * time.Duration(i) log.Infof("sleeping %v to retry initializing Stackdriver exporter", d) time.Sleep(d) } log.Warn("could not initialize Stackdriver exporter after retrying, giving up") } func initTracing() { initJaegerTracing() initStackdriverTracing() } func initProfiling(service, version string) { // TODO(ahmetb) this method is duplicated in other microservices using Go // since they are not sharing packages. for i := 1; i <= 3; i++ { if err := profiler.Start(profiler.Config{ Service: service, ServiceVersion: version, // ProjectID must be set if not running on GCP. // ProjectID: "my-project", }); err != nil { log.Warnf("failed to start profiler: %+v", err) } else { log.Info("started Stackdriver profiler") return } d := time.Second * 10 * time.Duration(i) log.Infof("sleeping %v to retry initializing Stackdriver profiler", d) time.Sleep(d) } log.Warn("could not initialize Stackdriver profiler after retrying, giving up") } ================================================ FILE: microservices-demo/src/shippingservice/quote.go ================================================ // Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "fmt" "math" ) // Quote represents a currency value. type Quote struct { Dollars uint32 Cents uint32 } // String representation of the Quote. func (q Quote) String() string { return fmt.Sprintf("$%d.%d", q.Dollars, q.Cents) } // CreateQuoteFromCount takes a number of items and returns a Price struct. func CreateQuoteFromCount(count int) Quote { return CreateQuoteFromFloat(8.99) } // CreateQuoteFromFloat takes a price represented as a float and creates a Price struct. func CreateQuoteFromFloat(value float64) Quote { units, fraction := math.Modf(value) return Quote{ uint32(units), uint32(math.Trunc(fraction * 100)), } } ================================================ FILE: microservices-demo/src/shippingservice/shippingservice_test.go ================================================ // Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "testing" "golang.org/x/net/context" pb "github.com/GoogleCloudPlatform/microservices-demo/src/shippingservice/genproto" ) // TestGetQuote is a basic check on the GetQuote RPC service. func TestGetQuote(t *testing.T) { s := server{} // A basic test case to test logic and protobuf interactions. req := &pb.GetQuoteRequest{ Address: &pb.Address{ StreetAddress: "Muffin Man", City: "London", State: "", Country: "England", }, Items: []*pb.CartItem{ { ProductId: "23", Quantity: 1, }, { ProductId: "46", Quantity: 3, }, }, } res, err := s.GetQuote(context.Background(), req) if err != nil { t.Errorf("TestGetQuote (%v) failed", err) } if res.CostUsd.GetUnits() != 8 || res.CostUsd.GetNanos() != 990000000 { t.Errorf("TestGetQuote: Quote value '%d.%d' does not match expected '%s'", res.CostUsd.GetUnits(), res.CostUsd.GetNanos(), "11.220000000") } } // TestShipOrder is a basic check on the ShipOrder RPC service. func TestShipOrder(t *testing.T) { s := server{} // A basic test case to test logic and protobuf interactions. req := &pb.ShipOrderRequest{ Address: &pb.Address{ StreetAddress: "Muffin Man", City: "London", State: "", Country: "England", }, Items: []*pb.CartItem{ { ProductId: "23", Quantity: 1, }, { ProductId: "46", Quantity: 3, }, }, } res, err := s.ShipOrder(context.Background(), req) if err != nil { t.Errorf("TestShipOrder (%v) failed", err) } // @todo improve quality of this test to check for a pattern such as '[A-Z]{2}-\d+-\d+'. if len(res.TrackingId) != 18 { t.Errorf("TestShipOrder: Tracking ID is malformed - has %d characters, %d expected", len(res.TrackingId), 18) } } ================================================ FILE: microservices-demo/src/shippingservice/tracker.go ================================================ // Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "fmt" "math/rand" "time" ) // seeded determines if the random number generator is ready. var seeded bool = false // CreateTrackingId generates a tracking ID. func CreateTrackingId(salt string) string { if !seeded { rand.Seed(time.Now().UnixNano()) seeded = true } return fmt.Sprintf("%c%c-%d%s-%d%s", getRandomLetterCode(), getRandomLetterCode(), len(salt), getRandomNumber(3), len(salt)/2, getRandomNumber(7), ) } // getRandomLetterCode generates a code point value for a capital letter. func getRandomLetterCode() uint32 { return 65 + uint32(rand.Intn(25)) } // getRandomNumber generates a string representation of a number with the requested number of digits. func getRandomNumber(digits int) string { str := "" for i := 0; i < digits; i++ { str = fmt.Sprintf("%s%d", str, rand.Intn(10)) } return str } ================================================ FILE: microservices-demo/tilt-resources/dev/tilt_config.json ================================================ { "allowed_contexts": [ "do-nyc1-microservices-demo-dev" ], "default_registry": "registry.digitalocean.com/microservices-demo", "environment": "dev", "microservices": [ "cartservice", "checkoutservice", "currencyservice", "emailservice", "frontend", "paymentservice", "productcatalogservice", "recommendationservice", "redis", "shippingservice" ], "namespace": "microservices-demo-dev", "port_forwards": [ "frontend:9090" ] } ================================================ FILE: microservices-demo/tilt-resources/local/tilt_config.json ================================================ { "allowed_contexts": [ "docker-desktop" ], "default_registry": "", "environment": "local", "microservices": [ "cartservice", "checkoutservice", "currencyservice", "emailservice", "frontend", "paymentservice", "productcatalogservice", "recommendationservice", "redis", "shippingservice" ], "namespace": "microservices-demo-local", "port_forwards": [ "frontend:9090" ] } ================================================ FILE: podinfo-example/README.md ================================================ # Overview [Podinfo](https://github.com/stefanprodan/podinfo) is a tiny web application made with Go that showcases best practices of running microservices in Kubernetes. Podinfo is used by CNCF projects like [Flux](https://github.com/fluxcd/flux2) and [Flagger](https://github.com/fluxcd/flagger) for end-to-end testing and workshops. Specifications: - Health checks (readiness and liveness). - Graceful shutdown on interrupt signals. - File watcher for secrets and configmaps. - Instrumented with Prometheus and Open Telemetry. - Structured logging with zap. - 12-factor app with viper. - Fault injection (random errors and latency). - Swagger docs. - CUE, Helm and Kustomize installers. - End-to-End testing with Kubernetes Kind and Helm. - Kustomize testing with GitHub Actions and Open Policy Agent. - Multi-arch container image with Docker buildx and Github Actions. - Container image signing with Sigstore cosign. - CVE scanning with Trivy. Please visit the [Podinfo](https://github.com/stefanprodan/podinfo) documentation page for more details. ## Requirements To complete all steps and deploy the `Podinfo` sample application, you will need: 1. A [DOKS](https://docs.digitalocean.com/products/kubernetes/quickstart) cluster configured and running. 2. Latest [Kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) version for Kubernetes interaction. 3. [Git](https://git-scm.com/downloads) client for interacting with the [kubernetes-sample-apps](https://github.com/digitalocean/kubernetes-sample-apps) repository. ## Deploying to Kubernetes The [kustomization manifest](kustomize/kustomization.yaml) provided in this repository will get you started with deploying the `Podinfo` application Kubernetes resources. First, you need to clone this repository: ```shell git clone https://github.com/digitalocean/kubernetes-sample-apps.git ``` Then, change directory to your local copy: ```shell cd kubernetes-sample-apps ``` Now, create Podinfo sample application Kubernetes resources using the kubectl kustomize option (`-k` flag): ```shell kubectl apply -k podinfo-example/kustomize ``` The output looks similar to: ```text namespace/podinfo created service/podinfo created deployment.apps/podinfo created horizontalpodautoscaler.autoscaling/podinfo created ``` If everything went well, you should have a new Kubernetes namespace created named `podinfo`. Inside the new namespace, you can inspect all resources created by the kustomization manifest from the sample apps repository (all Podinfo application pods should be up and running): ```shell kubectl get all -n podinfo ``` The output looks similar to: ```text NAME READY STATUS RESTARTS AGE pod/podinfo-df7bb55d4-dhrpx 1/1 Running 0 107s pod/podinfo-df7bb55d4-jhq7m 1/1 Running 0 91s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/podinfo ClusterIP 10.245.152.36 9898/TCP,9999/TCP 109s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/podinfo 2/2 2 2 108s NAME DESIRED CURRENT READY AGE replicaset.apps/podinfo-df7bb55d4 2 2 2 109s NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE horizontalpodautoscaler.autoscaling/podinfo Deployment/podinfo /99% 2 4 2 109s ``` Finally, port-forward the `podinfo` service using `kubectl`: ```shell kubectl port-forward service/podinfo -n podinfo 9898:9898 ``` Open a web browser and point to [localhost:9898](http://localhost:9898/). You should see the Podinfo application welcome page: ![Podinfo Welcome Page](assets/images/podinfo-welcome-page.png) ## Cleaning Up To clean up all Kubernetes resources created by the Podinfo sample application, below command must be used: ```shell kubectl delete ns podinfo ``` **Note:** Kubectl kustomize subcommand has a delete option that can be used - `kubectl delete -k podinfo-example/kustomize`. But, it won't work well in this case because if the namespace is deleted first then the remaining operations will fail. ================================================ FILE: podinfo-example/kustomize/kustomization.yaml ================================================ ## Podinfo Sample Application Kustomization apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization # Making sure all resources used in this tutorial are created in a dedicated namespace # Also specific annotations are added for later identification namespace: podinfo commonAnnotations: provider: kubernetes-sample-apps # Podinfo resources (namespace, services, deployments, etc) resources: - resources/namespace.yaml - github.com/stefanprodan/podinfo/kustomize ================================================ FILE: podinfo-example/kustomize/resources/namespace.yaml ================================================ apiVersion: v1 kind: Namespace metadata: name: podinfo