diff --git a/.github/README.md b/.github/README.md deleted file mode 100644 index 758c6329d..000000000 --- a/.github/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# GitHub configurations and bots - -The repo defines templates for new [pull requests], [bugs] and [features]. -The configurations include the following bots: - -* [Blunderbuss]: Auto-assigner of a Github users to pull requests and issues -* [Header checker]: Presubmit check that all files with configured extensions have the proper copyright header -* [Conventional commit lint]: Presubmit check that all commit messages in PR follow the [convention] -* [Snippets]: Scanner for possible code sample snippets to integrate them into Google Cloud documentation -* [Trusted contributors]: Integrator for Github application trusted access to the repo - -For information about the customized workflow, see [workfows/README] - -[pull requests]: ./PULL_REQUEST_TEMPLATE.md -[bugs]: ISSUE_TEMPLATE/bug_report.md -[features]: ISSUE_TEMPLATE/feature_request.md -[blunderbuss]: https://github.com/googleapis/repo-automation-bots/tree/main/packages/blunderbuss -[header checker]: https://github.com/googleapis/repo-automation-bots/tree/main/packages/header-checker-lint -[workfows/README]: workflows/README.md -[conventional commit lint]: https://github.com/googleapis/repo-automation-bots/tree/main/packages/conventional-commit-lint -[convention]: https://www.conventionalcommits.org/en/v1.0.0/ -[snippets]: https://github.com/googleapis/repo-automation-bots/tree/main/packages/snippet-bot -[trusted contributors]: https://github.com/googleapis/repo-automation-bots/tree/main/packages/trusted-contribution diff --git a/.github/conventional-commit-lint.yaml b/.github/conventional-commit-lint.yaml index b82db082e..adc7330c5 100644 --- a/.github/conventional-commit-lint.yaml +++ b/.github/conventional-commit-lint.yaml @@ -1,5 +1,19 @@ +# Copyright 2023 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. + # Presubmit test that ensures that commit messages are build following convention # https://github.com/googleapis/repo-automation-bots/tree/main/packages/conventional-commit-lint enabled: true -always_check_pr_title: true +always_check_pr_title: false diff --git a/.github/header-checker-lint.yml b/.github/header-checker-lint.yml index 5a7773b8c..b8a9efd23 100644 --- a/.github/header-checker-lint.yml +++ b/.github/header-checker-lint.yml @@ -1,3 +1,17 @@ +# Copyright 2023 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. + # Presubmit test that ensures that source files contain valid license headers # https://github.com/googleapis/repo-automation-bots/tree/main/packages/header-checker-lint # Install: https://github.com/apps/license-header-lint-gcf diff --git a/renovate.json b/.github/renovate.json similarity index 100% rename from renovate.json rename to .github/renovate.json diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 359ef5274..ac4b4ea5f 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -35,9 +35,9 @@ jobs: cancel-in-progress: true ``` -### Terraform Lint - [lint-terraform.yaml] +### Terraform workflow ([terraform.yaml]) -The workflow is triggered by changes to Terraform configurations used for provisioning Cloud Ops Sandbox: +The workflow is triggered by changes to Terraform configurations in the project: ```yaml on: @@ -46,19 +46,14 @@ on: - 'provisioning/terraform/**' ``` -It uses the [tflint] Github action. +It defines two jobs: -#### Handling skipped but required checks - -To allow using this workflow as a [required status check] the file [lint-terraform-other.yaml] is used. It defines the workflow with the same name that _does nothing_ when triggered for changes outside the Terraform configuration. +1. Linting that validates formatting and other rules and dependecies using [tflint] +2. End-to-end deployment that provisions Online Boutique demo app with Sandbox from scratch. +And destroys it afterward. -### End-to-end Deployment +#### End-to-end deployment steps -The workflow is triggered by pull request modifications (excluding a closure of the request) for branches `main` and branches with names starting with `milestone/` or `release/`. -The workflow is not triggered for changes to documentation or markdown files. -Permissions are updated to acquire the identity token from Google Cloud Identity service. See [blog] for more details. - -The workflow installs Google Cloud CLI to complete the list of required binaries (gcloud, git, kubectl). Then it triggers installation of Cloud Ops Sandbox using [install.sh] script. The deployment reuses the same GCS bucket to maintain Terraform state for all workflow executions but prefixes each one with the first 7 digits of SHA ( [`${{ github.sha }}`][sha] )of the commit. The installation is triggered with the following parameters: @@ -68,12 +63,54 @@ The installation is triggered with the following parameters: * Allowing deployment of the load generator * Disabling configuration of Anthos Service Mesh and deployment of Online Boutique ingress +#### Handling skipped but required checks + +The additional file [non-terraform.yaml] defines the workflow with the same name to support +the use of the workflow as [required status check]. +It is configured to run on any "non-terraform" changes, so the required workflow will always +guaranteed to terminate. + +### Required workflows + +The workflows triggered by pull request modifications (excluding a closure of the request) +are enforced on `main` and branches with names starting with `milestone/` or `release/`. + +### Running jobs that require Google Cloud authentication + +Jobs that need to authenticate vs. Google Cloud use keyless authentication method. +The method is described with more details in the [blog]. +Job permissions are updated to allow storing id token. +The workflow installs Google Cloud CLI to complete the list of required binaries (gcloud, git, kubectl). + +## GitHub configurations and bots + +The repo defines templates for new [pull requests], [bugs] and [features]. +The configurations include the following bots: + +* [Blunderbuss]: Auto-assigner of a Github users to pull requests and issues +* [Header checker]: Presubmit check that all files with configured extensions have the proper copyright header +* [Conventional commit lint]: Presubmit check that all commit messages in PR follow the [convention] +* [Snippets]: Scanner for possible code sample snippets to integrate them into Google Cloud documentation +* [Trusted contributors]: Integrator for Github application trusted access to the repo + +For information about the customized workflow, see [workfows/README] + [hosted]: https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners [bots]: ../README.md -[lint-terraform.yaml]: ./lint-terraform.yaml -[lint-terraform-other.yaml]: ./lint-terraform-other.yaml +[terraform.yaml]: ./terraform.yaml +[non-terraform.yaml]: ./non-terraform.yaml [tflint]: https://github.com/marketplace/actions/setup-tflint [blog]: https://cloud.google.com/blog/products/identity-security/enabling-keyless-authentication-from-github-actions [install.sh]: ../../provisioning/install.sh [sha]: https://docs.github.com/en/actions/learn-github-actions/contexts#github-context [required status check]: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/about-protected-branches#require-status-checks-before-merging +[pull requests]: ./PULL_REQUEST_TEMPLATE.md +[bugs]: ISSUE_TEMPLATE/bug_report.md +[features]: ISSUE_TEMPLATE/feature_request.md +[blunderbuss]: https://github.com/googleapis/repo-automation-bots/tree/main/packages/blunderbuss +[header checker]: https://github.com/googleapis/repo-automation-bots/tree/main/packages/header-checker-lint +[workfows/README]: workflows/README.md +[conventional commit lint]: https://github.com/googleapis/repo-automation-bots/tree/main/packages/conventional-commit-lint +[convention]: https://www.conventionalcommits.org/en/v1.0.0/ +[snippets]: https://github.com/googleapis/repo-automation-bots/tree/main/packages/snippet-bot +[trusted contributors]: https://github.com/googleapis/repo-automation-bots/tree/main/packages/trusted-contribution diff --git a/.github/workflows/lint-terraform-other.yaml b/.github/workflows/cli.yaml similarity index 67% rename from .github/workflows/lint-terraform-other.yaml rename to .github/workflows/cli.yaml index 8e35ee34d..add901672 100644 --- a/.github/workflows/lint-terraform-other.yaml +++ b/.github/workflows/cli.yaml @@ -11,19 +11,25 @@ # 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. +name: CLI -# allow use of the workflow as required status check when no changes in provisioning/terraform/** -# for details see https://github.com/orgs/community/discussions/49124 -name: terraform lint on: pull_request: types: [opened,synchronize,reopened] - paths-ignore: - - 'provisioning/terraform/**' jobs: - tflint: - name: "not terraform files" + + shellcheck: runs-on: ubuntu-latest + permissions: + contents: read + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + steps: - - run: 'echo "No terraform lint required"' + - name: Checkout source code + uses: actions/checkout@v3 + + - name: Check CLI script + run: shellcheck provisioning/sandboxctl diff --git a/.github/workflows/lint-terraform.yaml b/.github/workflows/lint-terraform.yaml deleted file mode 100644 index b2f1a23c7..000000000 --- a/.github/workflows/lint-terraform.yaml +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright 2023 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. - -name: terraform lint -on: - pull_request: - types: [opened,synchronize,reopened] - paths: - - 'provisioning/terraform/**' - -jobs: - tflint: - runs-on: ubuntu-latest - permissions: - contents: read - concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - - steps: - - name: Checkout source code - uses: actions/checkout@v3 - - - name: Terraform backend initialization - run: terraform -chdir=./provisioning/terraform/ init -backend=false - - - name: Cache plugin dir - uses: actions/cache@v3 - with: - path: ~/.tflint.d/plugins - key: tflint-${{ hashFiles('.tflint.hcl') }} - - - uses: terraform-linters/setup-tflint@v3 - name: Setup TFLint - with: - tflint_version: v0.45.0 - - - name: Show version - run: tflint --version - - - name: Init TFLint - run: tflint --init - env: - # https://github.com/terraform-linters/tflint/blob/master/docs/user-guide/plugins.md#avoiding-rate-limiting - GITHUB_TOKEN: ${{ github.token }} - - - name: Run TFLint - run: tflint -f compact --chdir ./provisioning/terraform diff --git a/.github/workflows/non-terraform.yaml b/.github/workflows/non-terraform.yaml new file mode 100644 index 000000000..96d0abf07 --- /dev/null +++ b/.github/workflows/non-terraform.yaml @@ -0,0 +1,43 @@ +# Copyright 2023 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. +name: Terraform + +on: + pull_request: + types: [opened,synchronize,reopened] + paths-ignore: + - 'provisioning/terraform/**' + + +jobs: + tflint: + permissions: + contents: read + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + + steps: + - run: 'echo "No work to do for non-terraform changes"' + + + e2e-deployment: + permissions: + contents: read + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + + steps: + - run: 'echo "No work to do for non-terraform changes"' diff --git a/.github/workflows/e2e-deployment.yaml b/.github/workflows/terraform.yaml similarity index 50% rename from .github/workflows/e2e-deployment.yaml rename to .github/workflows/terraform.yaml index 09344f4f6..611b8be42 100644 --- a/.github/workflows/e2e-deployment.yaml +++ b/.github/workflows/terraform.yaml @@ -11,22 +11,60 @@ # 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. +name: Terraform -name: end-to-end integration testing on: pull_request: types: [opened,synchronize,reopened] - branches: ["main","milestone/*","release/*"] - paths-ignore: - - 'docs/**' - - '**/*.md' - - '**/*.txt' - - '**/*.html' - - '**/*.css' + paths: + - 'provisioning/terraform/**' + jobs: + + tflint: + runs-on: ubuntu-latest + permissions: + contents: read + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + + steps: + - name: Checkout source code + uses: actions/checkout@v3 + + - name: Terraform backend initialization + run: terraform -chdir=./provisioning/terraform/ init -backend=false + + - name: Cache plugin dir + uses: actions/cache@v3 + with: + path: ~/.tflint.d/plugins + key: tflint-${{ hashFiles('.tflint.hcl') }} + + - name: Setup TFLint + uses: terraform-linters/setup-tflint@v3 + with: + tflint_version: v0.45.0 + + - name: Show version + run: tflint --version + + - name: Init TFLint + run: tflint --init + env: + # https://github.com/terraform-linters/tflint/blob/master/docs/user-guide/plugins.md#avoiding-rate-limiting + GITHUB_TOKEN: ${{ github.token }} + + - name: TF Linting + run: tflint -f compact --chdir ./provisioning/terraform + + - name: Linting convenience shell scripts + run: shellcheck provisioning/terraform/**/*.sh + e2e-deployment: - name: "provision and deploy Cloud Sandbox with Online Boutique" + needs: tflint runs-on: ubuntu-latest permissions: contents: 'read' @@ -36,46 +74,44 @@ jobs: cancel-in-progress: true steps: - - uses: actions/checkout@v3 - name: "checkout source code" + - name: Checkout source code + uses: actions/checkout@v3 - - id: 'auth' - name: "authenticate to Google Cloud" + - name: Authenticate to Google Cloud + id: 'auth' uses: google-github-actions/auth@v1 with: token_format: 'access_token' workload_identity_provider: ${{ secrets.E2E_IDENTITY_PROVIDER }} service_account: ${{ secrets.E2E_SERVICE_ACCOUNT }} - - name: "set up Cloud CLI" + - name: Setup GCloud CLI uses: google-github-actions/setup-gcloud@v1 with: install_components: 'gke-gcloud-auth-plugin' # select a zone in us-central1 region and use it to next steps as ${{ env.cluster_location }} - - name: "select deployment zone" + - name: Setup deployment location to random zone run: |- zones=("us-central1-a" "us-central1-b" "us-central1-c" "us-central1-f") selected_location=${zones[ $RANDOM % ${#zones[@]} ]} echo "Terraform will provision GKE cluster in \"${selected_location}\"" echo "cluster_location=${selected_location}" >> $GITHUB_ENV - - name: "deploy Sandbox" + - name: Deploy Online Boutique with Sandbox env: SHA: ${{ github.sha }} run: |- cd "${{ github.workspace }}/provisioning" state_prefix="${SHA:0:7}" - ./install.sh --project "${{ secrets.E2E_PROJECT_ID }}" --terraform-prefix "${state_prefix}" \ - --cluster-name "cloudops-sandbox-${state_prefix}" --cluster-location "${{ env.cluster_location }}" --skip-asm --verbose + ./sandboxctl create -p "${{ secrets.E2E_PROJECT_ID }}" --terraform-prefix "${state_prefix}" \ + -n "cloudops-sandbox-${state_prefix}" -l "${{ env.cluster_location }}" --skip-asm -v - - name: "clean up" + - name: Clean up deployment env: SHA: ${{ github.sha }} run: |- - cd "${{ github.workspace }}/provisioning/terraform" + cd "${{ github.workspace }}/provisioning" state_prefix="${SHA:0:7}" - terraform destroy -auto-approve --var="gcp_project_id=${{ secrets.E2E_PROJECT_ID }}" \ - --var="state_bucket_name=${{ secrets.E2E_PROJECT_ID }}-cloud-ops-sandbox-terraform-state" \ - --var="state_prefix=${state_prefix}" --var="gke_cluster_name=cloudops-sandbox-${state_prefix}" \ - --var="gke_cluster_location=${{ env.cluster_location }}" --var="filepath_manifest=../kustomize/online-boutique/" + ./sandboxctl delete -p "${{ secrets.E2E_PROJECT_ID }}" --terraform-prefix "${state_prefix}" \ + -n "cloudops-sandbox-${state_prefix}" -l "${{ env.cluster_location }}" --skip-asm -v diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5dcdde3bf..2f8cc4878 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,6 +28,13 @@ information on using pull requests. This project follows [Google's Open Source Community Guidelines](https://opensource.google/conduct/). +## Additional Information + +For additional information about how to submit your PRs, branching model and +version management, please look into [docs/][1] folder. + +[1]: https://github.com/GoogleCloudPlatform/cloud-ops-sandbox/tree/main/docs + - - - - -Page Moved - - -This page has moved. Click here to go to the new page. - - \ No newline at end of file diff --git a/docs/tutorial.md b/docs/tutorial.md deleted file mode 100644 index e95379a78..000000000 --- a/docs/tutorial.md +++ /dev/null @@ -1,279 +0,0 @@ -# Cloud Operations Sandbox Tutorial - -## Overview - -The Cloud Operations Sandbox is intended to make it easy for you to deploy and run a non-trivial application that lets you explore the Google Cloud Platform services, particularly the [Cloud Operations](http://cloud.google.com/products/operations) (formerly Stackdriver) product suite. Cloud Operations is a suite of tools that helps you gain full observability into your code and applications. - -The Hipster Shop application used in the sandbox is intended to be sufficiently complex such that you can meaningfully experiment with it, and the Sandbox automatically provisions a new demo cluster, configures and deploys Hipster Shop, and simulates real users. - -With the Sandbox running, you can experiment with various Cloud Operations tools to solve problems and accomplish standard SRE tasks in a sandboxed environment without impacting your production monitoring setup. - -### Architecture of the Hipster Shop application - -The Hipster Shop application consists of a number of microservices, written in a variety of languages, that talk to each other over gRPC. [To learn more.](https://cloud-ops-sandbox.dev/docs/service_overview/#service-architecture) - -### Prerequisites - -You must have an active Google Cloud Platform Billing Account. If you already have one, you can skip this section. - -Otherwise, to create a GCP Billing Account, do the following: - -1. Go to the Google Cloud Platform [Console](https://console.cloud.google.com/) and sign in (if you have an account), or sign up (if you don't have an account). -1. Select **Billing** from the navigation panel and follow the instructions. - -For more information, see ["Create a new billing account"](https://cloud.google.com/billing/docs/how-to/manage-billing-account). - -## Set up - -The installation process takes up to 20 minutes. When it completes, you will see a message like the one below, go to the next step: - -```bash -Cloud Operations Sandbox deployed successfully! -    Google Cloud Console GKE Dashboard: https://console.cloud.google.com/kubernetes/workload?project= -    Google Cloud Console Monitoring Workspace: https://console.cloud.google.com/monitoring?project= -    Hipstershop web app address: http://XX.XX.XX.XX -    Load generator web interface: http://XX.XX.XX.XX -``` - -The URLs in this message tell you where to find the results of the installation. - -If a message does **not** appear, and the installation script is not able to run, then try running `sandboxctl create` in your Cloud Shell terminal once you have set-up your billing account. - -### Recovering from session timeout - -Should your Cloud Shell session timeout due to user inactivity, you will need to launch the custom Cloud Shell image to access the `sandboxctl` command. -Click the - -![Open in Cloud Shell](https://gstatic.com/cloudssh/images/open-btn.png) - -button from the [Cloud Operations Sandbox homepage](https://cloud-ops-sandbox.dev/) to restart the custom Cloud Shell. - -## Explore the Sandbox - -Cloud Operations Sandbox comes with several capabilities out-of-the-box, in this tutorial, we walk through a guided tour of products in Cloud Operations and explore how they can be used to work with an application. -For additional information please refer to the [User Guide](https://cloud-ops-sandbox.dev/docs/). - -Let's get started! - -### Explore your project in GCP - -In another browser tab, navigate to the GCP GKE Dashboard URL, which takes you to the [Kubernetes Engine **Workloads** page](https://console.cloud.google.com/kubernetes/workload) for the project created by the installer ([documentation](https://cloud.google.com/kubernetes-engine/docs/)). - -### Shop like a hipster - -In a new browser tab, navigate to the Hipster Shop URL, where you can "purchase" everything you need for your hipster lifestyle using a mock credit card number. - -### Run the load generator - -Cloud Ops Sandbox comes with [Locust load generator](https://locust.io/), to simulate users traffic. - -- In another browser tab, navigate to the load-generator URL(from the installation stage if it isn't populated). -- Enter the number of **users** and **spawn rate**. For this application, we recommend to test 100 total users with a spawn rate of 2 users per second. -- Fill in the **Host** field with the "Hipster shop web address" from the installation stage if it isn't populated. -- Click the **Start swarming** button to begin generating traffic to the site. - -From here, you can explore how the application was deployed, and you can use the navigation menu to bring up other GCP tools. - -### Explore Cloud Monitoring - -Navigate to the GCP Monitoring Workspace URL, which takes you to the [Cloud Monitoring **Workspace** page](https://console.cloud.google.com/monitoring) for your new project. The console may take some time to create a new workspace. Afterward, you'll be able to see a few dashboards generated through Cloud Operations tools. - -## Learn Cloud Operations - -### Cloud Operations Overview - -Cloud Operations provides products for both developers and administrators, this section introduces a few of the products, for additional information refer to the [User Guide.](https://cloud-ops-sandbox.dev/docs/) - -Application developers need to be able to investigate the cause of problems in applications running in distributed environments, and in this context, the importance of **Application Performance Management (APM)** has increased. Cloud Operations provides 3 products for APM: - -- [Cloud Trace](https://console.cloud.google.com/traces) -- [Cloud Profiler](https://console.cloud.google.com/profiler) -- [Cloud Debugger](https://console.cloud.google.com/debug) - -> Note: The recommended solution for application instrumentation is [**OpenCensus**](https://opencensus.io/), an open-source project that supports trace instrumentation in a variety of languages and that can export this data to Cloud. - -Similarly, cloud-native, microservice-based applications complicate traditional approaches used by administrators for monitoring system health: it's harder to observe your system health when the number of instances is flexible and the inter-dependencies among the many components are complicated. In the last few years, **Site Reliability Engineering (SRE)** has become recognized as a practical approach to managing large-scale, highly complex, distributed systems. -In addition, Cloud Operations provides the several tools that are useful for [Site Reliability Engineering (SRE)](https://sre.google/): - -- [Cloud Monitoring](https://console.cloud.google.com/monitoring) -- [Cloud Logging](https://console.cloud.google.com/logs) -- [Cloud Error Reporting](https://console.cloud.google.com/errors) - -## The Cloud Observability Products: Monitoring, Logging, and Error Reporting - -Next, learn about Cloud Observability products! - -### Cloud Monitoring - -[Cloud Monitoring](https://console.cloud.google.com/monitoring) is the go-to place to grasp real-time trends of the system based on SLI/SLO. SRE team and application development team (and even business organization team) can collaborate to set up charts on the monitoring dashboard using metrics sent from the resources and the applications. - -#### Using Monitoring - -To get to Cloud Monitoring from the GCP console, select **Monitoring** on the navigation panel. By default, you reach an overview page. - -There are many pre-built monitoring pages. For example, the GKE Cluster Details page (select **Monitoring > Dashboards > Kubernetes Engine > Infrastructure**) brings up a page that provides information about the Sandbox cluster. - -You can also use the Monitoring console to create alerts and uptime checks, and to create dashboards that chart metrics you are interested in. For example, Metrics Explorer lets you select a specific metric, configure it for charting, and then save the chart. Select **Monitoring > Metrics Explorer** from the navigation panel to bring it up. - -### Monitoring and logs-based metrics - -Cloud Logging defines some logs-based metrics, but you can also create your own, for details, see ["Using logs-based metrics"](https://cloud.google.com/logging/docs/logs-based-metrics/).. To see the available metrics, select **Logging> Logs-based metrics** from the navigation panel. You see a summary of the system-provided and user-defined logs-based metrics. - -> Note: All system-defined logs-based metrics are counters. User-defined logs-based metrics can be either counter or distribution metrics. - -### Creating a logs-based metric - -To create a logs-based metric, click the **Create Metric** button at the top of the **Logs-based metrics** page or the Logs Viewer. This takes you to the Logs Viewer if needed, and also brings up the Metric Editor panel. - -Creating a logs-based metric involves two general steps: - -1. Identifying the set of log entries you want to use as the source of data for your entry by using the Logs Viewer. Using the Logs Viewer is briefly described in the **Cloud Logging** section of this document. -2. Describing the metric data to extract from these log entries by using the Metric Editor. - -This example creates a logs-based metric that counts the number of times a user (user ID, actually) adds an item to the HipsterShop cart. (This is an admittedly trivial example, though it could be extended. For example, from this same set of records, you can extract the user ID, item, and quantity added.) - -First, create a logs query that finds the relevant set of log entries: - -1. For the resource type, select **Kubernetes Container > cloud-ops-sandbox > default > server** -2. In the box with default text "Filter by label or text search", enter "AddItemAsync" (the method used to add an item to the cart), and hit return. - -Second, describe the new metric to be based on the logs query. This will be a counter metric. Enter a name and description and click **Create Metric**. - -It takes a few minutes for metric data to be collected, but once the metric collection has begun, you can chart this metric just like any other. - -To chart this metric using Metrics Explorer, select **Monitoring** from the GCP console, and on the Monitoring console, select **Resources > Metrics** Explorer. - -Search for the metric type using the name you gave it. - -## Cloud Logging - -Operators can look at [logs](https://console.cloud.google.com/logs) in [Cloud Logging](https://cloud.google.com/logging/docs/) to find clues explaining any anomalies in the metrics charts. - -### Using Logging - -You can access Cloud Logging by selecting **Logging** from the GCP navigation menu. This brings up the Logs Viewer interface. - -The Logs Viewer allows you to view logs emitted by resources in the project using search filters provided. The Logs Viewer lets you select standard filters from pulldown menus. - -### An example: server logs - -To view all container logs emitted by pods running in the default namespace, use the Resources and Logs filter fields (these default to **Audited Resources** and **All logs**): - -1. For the resource type, select **GKE Container -> cloud-ops-sandbox -> default** -2. For the log type, select **server** - -The Logs Viewer now displays the logs generated by pods running in the default namespace. - -For additional information and examples like log export see [User Guide.](https://cloud-ops-sandbox.dev/docs/user-guide/learn-ops-management/cloud_logging/) - -## Cloud Error Reporting - -[Cloud Error Reporting](https://console.cloud.google.com/errors) ([documentation](https://cloud.google.com/error-reporting/docs/)) automatically groups errors depending on stack trace message patterns and shows the frequency of each error group. The error groups are generated automatically, based on stack traces. -On opening an error group report, operators can access to the exact line in the application code where the error occurred and reason about the cause by navigating to the line of the source code on Google Cloud Source Repository. - -### Using Error Reporting - -You can access Error Reporting by selecting **Error Reporting** from the GCP navigation menu. - -> **Note:** Error Reporting can also let you know when new errors are received; see ["Notifications for Error Reporting"](https://cloud.google.com/error-reporting/docs/notifications) for details. - -To get started, select any open error by clicking on the error in the **Error** field. - -The **Error Details** screen shows you when the error has been occurring in the timeline and provides the stack trace that was captured with the error. **Scroll down** to see samples of the error. - -Click **View Logs** for one of the samples to see the log messages that match this particular error. - -You can expand any of the messages that matches the filter to see the full stack trace. - -## SLO Monitoring - -Cloud operations sandbox comes with several predefined SLOs(Service level objectives), that allow us to measure our users happiness. To learn more about SLIs and SLOs [visit here.](https://cloud.google.com/blog/products/devops-sre/sre-fundamentals-slis-slas-and-slos) - -Cloud operations suite provides **service oriented monitoring**, that means that we are configuring SLIs, SLOs and Burning Rates Alerts for a 'service'. Cloud Operations Sandbox' services are already detected since Istio automatically detects and creates services for us. But to demonstrate that you can create your own services, it also deploys custom services using [Terraform](https://github.com/GoogleCloudPlatform/cloud-ops-sandbox/tree/main/terraform/monitoring). - -You can find all the services under [monitoring → services → Services Overview](https://cloud.google.com/stackdriver/docs/solutions/slo-monitoring/ui/svc-overview) , and you can create your own [custom service.](https://cloud.google.com/stackdriver/docs/solutions/slo-monitoring/ui/define-svc) - -### Services SLOs - -To view, edit or create SLOs for a service you need to go to the service page, for additional information refer to the [User Guide.](https://cloud-ops-sandbox.dev/docs/) -> The *predefined SLOs* are also deployed as part of [Terraform code](https://github.com/GoogleCloudPlatform/cloud-ops-sandbox/tree/main/terraform/monitoring/04_slos.tf) and currently are for the mentioned custom services, the Istio service and Rating service. - -![Services example](https://github.com/GoogleCloudPlatform/cloud-ops-sandbox/raw/main/docs/images/user-guide/37-services-overview.png "Example of Cloud Operations Services") - -### Configure your own SLIs and SLOs - -You can [configure your own SLIs and SLOs](https://cloud.google.com/stackdriver/docs/solutions/slo-monitoring/ui/create-slo) for an existing service or for your own custom service. - -> **Remember** Our scope to examine and measure our users' happiness is User journey, so in order to create the SLO you need to identify the most important ones to the business. Then we want to *identify the metrics* that are closest to the customer experience and ingest that data. - -1. In the service screen we will choose Create SLO -2. Then we will set our SLI, we need to choose SLI type and the method(request vs window based) -3. Then we wil define our metric and we can also preview its performance based on historical data -4. Then we will configure our SLO, our target in a specific time window. We can also choose between [rolling window or a calendar window](https://sre.google/workbook/implementing-slos/) - -### Configure Burn Rate Alerts - -After you created the SLO, you can create [Burn Rate Alerts](https://cloud.google.com/stackdriver/docs/solutions/slo-monitoring/alerting-on-budget-burn-rate) for those. - -> There are also several *predefined polices* are deployed as part of [Terraform](https://github.com/GoogleCloudPlatform/cloud-ops-sandbox/blob/main/terraform/monitoring/05_alerting_policies.tf). You can view or edit them in the service screen. - -5. In the service screen we will be able to see our new SLO and we will choose 'Create Alerting Policy' -6. Then we will want to set the alert's condition, who and how they will be notified and additional instructions -7. After it will be created you could see it and incidents that might be triggered due to it in teh service screen and in the Alerting screen - -For additional information refer to the [User Guide.](https://cloud-ops-sandbox.dev/docs/user-guide) - -## SRE Recipes - -SRE Recipes is our [Chaos Engineering](https://en.wikipedia.org/wiki/Chaos_engineering) tool to test your sandbox environment. It helps users to familiarize themselves with finding the root cause of a breakage using Cloud Operations suite of tools. -Each 'recipe' simulates a different scenario of real life problems that can occur to the production system. There are several recipes that you can run and you can also [contribute your own.](https://github.com/GoogleCloudPlatform/cloud-ops-sandbox/tree/main/sre-recipes#contributing) - -```bash -sandboxctl sre-recipes -``` - -### Running an example SRE Recipe - -> **Note:** Recipe's names are not explicit by design as we don't want to allude to the problem. - -1. Run the recipe to manufacture errors in the demo cluster - -> **Note:** It may take up to 5 minutes for breakages to take effect in production. - -```bash -sandboxctl sre-recipes break recipe0 -``` - -2. Use Cloud Operations suite to diagnose the problem. - -> **Note:** If you are stuck, you can use a hint to direct you to the right direction. - -```bash -sandboxctl sre-recipes hint recipe0 -``` - -3. Verify your hypothesis on what could be wrong with the demo app by using command line tool - -```bash -sandboxctl sre-recipes verify recipe0 -``` - -4. After you discover the problem, you can restore the cluster to its original state. - -```bash -sandboxctl sre-recipes restore recipe0 -``` - -## Destroying your cluster - -Once you have finished exploring the Cloud Operations Sandbox project, don't forget to destroy it to avoid incurring additional billing. - -Destroy your Sandbox project by opening the Cloud Shell and running sandboxctl destroy: - -```bash -sandboxctl destroy -``` - -**Note:** This script destroys the current project. If `sandboxctl create` were run again, a Sandbox project with a new project id would be created. - -**Congratulations on finishing the Cloud Operations Sandbox tutorial!** diff --git a/docs/walkthrough.md b/docs/walkthrough.md new file mode 100644 index 000000000..501386aa9 --- /dev/null +++ b/docs/walkthrough.md @@ -0,0 +1,169 @@ +# Cloud Ops Sandbox Walkthrough + +## Introduction + +Cloud Ops Sandbox is intended to make it easy for you to explore observability +capabilities of Google Cloud services on the example of a non-trivial +microservice architecture deployed on Kubernetes. +[Cloud Operations][1] suite (formerly known as Stackdriver) is a collection of +services and tools that helps you gain full observability into your workloads. + +Cloud Ops Sandbox uses [Online Boutique][2] OSS as the example application. +When launched, Cloud Ops Sandbox provisions a GKE cluster and deploys Online +Boutique services together with an opinionated configuration of Cloud +Operations suite that includes monitoring dashboards, uptime checks, service +SLOs and alerts. + +You can experiment with Cloud Ops Sandbox environment to simulate problems with +Online Boutique services and to use Cloud Operations services and tools to +observe and troubleshoot the problems. + +Cloud Ops Sandbox uses Terraform to provision and configure necessary resources +and tools. + +Estimated time + + + +## Project Setup + +Before you begin, you will need a Google Cloud project. +Do the following steps to create or select the project that will be used to +launch Cloud Ops Sandbox and to enable required Google Cloud APIs. + +**Note:** It is highly recommended to use a project that is dedicated to +launch Cloud Ops Sandbox. Using the same project to host other applications +may result in unexpected decrease in performance or other conflicts. + + + +Configure Cloud Shell to use the selected project by running the following +command in Cloud Shell: + +```bash +gcloud configure set project +``` + + + + +If prompted, authorize Cloud Shell to call listed Google Cloud APIs. + +## Launch Cloud Ops Sandbox + +To launch Sandbox using default settings run the following command in Cloud Shell: + +```shell +provisioning/sandboxctl create --project-id +``` + +By default the launch will install [Anthos Service Mesh][3](ASM) and the +load generator that will create a simulated load on the demo application. +Also it will provision the [regional cluster][4] in the `us-central1` region. +If you wish to customize any of these default settings, you will need to run the +above command with additional parameters. + +By default the launch will run all Online Boutique services in [ASM][3]. +If you are not interested in using ASM, add the `--skip-asm` parameter to the +launch command. + +If you want to experiment with Sandbox without simulated load, add the +`--skip-loadgenerator` parameter to the launch command below. + +In order to change the region where GKE cluster is provisioned or to be provisioned +it as a [zonal cluster][5], add `--cluster-location [LOC]` parameter. +And provide a name of a region or a zone as `[LOC]` + +The GKE cluster name is set to `cloud-ops-sandbox`. If you want to customize it +add `--cluster-name [NAME]` parameter to the launch command below while +replacing `[NAME]` with the desired legal cluster name. + +During launch process, CLI prints out execution log (mainly from Terraform) to +console. On completion, you should see the output similar to the following: + +```terminal +Explore Cloud Ops Sandbox features by browsing + +GKE Dashboard: https://console.cloud.google.com/kubernetes/workload?project= +Monitoring Workspace: https://console.cloud.google.com/monitoring/?project= +Trying Online Boutique at http://10.0.0.1/ +``` + +You can use these URL to explore GKE cluster and Sandbox observability artifacts. + +### Recovering from errors + +If the launch fails due interim connection issues, repeat the launch command to +restart the process. +If the problem persists, use CLI to [delete Sandbox](#delete-launched-sandbox) +in order to clean up the failed launch and then try the launch process again. + +## Explore the Sandbox + +After completing launch process you can experiment with various Sandbox components. +If you are not ready to explore, click **Next** button to learn about how to +delete the launched Sandbox. + +### Explore Online Boutique + +Start with exploring the Online Boutique application that Sandbox uses. + +Open the Cloud Console navigation menu, hover over Kubernetes Engine, +and then click Services & Ingress. + + + +In the list shown list of services, look for the service of **Type** `External +load balancer`. The service name will be "istio-gateway" if you launched +Sandbox with ASM or "frontend-external" if you launched it without ASM. +In the endpoint column of this service, click the link with trailing `:80`. +A browser will open a window with Online Boutique application. You can +experiment with it to see what workflows can be triggered by user's actions. + +### Explore Cloud Trace + +You can see follow these workflow traces in Cloud Trace. +Open the Cloud Console navigation menu, hover over Trace, +and then click Trace List. + + + +You will see all traces reported by Online Boutique services. +Try to select any of them to get more information about call stack. + +**Note:** There can be not enough information immediately after launch. +You may want to return to this screen later. + +You can also check Overview screen for trace statistics of the project. +To do it, click + +Overview item in the toolbar on the left. + +## Delete Launched Sandbox + +When you do not need Cloud Ops Sandbox anylonger, don't forget to delete it to +avoid incurring additional costs. + +To delete the launched Sandbox, run the following command: + +```bash +provisioning/sandboxctl delete --project-id +``` + +**Warning:** If you customized your launch with additional parameters +(e.g. custom location), you will need to use these parameters for delete +operations. Otherwise, the delete operation may fail. + +If you launched Sandbox in a dedicated project and do not need the project, +you can simply [shut down the project][6]. + + + +[1]: http://cloud.google.com/products/operations +[2]: https://github.com/GoogleCloudPlatform/microservices-demo +[3]: https://cloud.google.com/anthos/service-mesh +[4]: https://cloud.google.com/kubernetes-engine/docs/concepts/types-of-clusters#regional_clusters +[5]: https://cloud.google.com/kubernetes-engine/docs/concepts/types-of-clusters#zonal_clusters +[6]: https://cloud.google.com/resource-manager/docs/creating-managing-projects#shutting_down_projects diff --git a/hack/README.md b/hack/README.md deleted file mode 100755 index 41d89df0c..000000000 --- a/hack/README.md +++ /dev/null @@ -1,18 +0,0 @@ -## `hack/` - -This directory provides scripts for building and pushing Docker images, and tagging new demo -releases. - -### env variables - -- `TAG` - git release tag / Docker tag. -- `REPO_PREFIX` - Docker repo prefix to push images. Format: `$user/$project`. Resulting images will be of the - format `$user/$project/$svcname:$tag` (where `svcname` = `adservice`, `cartservice`, - etc.) - -### scripts - -1. `./make-docker-images.sh`: builds and pushes images to the specified Docker repository. -2. `./make-release-artifacts.sh`: generates a combined YAML file with image $TAG at: - `./release/kubernetes-manifests/demo.yaml`. -3. `./make-release.sh`: runs scripts 1 and 2, then runs `git tag` / pushes updated manifests to master. diff --git a/hack/make-docker-images.sh b/hack/make-docker-images.sh deleted file mode 100755 index cd4cc63c7..000000000 --- a/hack/make-docker-images.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/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}")" - image="${REPO_PREFIX}/$svcname:$TAG" - ( - cd "${dir}" - log "Building: ${image}" - docker build -t "${image}" . - - log "Pushing: ${image}" - docker push "${image}" - ) -done < <(find "${SCRIPTDIR}/../src" -mindepth 1 -maxdepth 1 -type d -print0) - -log "Successfully built and pushed all images." diff --git a/hack/make-release-artifacts.sh b/hack/make-release-artifacts.sh deleted file mode 100755 index 9e9c85844..000000000 --- a/hack/make-release-artifacts.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/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}" - -read_manifests() { - local dir - dir="$1" - - while IFS= read -d $'\0' -r file; do - cat "${file}" - echo "---" - done < <(find "${dir}" -name '*.yaml' -type f -print0) -} - -mk_kubernetes_manifests() { - out_manifest="$(read_manifests "${SCRIPTDIR}/../kubernetes-manifests")" - - # replace "image" repo, tag for each service - for dir in ./src/*/ - do - svcname="$(basename "${dir}")" - image="$REPO_PREFIX/$ - :$TAG" - - pattern="^(\s*)image:\s.*$svcname(.*)(\s*)" - replace="\1image: $image\3" - out_manifest="$(sed -r "s|$pattern|$replace|" <(echo "${out_manifest}") )" - done - echo "${out_manifest}" -} - -mk_istio_manifests() { - read_manifests "${SCRIPTDIR}/../istio-manifests" -} - -main() { - mkdir -p "${OUT_DIR}" - local k8s_manifests_file istio_manifests_file - - k8s_manifests_file="${OUT_DIR}/kubernetes-manifests.yaml" - mk_kubernetes_manifests > "${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 diff --git a/hack/make-release.sh b/hack/make-release.sh deleted file mode 100755 index ff49ff40f..000000000 --- a/hack/make-release.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/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. - -# Creates a new release by 1) building/pushing images, 2) injecting tag into YAML, -# 3) creating a new git tag, and 4) pushing tags/updated YAML to $BRANCH. - -set -euo pipefail - -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}" - -# build and push images -./hack/make-docker-images.sh - -# update yaml -./hack/make-release-artifacts.sh - -# create git release / push to master -log "Pushing k8s manifests to master..." -git tag "$TAG" -git add release/ -git commit --allow-empty -m "Release $TAG" -git push --tags -git push origin master - -log "Successfully tagged release $TAG." diff --git a/hack/scratchpad.sh b/hack/scratchpad.sh deleted file mode 100644 index 899096e0c..000000000 --- a/hack/scratchpad.sh +++ /dev/null @@ -1,113 +0,0 @@ -# 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. - -#!/bin/bash -# -# Create a new deployment of Hipster Shop - -# Install Prerequisites -#sudo apt-get install jshon - -PROJECT_NAME="sandbox-demos" -ORGANIZATION_ID=396521612403 -FOLDER_ID=396521612403 -ZONE="us-west1-a" -CLUSTER_NAME=hipstershop -SERVICE_ACCOUNT_NAME=hipstershop-service-account - -if [ "$#" -lt 3 ]; then - echo "Usage: ./install.sh billingid project-prefix email" - echo " eg: ./install.sh 0X0X0X-0X0X0X-0X0X0X sandbox-20190106 somebody@gmail.com" - exit -fi - -ACCOUNT_ID=$1 -shift -PROJECT_PREFIX=$1 -shift -EMAILS=$@ - -# Update gcloud SDK -#gcloud components update - -# The following might be needed for Stackdriver Workspaces API -# gcloud components install alpha - -for EMAIL in $EMAILS; do - PROJECT_ID=$(echo "${PROJECT_PREFIX}-${EMAIL}" | sed 's/@/x/g' | sed 's/\./x/g' | cut -c 1-30) - #gcloud services enable container.googleapis.com --project $PROJECT_ID - echo "Creating project $PROJECT_NAME for $EMAIL ... " - - # create - gcloud projects create $PROJECT_ID --name $PROJECT_NAME --enable-cloud-apis --labels=product=sandbox - #--folder=$FOLDER_ID - #--organization=$ORGANIZATION_ID - sleep 2 - - # editor - rm -f iam.json.* - gcloud projects get-iam-policy $PROJECT_ID --format=json > iam.json.orig - cat iam.json.orig | sed s'/"bindings": \[/"bindings": \[ \{"members": \["user:'$EMAIL'"\],"role": "roles\/editor"\},/g' > iam.json.new - gcloud projects set-iam-policy $PROJECT_ID iam.json.new - - # billing - gcloud beta billing projects link $PROJECT_ID --billing-account=$ACCOUNT_ID - -done - -################# -# Create service account for project -gcloud iam service-accounts create hipstershop-service-account --display-name="Hipstershop Service Account" --project $PROJECT_ID - -# List service accounts and assign full address to IAM_ACCOUNT variable -gcloud iam service-accounts list --project $PROJECT_ID - -# alternative: append project and iam.gserviceacccount.com suffix -#$IAM_ACCOUNT={$SERVICE_ACCOUNT_NAME}@{$PROJECT_NAME}.iam.gserviceaccount.com -IAM_ACCOUNT=$(gcloud iam service-accounts list --project $PROJECT_ID --format="value(email)") - -# Add service account to be an owner of the project -gcloud projects add-iam-policy-binding $PROJECT_ID --member serviceAccount:$IAM_ACCOUNT --role roles/owner - -# Create private key for service account -gcloud iam service-accounts keys create hipstershop_credentials.json --iam-account=$IAM_ACCOUNT --key-file-type=json --project $PROJECT_ID - -# Activate authentication with service account -gcloud auth activate-service-account $IAM_ACCOUNT --key-file=hipstershop_credentials.json --project $PROJECT_ID - -# Enable APIs -# List all available to find the right command for missing API -# gcloud services list --available -gcloud services enable container.googleapis.com --project $PROJECT_ID -gcloud services enable cloudtrace.googleapis.com --project $PROJECT_ID - -# Create GKE cluster -gcloud container clusters create $CLUSTER_NAME --enable-autoupgrade --enable-autoscaling --min-nodes=3 --max-nodes=10 --num-nodes=5 --zone=$ZONE --labels=product=hipstershop --node-labels=product=hipstershop --scopes=cloud-platform --project $PROJECT_ID - -# Enable Google Container Registry -gcloud services enable containerregistry.googleapis.com --project $PROJECT_ID - -# Add GCR authentication support to docker -gcloud auth configure-docker -q --project $PROJECT_ID - -# Get Skaffold -curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64 -chmod +x skaffold -sudo mv skaffold /usr/local/bin - -# build everything locally and push to gcr, then deploy to gke -skaffold run --default-repo=gcr.io/$PROJECT_ID - -# get external IP -kubectl service frontend-external \ No newline at end of file diff --git a/istio-manifests/frontend-gateway.yaml b/istio-manifests/frontend-gateway.yaml deleted file mode 100644 index 3a9e0fd86..000000000 --- a/istio-manifests/frontend-gateway.yaml +++ /dev/null @@ -1,44 +0,0 @@ -# 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: networking.istio.io/v1alpha3 -kind: Gateway -metadata: - name: frontend-gateway -spec: - selector: - istio: ingressgateway # use Istio default gateway implementation - servers: - - port: - number: 80 - name: http - protocol: HTTP - hosts: - - "*" ---- -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: frontend-ingress -spec: - hosts: - - "*" - gateways: - - frontend-gateway - http: - - route: - - destination: - host: frontend - port: - number: 80 \ No newline at end of file diff --git a/istio-manifests/frontend.yaml b/istio-manifests/frontend.yaml deleted file mode 100644 index 4e1495093..000000000 --- a/istio-manifests/frontend.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# 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: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: frontend -spec: - hosts: - - "frontend.default.svc.cluster.local" - http: - - route: - - destination: - host: frontend - port: - number: 80 \ No newline at end of file diff --git a/kubernetes-manifests/adservice.yaml b/kubernetes-manifests/adservice.yaml deleted file mode 100644 index 1ff6a47d4..000000000 --- a/kubernetes-manifests/adservice.yaml +++ /dev/null @@ -1,66 +0,0 @@ -# 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: adservice -spec: - selector: - matchLabels: - app: adservice - template: - metadata: - labels: - app: adservice - spec: - terminationGracePeriodSeconds: 5 - containers: - - name: adservice - image: gcr.io/stackdriver-sandbox-230822/sandbox/adservice:v0.8.2 - ports: - - containerPort: 9555 - env: - - name: PORT - value: "9555" - resources: - requests: - cpu: 200m - memory: 180Mi - limits: - cpu: 300m - memory: 300Mi - readinessProbe: - initialDelaySeconds: 20 - periodSeconds: 15 - exec: - command: ["/bin/grpc_health_probe", "-addr=:9555"] - livenessProbe: - initialDelaySeconds: 20 - periodSeconds: 15 - exec: - command: ["/bin/grpc_health_probe", "-addr=:9555"] ---- -apiVersion: v1 -kind: Service -metadata: - name: adservice -spec: - type: ClusterIP - selector: - app: adservice - ports: - - name: grpc - port: 9555 - targetPort: 9555 diff --git a/kubernetes-manifests/cartservice.yaml b/kubernetes-manifests/cartservice.yaml deleted file mode 100644 index 41a2ccb3c..000000000 --- a/kubernetes-manifests/cartservice.yaml +++ /dev/null @@ -1,112 +0,0 @@ -# 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: - selector: - matchLabels: - app: cartservice - template: - metadata: - labels: - app: cartservice - spec: - terminationGracePeriodSeconds: 5 - initContainers: - - name: init-redis-ready - image: busybox:1.28 - command: ['bin/sh', '-c', 'until nslookup redis-cart; do echo waiting for redis; sleep 2; done;'] - containers: - - name: cartservice - image: gcr.io/stackdriver-sandbox-230822/sandbox/cartservice:v0.8.2 - ports: - - containerPort: 7070 - env: - - name: REDIS_ADDR - value: "redis-cart:6379" - - name: ASPNETCORE_URLS - value: "http://0.0.0.0:7070" - - name: OTEL_COLLECTOR_ADDR - value: "http://localhost:4317" - resources: - requests: - cpu: 200m - memory: 64Mi - limits: - cpu: 300m - memory: 128Mi - readinessProbe: - initialDelaySeconds: 15 - exec: - command: ["/bin/grpc_health_probe", "-addr=:7070", "-rpc-timeout=5s"] - livenessProbe: - initialDelaySeconds: 15 - periodSeconds: 10 - exec: - command: ["/bin/grpc_health_probe", "-addr=:7070", "-rpc-timeout=5s"] - # Add a 'sidecar' container running the OpenTelemetry collector - - name: otel-agent - image: otel/opentelemetry-collector-contrib:0.28.0 - args: - - --config=/conf/otel-agent-config.yaml - volumeMounts: - - name: otel-agent-config-vol - mountPath: /conf - volumes: - - configMap: - items: - - key: otel-agent-config.yaml - path: otel-agent-config.yaml - name: otel-agent-config - name: otel-agent-config-vol ---- -apiVersion: v1 -kind: Service -metadata: - name: cartservice -spec: - type: ClusterIP - selector: - app: cartservice - ports: - - name: grpc - port: 7070 - targetPort: 7070 ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: otel-agent-config -# Open Telemetry Collector config -# https://opentelemetry.io/docs/collector/configuration -data: - otel-agent-config.yaml: | - receivers: - otlp: - protocols: - grpc: - exporters: - otlp: - endpoint: "opentelemetrycollector.default.svc.cluster.local:4317" # Forward traces to collector gateway in cluster - insecure: true - processors: - batch: - service: - pipelines: - traces: - receivers: [otlp] # Receive otlp-formatted data from microservice using OpenTelemetry SDK - exporters: [otlp] # Export to OpenTelemtry collector agent on same host diff --git a/kubernetes-manifests/checkoutservice.yaml b/kubernetes-manifests/checkoutservice.yaml deleted file mode 100644 index f36c64272..000000000 --- a/kubernetes-manifests/checkoutservice.yaml +++ /dev/null @@ -1,71 +0,0 @@ -# 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: - selector: - matchLabels: - app: checkoutservice - template: - metadata: - labels: - app: checkoutservice - spec: - containers: - - name: checkoutservice - image: gcr.io/stackdriver-sandbox-230822/sandbox/checkoutservice:v0.8.2 - ports: - - containerPort: 5050 - readinessProbe: - exec: - command: ["/bin/grpc_health_probe", "-addr=:5050"] - livenessProbe: - exec: - command: ["/bin/grpc_health_probe", "-addr=:5050"] - env: - - 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" - 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 diff --git a/kubernetes-manifests/currencyservice.yaml b/kubernetes-manifests/currencyservice.yaml deleted file mode 100644 index 19807874e..000000000 --- a/kubernetes-manifests/currencyservice.yaml +++ /dev/null @@ -1,60 +0,0 @@ -# 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: - selector: - matchLabels: - app: currencyservice - template: - metadata: - labels: - app: currencyservice - spec: - terminationGracePeriodSeconds: 5 - containers: - - name: currencyservice - image: gcr.io/stackdriver-sandbox-230822/sandbox/currencyservice:v0.8.2 - ports: - - name: grpc - containerPort: 7000 - readinessProbe: - exec: - command: ["/bin/grpc_health_probe", "-addr=:7000"] - livenessProbe: - exec: - command: ["/bin/grpc_health_probe", "-addr=:7000"] - resources: - requests: - cpu: 100m - memory: 64Mi - limits: - cpu: 200m - memory: 128Mi ---- -apiVersion: v1 -kind: Service -metadata: - name: currencyservice -spec: - type: ClusterIP - selector: - app: currencyservice - ports: - - name: grpc - port: 7000 - targetPort: 7000 diff --git a/kubernetes-manifests/emailservice.yaml b/kubernetes-manifests/emailservice.yaml deleted file mode 100644 index 7dfeee140..000000000 --- a/kubernetes-manifests/emailservice.yaml +++ /dev/null @@ -1,61 +0,0 @@ -# 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: - selector: - matchLabels: - app: emailservice - template: - metadata: - labels: - app: emailservice - spec: - terminationGracePeriodSeconds: 5 - containers: - - name: emailservice - image: gcr.io/stackdriver-sandbox-230822/sandbox/emailservice:v0.8.2 - ports: - - containerPort: 8080 - readinessProbe: - periodSeconds: 5 - exec: - command: ["/bin/grpc_health_probe", "-addr=:8080"] - livenessProbe: - periodSeconds: 5 - exec: - command: ["/bin/grpc_health_probe", "-addr=:8080"] - resources: - requests: - cpu: 100m - memory: 64Mi - limits: - cpu: 200m - memory: 128Mi ---- -apiVersion: v1 -kind: Service -metadata: - name: emailservice -spec: - type: ClusterIP - selector: - app: emailservice - ports: - - name: grpc - port: 5000 - targetPort: 8080 diff --git a/kubernetes-manifests/frontend.yaml b/kubernetes-manifests/frontend.yaml deleted file mode 100644 index a7cc5a218..000000000 --- a/kubernetes-manifests/frontend.yaml +++ /dev/null @@ -1,98 +0,0 @@ -# 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: - selector: - matchLabels: - app: frontend - template: - metadata: - labels: - app: frontend - spec: - containers: - - name: frontend - image: gcr.io/stackdriver-sandbox-230822/sandbox/frontend:v0.8.2 - 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: 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" - - name: RATING_SERVICE_ADDR - value: "http://some.host" - resources: - requests: - cpu: 200m - memory: 128Mi - limits: - cpu: 320m - memory: 256Mi ---- -apiVersion: v1 -kind: Service -metadata: - name: frontend -spec: - type: ClusterIP - selector: - app: frontend - ports: - - name: http - port: 80 - targetPort: 8080 ---- -apiVersion: v1 -kind: Service -metadata: - name: frontend-external -spec: - type: LoadBalancer - selector: - app: frontend - ports: - - name: http - port: 80 - targetPort: 8080 diff --git a/kubernetes-manifests/opentelemetrycollector.yaml b/kubernetes-manifests/opentelemetrycollector.yaml deleted file mode 100644 index 0310ce57a..000000000 --- a/kubernetes-manifests/opentelemetrycollector.yaml +++ /dev/null @@ -1,103 +0,0 @@ -# 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. - ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: opentelemetrycollector -spec: - replicas: 1 - selector: - matchLabels: - app: opentelemetrycollector - template: - metadata: - labels: - app: opentelemetrycollector - spec: - # Init container retrieves the current cloud project id from the metadata server - # and inserts it into the collector config template - # https://cloud.google.com/compute/docs/storing-retrieving-metadata - initContainers: - - name: otel-gateway-init - image: gcr.io/google.com/cloudsdktool/cloud-sdk:326.0.0-alpine - command: - - '/bin/bash' - - '-c' - - | - sed "s/{{PROJECT_ID}}/$(curl -H 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1/project/project-id)/" /template/collector-gateway-config-template.yaml >> /conf/collector-gateway-config.yaml - volumeMounts: - - name: collector-gateway-config-template - mountPath: /template - - name: collector-gateway-config - mountPath: /conf - containers: - # This gateway container will receive trace information from one or more microservices - # and forward it to Cloud Trace - - name: otel-gateway - args: - - --config=/conf/collector-gateway-config.yaml - image: otel/opentelemetry-collector-contrib:0.28.0 - volumeMounts: - - name: collector-gateway-config - mountPath: /conf - volumes: - # Simple ConfigMap volume with template file - - name: collector-gateway-config-template - configMap: - items: - - key: collector-gateway-config-template.yaml - path: collector-gateway-config-template.yaml - name: collector-gateway-config-template - # Create a volume to store the expanded template (with correct cloud project ID) - - name: collector-gateway-config - emptyDir: {} ---- -apiVersion: v1 -kind: Service -metadata: - name: opentelemetrycollector -spec: - ports: - - name: grpc-otlp - port: 4317 - protocol: TCP - targetPort: 4317 - selector: - app: opentelemetrycollector - type: ClusterIP ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: collector-gateway-config-template -# Open Telemetry Collector config -# https://opentelemetry.io/docs/collector/configuration/ -data: - collector-gateway-config-template.yaml: | - receivers: - otlp: - protocols: - grpc: - processors: - exporters: - googlecloud: - project: {{PROJECT_ID}} - service: - pipelines: - traces: - receivers: [otlp] # Receive otlp-formatted data from other collector instances - processors: [] - exporters: [googlecloud] # Export directly to Google Cloud \ No newline at end of file diff --git a/kubernetes-manifests/paymentservice.yaml b/kubernetes-manifests/paymentservice.yaml deleted file mode 100644 index 32732f5c8..000000000 --- a/kubernetes-manifests/paymentservice.yaml +++ /dev/null @@ -1,59 +0,0 @@ -# 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: - selector: - matchLabels: - app: paymentservice - template: - metadata: - labels: - app: paymentservice - spec: - terminationGracePeriodSeconds: 5 - containers: - - name: paymentservice - image: gcr.io/stackdriver-sandbox-230822/sandbox/paymentservice:v0.8.2 - ports: - - containerPort: 50051 - readinessProbe: - exec: - command: ["/bin/grpc_health_probe", "-addr=:50051"] - livenessProbe: - 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: paymentservice -spec: - type: ClusterIP - selector: - app: paymentservice - ports: - - name: grpc - port: 50051 - targetPort: 50051 diff --git a/kubernetes-manifests/productcatalogservice.yaml b/kubernetes-manifests/productcatalogservice.yaml deleted file mode 100644 index 19ff3974a..000000000 --- a/kubernetes-manifests/productcatalogservice.yaml +++ /dev/null @@ -1,59 +0,0 @@ -# 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: - selector: - matchLabels: - app: productcatalogservice - template: - metadata: - labels: - app: productcatalogservice - spec: - terminationGracePeriodSeconds: 5 - containers: - - name: productcatalogservice - image: gcr.io/stackdriver-sandbox-230822/sandbox/productcatalogservice:v0.8.2 - ports: - - containerPort: 3550 - readinessProbe: - exec: - command: ["/bin/grpc_health_probe", "-addr=:3550"] - livenessProbe: - 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 diff --git a/kubernetes-manifests/recommendationservice.yaml b/kubernetes-manifests/recommendationservice.yaml deleted file mode 100644 index 4a5b158ff..000000000 --- a/kubernetes-manifests/recommendationservice.yaml +++ /dev/null @@ -1,56 +0,0 @@ -# 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: - selector: - matchLabels: - app: recommendationservice - template: - metadata: - labels: - app: recommendationservice - spec: - terminationGracePeriodSeconds: 5 - containers: - - name: recommendationservice - image: gcr.io/stackdriver-sandbox-230822/sandbox/recommendationservice:v0.8.2 - ports: - - containerPort: 8080 - env: - - name: PRODUCT_CATALOG_SERVICE_ADDR - value: "productcatalogservice:3550" - 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 diff --git a/kubernetes-manifests/redis.yaml b/kubernetes-manifests/redis.yaml deleted file mode 100644 index b67649b93..000000000 --- a/kubernetes-manifests/redis.yaml +++ /dev/null @@ -1,66 +0,0 @@ -# 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: - selector: - matchLabels: - app: redis-cart - template: - metadata: - labels: - app: redis-cart - spec: - containers: - - name: redis - 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: redis - port: 6379 - targetPort: 6379 diff --git a/kubernetes-manifests/shippingservice.yaml b/kubernetes-manifests/shippingservice.yaml deleted file mode 100644 index e184e3a77..000000000 --- a/kubernetes-manifests/shippingservice.yaml +++ /dev/null @@ -1,59 +0,0 @@ -# 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: - selector: - matchLabels: - app: shippingservice - template: - metadata: - labels: - app: shippingservice - spec: - containers: - - name: shippingservice - image: gcr.io/stackdriver-sandbox-230822/sandbox/shippingservice:v0.8.2 - ports: - - containerPort: 50051 - readinessProbe: - periodSeconds: 5 - exec: - command: ["/bin/grpc_health_probe", "-addr=:50051"] - livenessProbe: - 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 diff --git a/loadgenerator-manifests/loadgenerator.yaml b/loadgenerator-manifests/loadgenerator.yaml deleted file mode 100644 index 340cbcabb..000000000 --- a/loadgenerator-manifests/loadgenerator.yaml +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright 2015 Google Inc. All rights reserved. -# -# 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: - replicas: 1 - selector: - matchLabels: - app: loadgenerator - mode: master - template: - metadata: - labels: - app: loadgenerator - mode: master - spec: - containers: - - name: locust-main - image: gcr.io/stackdriver-sandbox-230822/sandbox/loadgenerator/gke:v0.8.2 - imagePullPolicy: Always - env: - - name: LOCUST_MODE - value: standalone - - name: LOCUST_TASK - value: basic - - name: TARGET_HOST - valueFrom: - configMapKeyRef: - name: address-config - key: FRONTEND_ADDR - ports: - - name: loc-master-web - containerPort: 8089 - protocol: TCP - - name: loc-master-api - containerPort: 8090 - protocol: TCP ---- -kind: Service -apiVersion: v1 -metadata: - name: loadgenerator - labels: - app: loadgenerator -spec: - ports: - - port: 80 - targetPort: loc-master-web - protocol: TCP - name: loc-master-web - - port: 81 - targetPort: loc-master-api - protocol: TCP - name: loc-master-api - selector: - app: loadgenerator - mode: master - type: LoadBalancer diff --git a/pb/demo.proto b/pb/demo.proto deleted file mode 100644 index e7de69874..000000000 --- a/pb/demo.proto +++ /dev/null @@ -1,262 +0,0 @@ -// 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; - -option go_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 "vintage" or "gardening" 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; -} diff --git a/pb/grpc/health/v1/health.proto b/pb/grpc/health/v1/health.proto deleted file mode 100644 index 38843ff1e..000000000 --- a/pb/grpc/health/v1/health.proto +++ /dev/null @@ -1,63 +0,0 @@ -// 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; - SERVICE_UNKNOWN = 3; // Used only by the Watch method. - } - ServingStatus status = 1; -} - -service Health { - // If the requested service is unknown, the call will fail with status - // NOT_FOUND. - rpc Check(HealthCheckRequest) returns (HealthCheckResponse); - - // Performs a watch for the serving status of the requested service. - // The server will immediately send back a message indicating the current - // serving status. It will then subsequently send a new message whenever - // the service's serving status changes. - // - // If the requested service is unknown when the call is received, the - // server will send a message setting the serving status to - // SERVICE_UNKNOWN but will *not* terminate the call. If at some - // future point, the serving status of the service becomes known, the - // server will send a new message with the service's serving status. - // - // If the call terminates with status UNIMPLEMENTED, then clients - // should assume this method is not supported and should not retry the - // call. If the call terminates with any other status (including OK), - // clients should retry the call with appropriate exponential backoff. - rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse); -} diff --git a/terraform/monitoring/dashboards/adservice_dashboard.json b/provisioning/configurations/online-boutique/dashboards/adservice_dashboard.json similarity index 90% rename from terraform/monitoring/dashboards/adservice_dashboard.json rename to provisioning/configurations/online-boutique/dashboards/adservice_dashboard.json index a94ed4683..9979b57a7 100644 --- a/terraform/monitoring/dashboards/adservice_dashboard.json +++ b/provisioning/configurations/online-boutique/dashboards/adservice_dashboard.json @@ -10,7 +10,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"kubernetes.io/container/cpu/limit_utilization\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"adservice\" resource.label.\"container_name\"=\"server\"", + "filter": "metric.type=\"kubernetes.io/container/cpu/limit_utilization\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"adservice\" resource.label.\"container_name\"=\"server\"", "aggregation": { "perSeriesAligner": "ALIGN_MEAN" } @@ -37,7 +37,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"istio.io/service/server/request_count\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"adservice\"", + "filter": "metric.type=\"istio.io/service/server/request_count\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"adservice\"", "aggregation": { "perSeriesAligner": "ALIGN_RATE" } @@ -118,7 +118,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"istio.io/service/server/response_latencies\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"adservice\"", + "filter": "metric.type=\"istio.io/service/server/response_latencies\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"adservice\"", "aggregation": { "perSeriesAligner": "ALIGN_PERCENTILE_99" } @@ -140,4 +140,4 @@ } ] } -} +} \ No newline at end of file diff --git a/terraform/monitoring/dashboards/cartservice_dashboard.json b/provisioning/configurations/online-boutique/dashboards/cartservice_dashboard.json similarity index 91% rename from terraform/monitoring/dashboards/cartservice_dashboard.json rename to provisioning/configurations/online-boutique/dashboards/cartservice_dashboard.json index c243f6d5a..d24129883 100644 --- a/terraform/monitoring/dashboards/cartservice_dashboard.json +++ b/provisioning/configurations/online-boutique/dashboards/cartservice_dashboard.json @@ -10,7 +10,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"kubernetes.io/container/memory/limit_utilization\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"cartservice\"", + "filter": "metric.type=\"kubernetes.io/container/memory/limit_utilization\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"cartservice\"", "aggregation": { "perSeriesAligner": "ALIGN_MEAN" } @@ -37,7 +37,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"kubernetes.io/container/memory/used_bytes\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"checkoutservice\"", + "filter": "metric.type=\"kubernetes.io/container/memory/used_bytes\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"checkoutservice\"", "aggregation": { "perSeriesAligner": "ALIGN_MEAN" } @@ -91,7 +91,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"istio.io/service/server/request_count\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"cartservice\"", + "filter": "metric.type=\"istio.io/service/server/request_count\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"cartservice\"", "aggregation": { "perSeriesAligner": "ALIGN_RATE" } @@ -172,7 +172,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"istio.io/service/server/response_latencies\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"cartservice\"", + "filter": "metric.type=\"istio.io/service/server/response_latencies\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"cartservice\"", "aggregation": { "perSeriesAligner": "ALIGN_DELTA", "crossSeriesReducer": "REDUCE_PERCENTILE_99" @@ -195,4 +195,4 @@ } ] } -} +} \ No newline at end of file diff --git a/terraform/monitoring/dashboards/checkoutservice_dashboard.json b/provisioning/configurations/online-boutique/dashboards/checkoutservice_dashboard.json similarity index 92% rename from terraform/monitoring/dashboards/checkoutservice_dashboard.json rename to provisioning/configurations/online-boutique/dashboards/checkoutservice_dashboard.json index 653251af2..8c1390d98 100644 --- a/terraform/monitoring/dashboards/checkoutservice_dashboard.json +++ b/provisioning/configurations/online-boutique/dashboards/checkoutservice_dashboard.json @@ -10,7 +10,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"kubernetes.io/container/cpu/limit_utilization\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"checkoutservice\"", + "filter": "metric.type=\"kubernetes.io/container/cpu/limit_utilization\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"checkoutservice\"", "aggregation": { "perSeriesAligner": "ALIGN_MEAN" } @@ -64,7 +64,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"istio.io/service/server/request_count\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"checkoutservice\"", + "filter": "metric.type=\"istio.io/service/server/request_count\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"checkoutservice\"", "aggregation": { "perSeriesAligner": "ALIGN_RATE" } @@ -145,7 +145,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"istio.io/service/server/response_latencies\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"checkoutservice\"", + "filter": "metric.type=\"istio.io/service/server/response_latencies\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"checkoutservice\"", "aggregation": { "perSeriesAligner": "ALIGN_PERCENTILE_99" } @@ -167,4 +167,4 @@ } ] } -} +} \ No newline at end of file diff --git a/terraform/monitoring/dashboards/currencyservice_dashboard.json b/provisioning/configurations/online-boutique/dashboards/currencyservice_dashboard.json similarity index 90% rename from terraform/monitoring/dashboards/currencyservice_dashboard.json rename to provisioning/configurations/online-boutique/dashboards/currencyservice_dashboard.json index 57107b423..7d57ce731 100644 --- a/terraform/monitoring/dashboards/currencyservice_dashboard.json +++ b/provisioning/configurations/online-boutique/dashboards/currencyservice_dashboard.json @@ -10,7 +10,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"kubernetes.io/container/cpu/limit_utilization\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"currencyservice\"", + "filter": "metric.type=\"kubernetes.io/container/cpu/limit_utilization\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"currencyservice\"", "aggregation": { "perSeriesAligner": "ALIGN_MEAN" } @@ -37,7 +37,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"istio.io/service/server/request_count\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"currencyservice\"", + "filter": "metric.type=\"istio.io/service/server/request_count\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"currencyservice\"", "aggregation": { "perSeriesAligner": "ALIGN_RATE" } @@ -118,7 +118,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"istio.io/service/server/response_latencies\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"currencyservice\"", + "filter": "metric.type=\"istio.io/service/server/response_latencies\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"currencyservice\"", "aggregation": { "perSeriesAligner": "ALIGN_PERCENTILE_99", "crossSeriesReducer": "REDUCE_PERCENTILE_99" @@ -141,4 +141,4 @@ } ] } -} +} \ No newline at end of file diff --git a/terraform/monitoring/dashboards/frontend_dashboard.json b/provisioning/configurations/online-boutique/dashboards/frontend_dashboard.json similarity index 84% rename from terraform/monitoring/dashboards/frontend_dashboard.json rename to provisioning/configurations/online-boutique/dashboards/frontend_dashboard.json index d969f663e..de78d0e22 100644 --- a/terraform/monitoring/dashboards/frontend_dashboard.json +++ b/provisioning/configurations/online-boutique/dashboards/frontend_dashboard.json @@ -10,7 +10,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"kubernetes.io/container/cpu/limit_utilization\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"frontend\"", + "filter": "metric.type=\"kubernetes.io/container/cpu/limit_utilization\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"frontend\"", "aggregation": { "perSeriesAligner": "ALIGN_MEAN" } @@ -37,7 +37,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"istio.io/service/server/request_count\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"frontend\"", + "filter": "metric.type=\"istio.io/service/server/request_count\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"frontend\"", "aggregation": { "perSeriesAligner": "ALIGN_RATE" } @@ -64,7 +64,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"istio.io/service/server/request_count\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"frontend\" metric.label.\"response_code\"!=\"200\"", + "filter": "metric.type=\"istio.io/service/server/request_count\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"frontend\" metric.label.\"response_code\"!=\"200\"", "aggregation": { "perSeriesAligner": "ALIGN_RATE" } @@ -91,7 +91,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"istio.io/service/server/response_latencies\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"frontend\"", + "filter": "metric.type=\"istio.io/service/server/response_latencies\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"frontend\"", "aggregation": { "perSeriesAligner": "ALIGN_PERCENTILE_99" } diff --git a/terraform/monitoring/dashboards/generic_dashboard.tmpl b/provisioning/configurations/online-boutique/dashboards/generic_dashboard.tmpl similarity index 84% rename from terraform/monitoring/dashboards/generic_dashboard.tmpl rename to provisioning/configurations/online-boutique/dashboards/generic_dashboard.tmpl index 10e54d60f..289ea5c68 100644 --- a/terraform/monitoring/dashboards/generic_dashboard.tmpl +++ b/provisioning/configurations/online-boutique/dashboards/generic_dashboard.tmpl @@ -10,7 +10,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"kubernetes.io/container/cpu/limit_utilization\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"${service_id}\"", + "filter": "metric.type=\"kubernetes.io/container/cpu/limit_utilization\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"${service_id}\"", "aggregation": { "perSeriesAligner": "ALIGN_MEAN" } @@ -37,7 +37,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"istio.io/service/server/request_count\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"${service_id}\"", + "filter": "metric.type=\"istio.io/service/server/request_count\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"${service_id}\"", "aggregation": { "perSeriesAligner": "ALIGN_RATE" } @@ -64,7 +64,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"istio.io/service/server/request_count\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"${service_id}\" metric.label.\"response_code\"!=\"200\"", + "filter": "metric.type=\"istio.io/service/server/request_count\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"${service_id}\" metric.label.\"response_code\"!=\"200\"", "aggregation": { "perSeriesAligner": "ALIGN_RATE" } @@ -91,7 +91,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"istio.io/service/server/response_latencies\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"${service_id}\"", + "filter": "metric.type=\"istio.io/service/server/response_latencies\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"${service_id}\"", "aggregation": { "perSeriesAligner": "ALIGN_PERCENTILE_99" } diff --git a/provisioning/configurations/online-boutique/dashboards/log_based_metric_dashboard.json b/provisioning/configurations/online-boutique/dashboards/log_based_metric_dashboard.json new file mode 100644 index 000000000..524b299bf --- /dev/null +++ b/provisioning/configurations/online-boutique/dashboards/log_based_metric_dashboard.json @@ -0,0 +1,38 @@ +{ + "displayName": "Log Based Metric Dashboard", + "gridLayout": { + "columns": "2", + "widgets": [ + { + "title": "Number of Products Ordered per day grouped by Product Name", + "xyChart": { + "dataSets": [ + { + "timeSeriesQuery": { + "timeSeriesFilter": { + "filter": "metric.type=\"logging.googleapis.com/user/${metric_name}\" resource.type=\"k8s_container\"", + "aggregation": { + "perSeriesAligner": "ALIGN_SUM", + "crossSeriesReducer": "REDUCE_MEAN", + "groupByFields": [ + "metric.label.\"product_name\"" + ] + } + } + }, + "plotType": "LINE", + "minAlignmentPeriod": "86400s" + } + ], + "yAxis": { + "label": "y1Axis", + "scale": "LINEAR" + }, + "chartOptions": { + "mode": "COLOR" + } + } + } + ] + } +} \ No newline at end of file diff --git a/terraform/monitoring/dashboards/productcatalogservice_dashboard.json b/provisioning/configurations/online-boutique/dashboards/productcatalogservice_dashboard.json similarity index 90% rename from terraform/monitoring/dashboards/productcatalogservice_dashboard.json rename to provisioning/configurations/online-boutique/dashboards/productcatalogservice_dashboard.json index e99eaa0f3..659d310f6 100644 --- a/terraform/monitoring/dashboards/productcatalogservice_dashboard.json +++ b/provisioning/configurations/online-boutique/dashboards/productcatalogservice_dashboard.json @@ -10,7 +10,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"kubernetes.io/container/memory/limit_utilization\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"productcatalogservice\"", + "filter": "metric.type=\"kubernetes.io/container/memory/limit_utilization\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"productcatalogservice\"", "aggregation": { "perSeriesAligner": "ALIGN_MEAN" } @@ -37,7 +37,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"istio.io/service/server/request_count\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"productcatalogservice\"", + "filter": "metric.type=\"istio.io/service/server/request_count\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"productcatalogservice\"", "aggregation": { "perSeriesAligner": "ALIGN_RATE" } @@ -118,7 +118,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"istio.io/service/server/response_latencies\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"productcatalogservice\"", + "filter": "metric.type=\"istio.io/service/server/response_latencies\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"productcatalogservice\"", "aggregation": { "perSeriesAligner": "ALIGN_DELTA", "crossSeriesReducer": "REDUCE_PERCENTILE_99" @@ -141,4 +141,4 @@ } ] } -} +} \ No newline at end of file diff --git a/terraform/monitoring/dashboards/recommendationservice_dashboard.json b/provisioning/configurations/online-boutique/dashboards/recommendationservice_dashboard.json similarity index 89% rename from terraform/monitoring/dashboards/recommendationservice_dashboard.json rename to provisioning/configurations/online-boutique/dashboards/recommendationservice_dashboard.json index 2752ed18f..bffa94fc9 100644 --- a/terraform/monitoring/dashboards/recommendationservice_dashboard.json +++ b/provisioning/configurations/online-boutique/dashboards/recommendationservice_dashboard.json @@ -10,7 +10,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"kubernetes.io/container/cpu/limit_utilization\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"recommendationservice\" resource.label.\"container_name\"=\"server\"", + "filter": "metric.type=\"kubernetes.io/container/cpu/limit_utilization\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"recommendationservice\" resource.label.\"container_name\"=\"server\"", "aggregation": { "perSeriesAligner": "ALIGN_MEAN" } @@ -37,7 +37,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"istio.io/service/server/request_count\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"recommendationservice\"", + "filter": "metric.type=\"istio.io/service/server/request_count\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"recommendationservice\"", "aggregation": { "perSeriesAligner": "ALIGN_RATE" } @@ -118,7 +118,7 @@ { "timeSeriesQuery": { "timeSeriesFilter": { - "filter": "metric.type=\"istio.io/service/server/response_latencies\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"cloud-ops-sandbox\" metadata.user_labels.\"app\"=\"recommendationservice\"", + "filter": "metric.type=\"istio.io/service/server/response_latencies\" resource.type=\"k8s_container\" resource.label.\"cluster_name\"=\"${cluster_name}\" AND resource.labels.\"namespace_name\"=\"default\" metadata.user_labels.\"app\"=\"recommendationservice\"", "aggregation": { "perSeriesAligner": "ALIGN_PERCENTILE_99" } @@ -140,4 +140,4 @@ } ] } -} +} \ No newline at end of file diff --git a/terraform/monitoring/dashboards/userexp_dashboard.json b/provisioning/configurations/online-boutique/dashboards/userexp_dashboard.json similarity index 100% rename from terraform/monitoring/dashboards/userexp_dashboard.json rename to provisioning/configurations/online-boutique/dashboards/userexp_dashboard.json diff --git a/provisioning/kustomize/online-boutique/kustomization.yaml b/provisioning/kustomize/online-boutique/kustomization.yaml new file mode 100644 index 000000000..31e92231d --- /dev/null +++ b/provisioning/kustomize/online-boutique/kustomization.yaml @@ -0,0 +1,23 @@ +# Copyright 2023 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: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- github.com/GoogleCloudPlatform/microservices-demo/kustomize/base?version=v0.6.0 +components: +- github.com/GoogleCloudPlatform/microservices-demo/kustomize/components/google-cloud-operations?version=v0.6.0 +#!DO NOT REMOVE FOLLOWING COMMENTED LINES! +#- github.com/GoogleCloudPlatform/microservices-demo/kustomize/components/service-mesh-istio?version=v0.6.0 +#- github.com/GoogleCloudPlatform/microservices-demo/kustomize/components/without-loadgenerator?version=v0.6.0 diff --git a/provisioning/sandboxctl b/provisioning/sandboxctl new file mode 100755 index 000000000..3d658a9e1 --- /dev/null +++ b/provisioning/sandboxctl @@ -0,0 +1,518 @@ +#!/bin/bash +# Copyright 2023 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. + +set -CeE +set -o pipefail + +if [[ "${BASH_VERSINFO:-0}" -lt 4 ]]; then + cat << EOF >&2 +WARNING: bash ${BASH_VERSION} does not support several modern safety features. +This script was written with the latest POSIX standard in mind, and was only +tested with modern shell standards. This script may not perform correctly in +this environment. +EOF + sleep 1 +else + set -u +fi + +SCRIPT_NAME="${0##*/}"; readonly SCRIPT_NAME +SCRIPT_DIR="$(realpath "$(dirname "${0}")")"; readonly SCRIPT_DIR +SANDBOX_VERSION="$(tr -d '\n' < "${SCRIPT_DIR}/version.txt")"; readonly SANDBOX_VERSION +SANDBOX_SESSION="${SANDBOX_SESSION:-$(python3 -c 'import uuid; print(uuid.uuid4())')}"; readonly SANDBOX_SESSION +AGCLOUD="" +ATERRAFORM="" + +main() { + if [[ "${*}" = '' ]]; then + usage >&2 + exit 2 + fi + + # shellcheck disable=SC2064 + trap "$(shopt -p nocasematch)" RETURN + shopt -s nocasematch + init + + case "${1}" in + create) + shift 1 + create_subcommand "${@}" + ;; + delete) + shift 1 + delete_subcommand "${@}" + ;; + *) + help_subcommand "${@}" + ;; + esac +} +create_subcommand() { + parse_args "${@}" + + ### Validate ### + x_exit_if_no_auth_token + if [[ -z "${PROJECT_ID}" ]]; then + local GCP_CONFIG_PROJECT + GCP_CONFIG_PROJECT=$(gcloud config list --format 'value(core.project)') + warn "You did not provide project ID. ${SCRIPT_NAME} will launch Cloud Ops Sandbox in project ${GCP_CONFIG_PROJECT}." + sleep 1 + echo "To continue, type 1 for 'yes':" + select opt in "yes" "no"; do + if [[ "${opt}" == "yes" ]]; then + PROJECT_ID="${GCP_CONFIG_PROJECT}" + break + elif [[ "${opt}" == "no" ]]; then + exit 0 + fi + done + elif [[ -z $(gcloud projects list --filter="project_id:${PROJECT_ID}") ]]; then + fatal "You need to provide a valid project ID." + exit 2 + fi + + ### Configre ### + prepare_terraform_state + clean_cached_tf_state + configure_terraform_input_vars + + pushd "${SCRIPT_DIR}/terraform" > /dev/null + { + configure_kustomization + terraform init -backend-config "bucket=${TF_BUCKET_NAME}" -backend-config "prefix=${TERRAFORM_PREFIX}" -lockfile=false && \ + terraform apply -auto-approve -var-file="${tf_FILE_LOCATION}" && \ + print_launch_instructions + } + popd > /dev/null + mv "${KUSTOMIZE_FILE}.origin" "${KUSTOMIZE_FILE}" +} +delete_subcommand() { + parse_args "${@}" + + ### Validate ### + x_exit_if_no_auth_token + if [[ -z "${PROJECT_ID}" || -z $(gcloud projects list --filter="project_id:${PROJECT_ID}") ]]; then + fatal "You need to provide a valid project ID." + fi + if ! does_terraform_state_exist; then + fatal "Project ${PROJECT_ID} does not run Cloud Ops Sandbox." + fi + + ### Configure ### + clean_cached_tf_state + configure_terraform_input_vars + + pushd "${SCRIPT_DIR}/terraform" > /dev/null + { + terraform init -backend-config "bucket=${TF_BUCKET_NAME}" -backend-config "prefix=${TERRAFORM_PREFIX}" -lockfile=false && \ + terraform destroy -auto-approve -var-file="${tf_FILE_LOCATION}" && \ + info "Successfully deleted Cloud Ops Sandbox from ${PROJECT_ID} project." + } + popd > /dev/null +} +help_subcommand() { + local PRINT_HELP; PRINT_HELP=0 + local PRINT_VERSION; PRINT_VERSION=0 + + while [[ $# != 0 ]]; do + case "${1}" in + -h | --help) + PRINT_HELP=1 + shift 1 + ;; + --version) + PRINT_VERSION=1 + shift 1 + ;; + *) + fatal_with_usage "Unknown option ${1}" + ;; + esac + done + + if [[ "${PRINT_HELP}" -eq 1 || "${PRINT_VERSION}" -eq 1 ]]; then + if [[ "${PRINT_VERSION}" -eq 1 ]]; then + version_message + else + usage + fi + exit + fi +} + +init() { + ATERRAFORM="$(which terraform || true)"; readonly ATERRAFORM; + AGCLOUD="$(which gcloud || true)"; readonly AGCLOUD; + PROJECT_ID="" + CLUSTER_LOCATION="" + CLUSTER_NAME="" + TERRAFORM_PREFIX="" + SKIP_LOADGENERATOR=0 + SKIP_ASM=0 + VERBOSE=0 + CLOUDOPS_SANDBOX_POOL_CFG=${CLOUDOPS_SANDBOX_POOL_CFG:-} +} + +### Support functions ### + +warn() { + info "[WARNING]: ${1}" >&2 +} + +error() { + info "[ERROR]: ${1}" >&2 +} + +info() { + if hash ts 2>/dev/null && [[ "${VERBOSE}" -eq 1 ]]; then + echo "${SCRIPT_NAME}: ${1}" | TZ=utc ts '%Y-%m-%dT%.T' >&2 + else + echo "${SCRIPT_NAME}: ${1}" >&2 + fi +} + +fatal() { + error "${1}" + exit 2 +} + +fatal_with_usage() { + error "${1}" + usage_short >&2 + exit 2 +} + +version_message() { + echo "${VERSION}" +} + +usage() { + cat << EOF +${SCRIPT_NAME} $(version_message) +usage: ${SCRIPT_NAME} [SUBCOMMAND] [OPTION]... + +Create or destroy Cloud Ops Sandbox in a Google Cloud environment. Options +specified over flags + +SUBCOMMANDS: + create Create will attempt to launch a new Cloud + Ops Sandbox + delete Delete will destroy resources and configurations + of the Cloud Ops Sandbox from the defined + Google Cloud environment. + +OPTIONS: + -l|--cluster_location The GCP location of the target cluster. + -n|--cluster_name The name of the target cluster. + -p|--project_id The GCP project ID. + --skip-asm (Optional) Set to not install Anthos + Service Mesh. Default is false. + --skip-loadgenerator (Optional) Set to not deploy load + generator. Default is false. + --terraform-prefix (Optional) Customize Terraform state + storage prefix to store multiple states + in the same project. Default is ''. + -v|--verbose Print commands before and after execution. + -h|--help Show this message and exit. + --version Print the version of this tool and exit. +EOF +} + +####### +# run_command takes a list of arguments that represents a command +# If DRY_RUN or VERBOSE is enabled, it will print the command, and if DRY_RUN is +# not enabled it runs the command. +####### +run_command() { + if [[ "${VERBOSE}" -eq 0 ]]; then + "${@}" 2>/dev/null + return "$?" + fi + info "Running: '${*}'" + info "-------------" + local RETVAL + { "${@}"; RETVAL="$?"; } || true + return $RETVAL +} + +####### +# retry takes an integer N as the first argument, and a list of arguments +# representing a command afterwards. It will retry the given command up to N +# times before returning 1. If the command is kubectl, it will try to +# re-get credentials in case something caused the k8s IP to change. +####### +retry() { + local MAX_TRIES; MAX_TRIES="${1}"; + shift 1 + for i in $(seq 0 "${MAX_TRIES}"); do + if [[ "${i}" -eq "${MAX_TRIES}" ]]; then + break + fi + { "${@}" && return 0; } || true + warn "Failed, retrying...($((i+1)) of ${MAX_TRIES})" + sleep 2 + done + local CMD="'$*'" + warn "Command $CMD failed." + false +} + +### Convenience functions #### + +gcloud() { + run_command "${AGCLOUD}" "${@}" +} + +terraform() { + run_command "${ATERRAFORM}" "${@}" +} + +arg_required() { + if [[ ! "${2:-}" || "${2:0:1}" = '-' ]]; then + fatal "Option ${1} requires an argument." + fi +} + +parse_args() { + local PRINT_HELP; PRINT_HELP=0 + local PRINT_VERSION; PRINT_VERSION=0 + + # shellcheck disable=SC2064 + trap "$(shopt -p nocasematch)" RETURN + shopt -s nocasematch + + while [[ $# != 0 ]]; do + case "${1}" in + -l | --cluster_location | --cluster-location) + arg_required "${@}" + CLUSTER_LOCATION="${2}"; readonly CLUSTER_LOCATION + shift 2 + ;; + -n | --cluster_name | --cluster-name) + arg_required "${@}" + CLUSTER_NAME="${2}"; readonly CLUSTER_NAME + shift 2 + ;; + -p | --project_id | --project-id) + arg_required "${@}" + PROJECT_ID="${2}"; readonly PROJECT_ID + shift 2 + ;; + --terraform_prefix | --terraform-prefix) + arg_required "${@}" + TERRAFORM_PREFIX="${2}"; readonly TERRAFORM_PREFIX + shift 2 + ;; + --skip_loadgenerator | --skip-loadgenerator) + SKIP_LOADGENERATOR=1; readonly SKIP_LOADGENERATOR + shift 1 + ;; + --skip_asm | --skip-asm) + SKIP_ASM=1; readonly SKIP_ASM + shift 1 + ;; + -v | --verbose) + VERBOSE=1; readonly VERBOSE + shift 1 + ;; + -h | --help) + PRINT_HELP=1; readonly PRINT_HELP + shift 1 + ;; + --version) + PRINT_VERSION=1; readonly PRINT_VERSION + shift 1 + ;; + *) + fatal_with_usage "Unknown option ${1}" + ;; + esac + done + + if [[ "${PRINT_HELP}" -eq 1 || "${PRINT_VERSION}" -eq 1 ]]; then + if [[ "${PRINT_VERSION}" -eq 1 ]]; then + version_message + else + usage + fi + exit + fi +} + +send_telemetry() { + if [[ $# -lt 1 ]]; then + fatal "Missing event argument" + fi + local EVENT_NAME="${1}" + local TIMESTAMP; TIMESTAMP=$(date --utc +%s.%N) + local OBFUSCATED_PROJECT_ID; OBFUSCATED_PROJECT_ID="$(echo "${PROJECT_ID}" | sha256sum | sed 's/ -//')" + gcloud pubsub topics publish "telemetry_test" \ + --user-output-enabled=false \ + --project "stackdriver-sandbox-230822" \ + --message="{ \ + \"session\":\"${SANDBOX_SESSION}\", \ + \"project\":\"${OBFUSCATED_PROJECT_ID}\", \ + \"event\":\"${EVENT_NAME}\", \ + \"datetime\":\"${TIMESTAMP}\", \ + \"version\":\"${SANDBOX_VERSION}\"}" +} + +x_exit_if_no_auth_token() { + local AUTHTOKEN; AUTHTOKEN="$(get_auth_token)" + if [[ -z "${AUTHTOKEN}" ]]; then + { read -r -d '' MSG; validation_error "${MSG}"; } <> "${tf_FILE_LOCATION}" +} + +configure_terraform_input_vars() { + tf_FILE_LOCATION="$(mktemp).tfvars"; readonly tf_FILE_LOCATION + + local CONTEXT_TFVARS; CONTEXT_TFVARS=$(cat <| "${tf_FILE_LOCATION}" + if [ -n "" ]; then + echo "? = \"${}\"" >> "${tf_FILE_LOCATION}" + fi + + if [[ -n "${CLUSTER_NAME}" ]]; then + append_to_terraform_config "gke_cluster_name" "${CLUSTER_NAME}" + fi + if [[ -n "${CLUSTER_LOCATION}" ]]; then + append_to_terraform_config "gke_cluster_location" "${CLUSTER_LOCATION}" + fi + append_to_terraform_config "enable_asm" "$([ "${SKIP_ASM}" == "1" ] && echo "false" || echo "true")" + if [[ -n "${CLOUDOPS_SANDBOX_POOL_CFG}" ]]; then + append_to_terraform_config "gke_node_pool" "${CLOUDOPS_SANDBOX_POOL_CFG}" + fi +} + +configure_kustomization() { + KUSTOMIZE_FILE="${SCRIPT_DIR}/kustomize/online-boutique/kustomization.yaml"; readonly KUSTOMIZE_FILE + cp "${KUSTOMIZE_FILE}" "${KUSTOMIZE_FILE}.origin" > /dev/null + local SED_EXPRESSION; SED_EXPRESSION="" + + # uncomment 'without-loadgenerator' component if skip_loadgen is set + if [[ "${SKIP_LOADGENERATOR}" == "1" ]]; then + SED_EXPRESSION+=" -E '/without-loadgenerator(\?version\=v?[0-9]+\.[0-9]+\.[0-9]+)?$/s/^#//'" + fi + # uncomment 'service-mesh-istio' component if skip_asm is NOT set + if [[ "${SKIP_ASM}" != "1" ]]; then + SED_EXPRESSION+=" -E '/service-mesh-istio(\?version\=v?[0-9]+\.[0-9]+\.[0-9]+)?$/s/^#//'" + fi + if [[ -n "${SED_EXPRESSION}" ]]; then + eval "sed ${SED_EXPRESSION} ${KUSTOMIZE_FILE}.origin >| ${KUSTOMIZE_FILE}" + fi +} + +print_launch_instructions() { + local EXTERNAL_IP + EXTERNAL_IP="$(terraform output --raw frontend_external_ip)" + + cat < 0 ? "-${var.state_prefix}" : "" + + depends_on = [ + null_resource.wait_pods_are_ready, + ] +} diff --git a/provisioning/terraform/gke.tf b/provisioning/terraform/gke.tf new file mode 100644 index 000000000..acc062b16 --- /dev/null +++ b/provisioning/terraform/gke.tf @@ -0,0 +1,81 @@ +# Copyright 2023 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. + +locals { + location_label = length(split("-", var.gke_cluster_location)) == 2 ? "--region" : (length(split("-", var.gke_cluster_location)) == 3 ? "--zone" : "--location") + resource_labels = var.enable_asm ? { "mesh_id" = "proj-${data.google_project.info.number}" } : {} +} + +resource "google_container_cluster" "sandbox" { + name = var.gke_cluster_name + location = var.gke_cluster_location + + release_channel { + channel = "STABLE" + } + + gateway_api_config { + channel = "CHANNEL_STANDARD" + } + + resource_labels = local.resource_labels + + description = "Provisioned for Cloud Ops Sandbox version ${file("../version.txt")}" + + # Enables Workload Identity + workload_identity_config { + workload_pool = "${data.google_project.info.project_id}.svc.id.goog" + } + + # Configures default node pool + node_pool { + initial_node_count = var.gke_node_pool.initial_node_count + + node_config { + machine_type = var.gke_node_pool.machine_type + labels = var.gke_node_pool.labels + oauth_scopes = ["https://www.googleapis.com/auth/cloud-platform"] + + # Enables Workload Identity + workload_metadata_config { + mode = "GKE_METADATA" + } + } + + dynamic "autoscaling" { + for_each = var.gke_node_pool.autoscaling != null ? [var.gke_node_pool.autoscaling] : [] + content { + min_node_count = autoscaling.value.min_node_count + max_node_count = autoscaling.value.max_node_count + } + } + } + + depends_on = [ + module.enable_google_apis + ] +} + +module "gcloud" { + source = "terraform-google-modules/gcloud/google" + version = "~> 3.1.0" + + platform = "linux" + additional_components = ["kubectl", "beta"] + + create_cmd_entrypoint = "gcloud" + # Module does not support explicit dependency + # Use 'local.cluster_name' to enforce implicit dependency because 'depends_on' is not available for this module + create_cmd_body = "container clusters get-credentials ${resource.google_container_cluster.sandbox.name} ${local.location_label}=${resource.google_container_cluster.sandbox.location} --project=${var.gcp_project_id}" +} diff --git a/provisioning/terraform/monitoring/README.md b/provisioning/terraform/monitoring/README.md new file mode 100644 index 000000000..efeead5d5 --- /dev/null +++ b/provisioning/terraform/monitoring/README.md @@ -0,0 +1,28 @@ +# Monitoring Terraform Module + +This folder includes Terraform configuration files that implement the Monitoring module for Cloud Ops Sandbox. + +> **Note:** The module uses [Google][] terraform provider (~> 4.54.0) and assumes that the provider is _ALREADY_ configured in the calling configuration. + +## Module arguments + +The following table describes all input arguments the module accepts: + +| Name | Type | Is required | Description | +| --- | --- | -+- | --- | +| filepath_configuration | `string` | | A path to the root folder storing configuration files and templates. The relative path should be defined relative to the root terraform folder | +| frontend_external_ip | `string` | ✔️ | A valid IPv4 address of the publicly available endpoint of the frontend service | +| gcp_project_id | `string` | ✔️ | A project id of the GCP project that hosts Cloud Ops Sandbox | +| notification_channel_email | `string` || A valid email address to be used as a destination for alert notifications | + +## What's included + +The module provisions Cloud Monitoring dashboards, uptime checks and alerts based on the provided configuration. +Additionally it provisions log-based metrics and configures SLOs for auto-detected and custom services. + +> **Note** +> The module creates an opinionated observability artifacts to demonstrate best +> practices in capturing various observability signals using Cloud Operations +> suite of services. + +[Google]: https://registry.terraform.io/providers/hashicorp/google/latest/docs diff --git a/provisioning/terraform/monitoring/alerts.tf b/provisioning/terraform/monitoring/alerts.tf new file mode 100644 index 000000000..c026120fa --- /dev/null +++ b/provisioning/terraform/monitoring/alerts.tf @@ -0,0 +1,96 @@ +# Copyright 2023 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. + +/* + * Uptime check policy: at least 2 checks failed during 300s + */ +resource "google_monitoring_alert_policy" "frontend_check_alert" { + display_name = "HTTP Uptime Check Alerting Policy" + combiner = "OR" + conditions { + display_name = "HTTP Uptime Check Alert" + condition_threshold { + filter = "metric.type=\"monitoring.googleapis.com/uptime_check/check_passed\" AND metric.label.check_id=\"${google_monitoring_uptime_check_config.frontend_http_check.uptime_check_id}\" AND resource.type=\"uptime_url\"" + duration = "300s" + comparison = "COMPARISON_GT" + aggregations { + # the alignment sets the window over which the metric is viewed + alignment_period = "1200s" + per_series_aligner = "ALIGN_NEXT_OLDER" + cross_series_reducer = "REDUCE_COUNT_FALSE" + group_by_fields = ["resource.label.*"] + } + threshold_value = "2" + trigger { + count = "1" + } + } + } + notification_channels = ["${google_monitoring_notification_channel.email_notification.id}"] +} + +/* + * SLO alert policies: burn rate continues during 60s in window of 1h + * (requires enable_asm to be `true`) + */ +resource "google_monitoring_alert_policy" "availability_slo_burn_alert" { + count = var.enable_asm ? length(local.slo_services) : 0 + display_name = "${local.slo_services[count.index].title} Availability SLO Burn Alert" + combiner = "AND" + conditions { + display_name = "SLO burn rate alert for availability SLO with a threshold of ${local.burn_rate}" + condition_threshold { + + # This filter alerts on burn rate over the past 60 minutes + # The service is defined by the unique Istio string that is automatically created + filter = "select_slo_burn_rate(\"${module.slo_service[count.index].qualified_name}/serviceLevelObjectives/${google_monitoring_slo.service_availability[count.index].slo_id}\", 60m)" + threshold_value = local.burn_rate + comparison = "COMPARISON_GT" + duration = "60s" + } + } + documentation { + content = < /dev/null +EOF + } +} diff --git a/terraform/05_loadgen.tf b/provisioning/terraform/monitoring/uptime_checks.tf similarity index 56% rename from terraform/05_loadgen.tf rename to provisioning/terraform/monitoring/uptime_checks.tf index 2c028c618..e9075f166 100644 --- a/terraform/05_loadgen.tf +++ b/provisioning/terraform/monitoring/uptime_checks.tf @@ -1,4 +1,4 @@ -# Copyright 2020 Google LLC +# Copyright 2023 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,13 +12,22 @@ # See the License for the specific language governing permissions and # limitations under the License. -module "loadgen" { - source = "./loadgen" +# Check http://frontend-external/ +resource "google_monitoring_uptime_check_config" "frontend_http_check" { + display_name = "HTTP Uptime Check" + timeout = "10s" + period = "60s" - count = var.skip_loadgen ? 0 : 1 + http_check { + path = "/" + port = "80" + } - external_ip = data.external.terraform_vars.result.external_ip - project_id = data.google_project.project.project_id - - depends_on = [null_resource.delay, null_resource.ratingservice_address_rewrite] + monitored_resource { + type = "uptime_url" + labels = { + project_id = var.gcp_project_id + host = var.frontend_external_ip + } + } } diff --git a/provisioning/terraform/monitoring/variables.tf b/provisioning/terraform/monitoring/variables.tf new file mode 100644 index 000000000..46051fadb --- /dev/null +++ b/provisioning/terraform/monitoring/variables.tf @@ -0,0 +1,71 @@ +# Copyright 2023 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. + +# Required input variables +variable "frontend_external_ip" { + type = string + description = "Publicly available IP of the frontend service" + validation { + condition = can(regex("^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$", var.frontend_external_ip)) + error_message = "The value should be a valid IPv4 address" + } +} + +variable "gcp_project_id" { + type = string + description = "The GCP project ID to apply this config to" +} + +variable "gcp_project_number" { + type = string + description = "The GCP project number to apply this config to" +} + +variable "enable_asm" { + type = bool + description = "Flags to provision ASM related resources" +} + +# Optional input variables +variable "filepath_configuration" { + type = string + description = "Path to monitoring resource configuration files. Relative path should be defined relative to the root terraform folder." + default = "../configurations/online-boutique" +} + +variable "gke_cluster_name" { + type = string + description = "Name given to the new GKE cluster" + default = "cloud-ops-sandbox" +} + +variable "notification_channel_email" { + type = string + description = "Email address to use for alert notification channel." + validation { + condition = can(regex("^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$", var.notification_channel_email)) + error_message = "The value should be a valid email address" + } + default = "devops@acme.com" +} + +variable "name_suffix" { + type = string + description = "Custom suffix to allow provisioning multiple copies of the resource within the same GCP project" + validation { + condition = can(regex("^$|^[\\w_-]{1,100}$", var.name_suffix)) + error_message = "The value should be a valid email address" + } + default = "" +} diff --git a/provisioning/terraform/online-boutique.tf b/provisioning/terraform/online-boutique.tf new file mode 100644 index 000000000..2c71a5506 --- /dev/null +++ b/provisioning/terraform/online-boutique.tf @@ -0,0 +1,115 @@ +# Copyright 2023 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. + +locals { + service_name = var.enable_asm ? "istio-gateway" : "frontend-external" + namespace_name = "default" +} + +# Configure default compute SA to be used by K8s default SA in default ns +data "google_compute_default_service_account" "default" { + # ensure that default compute service account is provisioned + depends_on = [ + module.gcloud, + ] +} + +resource "google_project_iam_binding" "default_compute_as_trace_agent" { + project = data.google_project.info.project_id + role = "roles/cloudtrace.agent" + + members = [ + "serviceAccount:${data.google_compute_default_service_account.default.email}", + ] +} + +resource "google_service_account_iam_binding" "default_compute_as_k8s_sa" { + service_account_id = data.google_compute_default_service_account.default.name + role = "roles/iam.workloadIdentityUser" + + members = [ + "serviceAccount:${data.google_project.info.project_id}.svc.id.goog[default/default]", + ] +} + +resource "kubernetes_annotations" "default_sa" { + api_version = "v1" + kind = "ServiceAccount" + metadata { + name = "default" + namespace = "default" + } + annotations = { + "iam.gke.io/gcp-service-account" = data.google_compute_default_service_account.default.email + } +} + +# NOTE: when re-applying the previous resources might not be disposed +resource "null_resource" "online_boutique_kustomization" { + triggers = { + kustomize_path = sha256(var.filepath_manifest) + } + provisioner "local-exec" { + interpreter = ["bash", "-exc"] + command = "kubectl apply -k ${var.filepath_manifest} -n ${local.namespace_name}" + } + + depends_on = [ + module.gcloud, + null_resource.install_asm + ] +} + +# Wait condition for all resources to be ready before finishing +resource "null_resource" "wait_pods_are_ready" { + provisioner "local-exec" { + interpreter = ["bash", "-exc"] + command = "kubectl wait --for=condition=ready pods --all -n ${local.namespace_name} --timeout=5m 2>/dev/null" + } + + depends_on = [ + null_resource.online_boutique_kustomization + ] +} + +# waiting for external provisioning of LB +resource "null_resource" "wait_service_conditions" { + provisioner "local-exec" { + interpreter = ["bash", "-exc"] + command = </dev/null +EOF + } + + depends_on = [ + null_resource.online_boutique_kustomization + ] +} + +data "kubernetes_service" "frontend_external_service" { + metadata { + name = local.service_name + namespace = local.namespace_name + } + # Kubernetes data sources do not support implicit dependencies + # https://github.com/hashicorp/terraform-provider-kubernetes/issues/1867 + depends_on = [ + null_resource.wait_service_conditions + ] +} diff --git a/terraform/04_ratingservice.tf b/provisioning/terraform/output.tf similarity index 63% rename from terraform/04_ratingservice.tf rename to provisioning/terraform/output.tf index 335637deb..11aa702b9 100644 --- a/terraform/04_ratingservice.tf +++ b/provisioning/terraform/output.tf @@ -1,10 +1,10 @@ -# Copyright 2020 Google LLC +# Copyright 2023 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 +# 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, @@ -12,9 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -module "ratingservice" { - source = "./ratingservice" - count = var.skip_ratingservice ? 0 : 1 - gcp_project_id = var.project_id - gcp_region_name = var.appengine_region +output "frontend_external_ip" { + value = length(data.kubernetes_service.frontend_external_service.status) > 0 ? data.kubernetes_service.frontend_external_service.status[0].load_balancer[0].ingress[0].ip : null } diff --git a/provisioning/terraform/project.tf b/provisioning/terraform/project.tf new file mode 100644 index 000000000..fb9576d24 --- /dev/null +++ b/provisioning/terraform/project.tf @@ -0,0 +1,42 @@ +# Copyright 2023 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. + +# Enable Google Cloud APIs +locals { + base_apis = [ + "clouderrorreporting.googleapis.com", + "cloudprofiler.googleapis.com", + "container.googleapis.com", /* compute.googleapis.com is provisioned as a dependency */ + ] + mesh_apis = [ + "mesh.googleapis.com", + # "meshtelemetry.googleapis.com", + "cloudresourcemanager.googleapis.com", + ] +} + +# Enable Google Cloud APIs +module "enable_google_apis" { + source = "terraform-google-modules/project-factory/google//modules/project_services" + version = "~> 14.1.0" + + project_id = var.gcp_project_id + disable_services_on_destroy = false + + activate_apis = concat(local.base_apis, var.enable_asm ? local.mesh_apis : []) +} + +data "google_project" "info" { + project_id = var.gcp_project_id +} diff --git a/provisioning/terraform/providers.tf b/provisioning/terraform/providers.tf new file mode 100644 index 000000000..b917bbd36 --- /dev/null +++ b/provisioning/terraform/providers.tf @@ -0,0 +1,73 @@ +# Copyright 2023 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. + + +# We use gcs as our backend, so the state file will be stored +# in a storage bucket. Since the bucket must preexists, we will create +# the project and bucket outside Terraform. Also since the configuration +# of bucket can't be a variable, we create an empty config and modify it +# in the data section. + +terraform { + # The module has 0.12 syntax and is not compatible with any versions below 0.12. + required_version = "~> 1.4.1" + + required_providers { + google = { + source = "hashicorp/google" + version = "~> 4.54.0" + } + google-beta = { + source = "hashicorp/google-beta" + version = "4.54.0" + } + null = { + source = "hashicorp/null" + version = "~>3.2.1" + } + kubernetes = { + source = "hashicorp/kubernetes" + version = "~>2.18.1" + } + } + backend "gcs" {} +} + +# tflint-ignore: terraform_unused_declarations +data "terraform_remote_state" "state" { + backend = "gcs" + config = { + bucket = var.state_bucket_name + prefix = var.state_prefix + } +} + +provider "google" { + project = var.gcp_project_id +} + +# Retrieve an access token as the Terraform runner +data "google_client_config" "default" {} + +provider "google-beta" { + project = var.gcp_project_id +} + +provider "kubernetes" { + host = "https://${resource.google_container_cluster.sandbox.endpoint}" + token = data.google_client_config.default.access_token + cluster_ca_certificate = base64decode( + resource.google_container_cluster.sandbox.master_auth[0].cluster_ca_certificate, + ) +} diff --git a/provisioning/terraform/scripts/install_asm.sh b/provisioning/terraform/scripts/install_asm.sh new file mode 100755 index 000000000..63381b70f --- /dev/null +++ b/provisioning/terraform/scripts/install_asm.sh @@ -0,0 +1,140 @@ +#!/bin/bash +# Copyright 2023 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. + +WORK_DIR=$(realpath "$(dirname "$0")") + +SCRIPT_NAME="${0##*/}"; readonly SCRIPT_NAME +ASM_VERSION=1.16; readonly ASM_VERSION + +pushd() { + command pushd "$@" > /dev/null || return 0 +} + +popd() { + command popd > /dev/null || return 0 +} + +info() { + echo "⚙️ ${SCRIPT_NAME}: ${1}" >&2 +} + +x_usage() { + cat << EOF +${SCRIPT_NAME} +usage: ${SCRIPT_NAME} [PARAMETER]... + +Configures managed Anthos Service Mesh (ASM) on the GKE cluster. + +PARAMETERS: + --channel (Optional) Managed ASM revision + channel. Should be one of the following: + 'stable', 'rapid' or 'regular'. + Default is 'stable'. + --cluster_location Zone or region name where the cluster + is provisioned. + --cluster_name The name of GKE cluster. + allow external VM workloads. + --project Google Cloud Project ID that + hosts the cluster. +EOF +} + +fatal() { + error "${1}" + exit 2 +} + +arg_required() { + if [[ ! "${2:-}" || "${2:0:1}" = '-' ]]; then + fatal "Option ${1} requires an argument." + fi +} + +parse_args() { + while [[ $# != 0 ]]; do + case "${1}" in + --project) + arg_required "${@}" + PROJECT_ID="${2}" + shift 2 + ;; + --channel) + arg_required "${@}" + CHANNEL="${2}" + shift 2 + ;; + --cluster_name) + arg_required "${@}" + CLUSTER_NAME="${2}" + shift 2 + ;; + --cluster_location) + arg_required "${@}" + CLUSTER_LOCATION="${2}" + shift 2 + ;; + -h | --help) + x_usage + exit + ;; + *) + x_usage + break + ;; + esac + done + + if [[ -z ${PROJECT_ID} ]] || [[ -z ${CLUSTER_NAME} ]] || [[ -z ${CLUSTER_LOCATION} ]]; then + info "Need to define project id, GKE cluster name and location" + exit 2 + fi + if [[ "${CHANNEL}" != "stable" && "${CHANNEL}" != "regular" && "${CHANNEL}" != "rapid" ]]; then + if [[ -n "${CHANNEL}" ]]; then + info "Valid channel is not found. 'stable' channel will be used." + fi + CHANNEL="stable" + fi +} + +# shellcheck disable=SC2164 +pushd "${WORK_DIR}" + +parse_args "$@" + +info "Downloading asmcli version ${ASM_VERSION}" +curl -s https://storage.googleapis.com/csm-artifacts/asm/asmcli_"${ASM_VERSION}" > asmcli +chmod -f +x asmcli + +info "Installing managed ASM version ${ASM_VERSION} for GKE cluster ${CLUSTER_NAME} ..." + +./asmcli install \ + --project_id "${PROJECT_ID}" \ + --cluster_name "${CLUSTER_NAME}" \ + --cluster_location "${CLUSTER_LOCATION}" \ + --fleet_id "${PROJECT_ID}" \ + --enable_all \ + --option prometheus-and-stackdriver \ + --managed \ + --channel "${CHANNEL}" \ + --use_managed_cni + +info "Annotating default namespaces for istio injection ..." +kubectl label namespace default istio-injection- istio.io/rev=asm-managed-"${CHANNEL}" --overwrite + +# clean up +rm ./asmcli + +# shellcheck disable=SC2164 +popd diff --git a/provisioning/terraform/variables.tf b/provisioning/terraform/variables.tf new file mode 100644 index 000000000..bfbe19e0b --- /dev/null +++ b/provisioning/terraform/variables.tf @@ -0,0 +1,89 @@ +/** + * Copyright 2023 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. + */ + +# Required input variables +variable "gcp_project_id" { + type = string + description = "The GCP project ID to apply this config to" +} + +variable "state_bucket_name" { + type = string + description = "The GCS bucket URL where Terraform stores the state" +} + +# Optional input variables +variable "asm_channel" { + type = string + description = "Defines one of the following managed ASM channels/revisions: 'rapid', 'regular' or stable'" + default = "stable" + validation { + condition = can(regex("^(rapid|regular|stable)$", var.asm_channel)) + error_message = "ASM channel/revision can be only 'rapid', 'regular' or stable'" + } +} + +variable "enable_asm" { + type = bool + description = "If true, installs Anthos Service Mesh (managed version of Istio) on the GKE cluster" + default = false +} + +variable "filepath_manifest" { + type = string + description = "Path to Kubernetes resources, written using Kustomize" + default = "../kustomize/online-boutique/" +} + +variable "gke_cluster_name" { + type = string + description = "Name given to the new GKE cluster" + default = "cloud-ops-sandbox" +} + +variable "gke_cluster_location" { + type = string + description = "Region or zone of the new GKE cluster" + default = "us-central1" +} + +# Default values for node pool support connecting the cluster to ASM +# https://cloud.google.com/service-mesh/docs/unified-install/anthos-service-mesh-prerequisites#cluster_requirements +variable "gke_node_pool" { + type = object({ + initial_node_count = number + labels = map(string) + machine_type = string + + autoscaling = object({ + max_node_count = number + min_node_count = number + }) + }) + description = "Initial settings and autoscale configuration of the GKE cluster's default node pool" + default = { + initial_node_count = 4 + labels = {} + machine_type = "e2-standard-4" + autoscaling = null + } +} + +variable "state_prefix" { + type = string + description = "Use to store multiple states when provisioning with the same state_bucket_name" + default = "" +} diff --git a/provisioning/version.txt b/provisioning/version.txt new file mode 100644 index 000000000..6b0feffff --- /dev/null +++ b/provisioning/version.txt @@ -0,0 +1 @@ +0.9.0-development \ No newline at end of file diff --git a/skaffold.yaml b/skaffold.yaml deleted file mode 100644 index b3bad6fa1..000000000 --- a/skaffold.yaml +++ /dev/null @@ -1,78 +0,0 @@ -# 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: skaffold/v1 -kind: Config -build: - artifacts: - - image: gcr.io/stackdriver-sandbox-230822/sandbox/emailservice - context: src/emailservice - - image: gcr.io/stackdriver-sandbox-230822/sandbox/productcatalogservice - context: src/productcatalogservice - - image: gcr.io/stackdriver-sandbox-230822/sandbox/recommendationservice - context: src/recommendationservice - - image: gcr.io/stackdriver-sandbox-230822/sandbox/shippingservice - context: src/shippingservice - - image: gcr.io/stackdriver-sandbox-230822/sandbox/checkoutservice - context: src/checkoutservice - - image: gcr.io/stackdriver-sandbox-230822/sandbox/paymentservice - context: src/paymentservice - - image: gcr.io/stackdriver-sandbox-230822/sandbox/currencyservice - context: src/currencyservice - - image: gcr.io/stackdriver-sandbox-230822/sandbox/cartservice - context: src/cartservice - - image: gcr.io/stackdriver-sandbox-230822/sandbox/frontend - context: src/frontend - - image: gcr.io/stackdriver-sandbox-230822/sandbox/adservice - context: src/adservice - # Intentionally leave out src/loadgenerator. It should be deployed externally - # from the microservices cluster to simulate more realistic network latency. - # (Real users won't be making requests from inside the kubernetes cluster.) - tagPolicy: - gitCommit: {} -deploy: - statusCheckDeadlineSeconds: 120 - kubectl: - manifests: - - ./kubernetes-manifests/adservice.yaml - - ./kubernetes-manifests/cartservice.yaml - - ./kubernetes-manifests/checkoutservice.yaml - - ./kubernetes-manifests/currencyservice.yaml - - ./kubernetes-manifests/emailservice.yaml - - ./kubernetes-manifests/frontend.yaml - - ./kubernetes-manifests/opentelemetrycollector.yaml - - ./kubernetes-manifests/paymentservice.yaml - - ./kubernetes-manifests/productcatalogservice.yaml - - ./kubernetes-manifests/recommendationservice.yaml - - ./kubernetes-manifests/redis.yaml - - ./kubernetes-manifests/shippingservice.yaml -profiles: -# "gcb" profile allows building and pushing the images -# on Google Container Builder without requiring docker -# installed on the developer machine. However, note that -# since GCB does not cache the builds, each build will -# start from scratch and therefore take a long time. -# -# This is not used by default. To use it, run: -# skaffold run -p gcb -- name: gcb - build: - googleCloudBuild: - diskSizeGb: 300 - machineType: N1_HIGHCPU_32 - timeout: 4000s -- name: local - build: - local: - push: false diff --git a/src/.gitignore b/src/.gitignore deleted file mode 100644 index db07b3a55..000000000 --- a/src/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# 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/ diff --git a/src/adservice/.gitignore b/src/adservice/.gitignore deleted file mode 100644 index 18097156b..000000000 --- a/src/adservice/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -*.iml -*.ipr -*.iws -.gradle/** -.idea/** -build/** - - diff --git a/src/adservice/Dockerfile b/src/adservice/Dockerfile deleted file mode 100644 index 2d7d1c37a..000000000 --- a/src/adservice/Dockerfile +++ /dev/null @@ -1,47 +0,0 @@ -# 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 openjdk:8-slim as builder - -WORKDIR /app - -COPY ["build.gradle", "gradlew", "./"] -COPY gradle gradle -RUN chmod +x gradlew -RUN ./gradlew downloadRepos - -COPY . . -RUN chmod +x gradlew -RUN ./gradlew installDist - -FROM openjdk:8-slim - -# Download Stackdriver Profiler Java agent -RUN apt-get -y update && apt-get install -qqy \ - wget \ - && rm -rf /var/lib/apt/lists/* -RUN mkdir -p /opt/cprof && \ - wget -q -O- https://storage.googleapis.com/cloud-profiler/java/latest/profiler_java_agent.tar.gz \ - | tar xzv -C /opt/cprof && \ - rm -rf profiler_java_agent.tar.gz - -RUN GRPC_HEALTH_PROBE_VERSION=v0.3.5 && \ - 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 /app . - -EXPOSE 9555 -ENTRYPOINT ["/app/build/install/hipstershop/bin/AdService"] diff --git a/src/adservice/README.md b/src/adservice/README.md deleted file mode 100644 index 599dbb7fb..000000000 --- a/src/adservice/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# Ad Service - -The Ad service provides advertisement based on context keys. If no context keys are provided then it returns random ads. - -## Building locally - -The Ad service uses gradlew to compile/install/distribute. Gradle wrapper is already part of the source code. To build Ad Service, run: - -``` -./gradlew installDist -``` -It will create executable script src/adservice/build/install/hipstershop/bin/AdService - -### Upgrading gradle version -If you need to upgrade the version of gradle then run - -``` -./gradlew wrapper --gradle-version -``` - -## Building docker image - -From `src/adservice/`, run: - -``` -docker build ./ -``` - diff --git a/src/adservice/build.gradle b/src/adservice/build.gradle deleted file mode 100644 index c99669af9..000000000 --- a/src/adservice/build.gradle +++ /dev/null @@ -1,125 +0,0 @@ -plugins { - id 'com.google.protobuf' version '0.8.16' - id 'com.github.sherter.google-java-format' version '0.9' - id 'idea' - id 'application' -} - -repositories { - mavenCentral() - mavenLocal() -} - -description = 'Ad Service' -group = "adservice" -version = "0.1.0-SNAPSHOT" - -def opencensusVersion = "0.27.0" -def grpcVersion = "1.32.1" -def jacksonVersion = "2.12.3" -def protocVersion = "3.12.3" - -tasks.withType(JavaCompile) { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 -} - -ext { - speed = project.hasProperty('speed') ? project.getProperty('speed') : false - offlineCompile = new File("$buildDir/output/lib") -} - -dependencies { - if (speed) { - implementation fileTree(dir: offlineCompile, include: '*.jar') - } else { - implementation "com.google.api.grpc:proto-google-common-protos:1.18.1", - "io.opencensus:opencensus-api:${opencensusVersion}", - "io.opencensus:opencensus-contrib-grpc-metrics:${opencensusVersion}", - "io.opencensus:opencensus-contrib-grpc-util:${opencensusVersion}", - "io.opencensus:opencensus-exporter-trace-jaeger:${opencensusVersion}", - "io.opencensus:opencensus-exporter-stats-stackdriver:${opencensusVersion}", - "io.opencensus:opencensus-exporter-trace-stackdriver:${opencensusVersion}", - "io.opencensus:opencensus-exporter-trace-logging:${opencensusVersion}", - "io.grpc:grpc-protobuf:${grpcVersion}", - "io.grpc:grpc-stub:${grpcVersion}", - "io.grpc:grpc-netty:${grpcVersion}", - "io.grpc:grpc-services:${grpcVersion}", - "org.apache.logging.log4j:log4j-core:2.16.0" - - runtimeOnly "com.fasterxml.jackson.core:jackson-core:${jacksonVersion}", - "com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}", - "io.opencensus:opencensus-contrib-log-correlation-log4j2:${opencensusVersion}", - "io.opencensus:opencensus-impl:${opencensusVersion}", - "io.netty:netty-tcnative-boringssl-static:2.0.39.Final" - } -} - -protobuf { - protoc { - artifact = "com.google.protobuf:protoc:${protocVersion}" - } - plugins { - grpc { - artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" - } - } - generateProtoTasks { - all()*.plugins { - grpc {} - } - ofSourceSet('main') - } -} - -googleJavaFormat { - toolVersion '1.7' -} - -// Inform IDEs like IntelliJ IDEA, Eclipse or NetBeans about the generated code. -sourceSets { - main { - java { - srcDirs 'hipstershop' - srcDirs 'build/generated/source/proto/main/java/hipstershop' - srcDirs 'build/generated/source/proto/main/grpc/hipstershop' - } - } -} - -startScripts.enabled = false - -// This to cache dependencies during Docker image building. First build will take time. -// Subsequent build will be incremental. -task downloadRepos(type: Copy) { - from configurations.compile - into offlineCompile - from configurations.runtime - into offlineCompile -} - -task adService(type: CreateStartScripts) { - mainClassName = 'hipstershop.AdService' - applicationName = 'AdService' - outputDir = new File(project.buildDir, 'tmp') - classpath = startScripts.classpath - defaultJvmOpts = - ["-Dlog4j2.contextDataInjector=io.opencensus.contrib.logcorrelation.log4j2.OpenCensusTraceContextDataInjector", - "-agentpath:/opt/cprof/profiler_java_agent.so=-cprof_service=adservice,-cprof_service_version=1.0.0"] -} - -task adServiceClient(type: CreateStartScripts) { - mainClassName = 'hipstershop.AdServiceClient' - applicationName = 'AdServiceClient' - outputDir = new File(project.buildDir, 'tmp') - classpath = startScripts.classpath - defaultJvmOpts = - ["-Dlog4j2.contextDataInjector=io.opencensus.contrib.logcorrelation.log4j2.OpenCensusTraceContextDataInjector", - "-agentpath:/opt/cprof/profiler_java_agent.so=-cprof_service=adserviceclient,-cprof_service_version=1.0.0"] -} - -applicationDistribution.into('bin') { - from(adService) - from(adServiceClient) - fileMode = 0755 -} diff --git a/src/adservice/genproto.sh b/src/adservice/genproto.sh deleted file mode 100755 index 36525e0d5..000000000 --- a/src/adservice/genproto.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/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. - -#!/bin/bash -e - -# protos are needed in adservice folder for compiling during Docker build. - -mkdir -p proto && \ -cp ../../pb/demo.proto src/main/proto diff --git a/src/adservice/gradle/wrapper/gradle-wrapper.jar b/src/adservice/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index f3d88b1c2..000000000 Binary files a/src/adservice/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/src/adservice/gradle/wrapper/gradle-wrapper.properties b/src/adservice/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 442d9132e..000000000 --- a/src/adservice/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/src/adservice/gradlew b/src/adservice/gradlew deleted file mode 100755 index 2fe81a7d9..000000000 --- a/src/adservice/gradlew +++ /dev/null @@ -1,183 +0,0 @@ -#!/usr/bin/env sh - -# -# Copyright 2015 the original author or 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 -# -# 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. -# - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=`expr $i + 1` - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -exec "$JAVACMD" "$@" diff --git a/src/adservice/gradlew.bat b/src/adservice/gradlew.bat deleted file mode 100644 index 9109989e3..000000000 --- a/src/adservice/gradlew.bat +++ /dev/null @@ -1,103 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/src/adservice/settings.gradle b/src/adservice/settings.gradle deleted file mode 100644 index 0bbe0117c..000000000 --- a/src/adservice/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'hipstershop' diff --git a/src/adservice/src/main/java/hipstershop/AdService.java b/src/adservice/src/main/java/hipstershop/AdService.java deleted file mode 100644 index a4713d650..000000000 --- a/src/adservice/src/main/java/hipstershop/AdService.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * 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 hipstershop; - -import com.google.common.collect.ImmutableListMultimap; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterables; -import hipstershop.Demo.Ad; -import hipstershop.Demo.AdRequest; -import hipstershop.Demo.AdResponse; -import io.grpc.Server; -import io.grpc.ServerBuilder; -import io.grpc.StatusRuntimeException; -import io.grpc.health.v1.HealthCheckResponse.ServingStatus; -import io.grpc.services.*; -import io.grpc.stub.StreamObserver; -import io.opencensus.common.Duration; -import io.opencensus.contrib.grpc.metrics.RpcViews; -import io.opencensus.exporter.stats.stackdriver.StackdriverStatsConfiguration; -import io.opencensus.exporter.stats.stackdriver.StackdriverStatsExporter; -import io.opencensus.exporter.trace.stackdriver.StackdriverTraceConfiguration; -import io.opencensus.exporter.trace.stackdriver.StackdriverTraceExporter; -import io.opencensus.trace.AttributeValue; -import io.opencensus.trace.Span; -import io.opencensus.trace.Tracer; -import io.opencensus.trace.Tracing; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Random; -import java.util.concurrent.TimeUnit; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -public final class AdService { - - private static final Logger logger = LogManager.getLogger(AdService.class); - private static final Tracer tracer = Tracing.getTracer(); - - private static int MAX_ADS_TO_SERVE = 2; - private Server server; - private HealthStatusManager healthMgr; - - private static final AdService service = new AdService(); - - private void start() throws IOException { - int port = Integer.parseInt(System.getenv("PORT")); - healthMgr = new HealthStatusManager(); - - server = - ServerBuilder.forPort(port) - .addService(new AdServiceImpl()) - .addService(healthMgr.getHealthService()) - .build() - .start(); - logger.info("Ad Service started, listening on " + port); - Runtime.getRuntime() - .addShutdownHook( - new Thread() { - @Override - public void run() { - // Use stderr here since the logger may have been reset by its JVM shutdown hook. - System.err.println("*** shutting down gRPC ads server since JVM is shutting down"); - AdService.this.stop(); - System.err.println("*** server shut down"); - } - }); - healthMgr.setStatus("", ServingStatus.SERVING); - } - - private void stop() { - if (server != null) { - healthMgr.clearStatus(""); - server.shutdown(); - } - } - - private static class AdServiceImpl extends hipstershop.AdServiceGrpc.AdServiceImplBase { - - /** - * Retrieves ads based on context provided in the request {@code AdRequest}. - * - * @param req the request containing context. - * @param responseObserver the stream observer which gets notified with the value of {@code - * AdResponse} - */ - @Override - public void getAds(AdRequest req, StreamObserver responseObserver) { - AdService service = AdService.getInstance(); - Span span = tracer.getCurrentSpan(); - try { - span.putAttribute("method", AttributeValue.stringAttributeValue("getAds")); - List allAds = new ArrayList<>(); - logger.info("received ad request (context_words=" + req.getContextKeysList() + ")"); - if (req.getContextKeysCount() > 0) { - span.addAnnotation( - "Constructing Ads using context", - ImmutableMap.of( - "Context Keys", - AttributeValue.stringAttributeValue(req.getContextKeysList().toString()), - "Context Keys length", - AttributeValue.longAttributeValue(req.getContextKeysCount()))); - for (int i = 0; i < req.getContextKeysCount(); i++) { - Collection ads = service.getAdsByCategory(req.getContextKeys(i)); - allAds.addAll(ads); - } - } else { - span.addAnnotation("No Context provided. Constructing random Ads."); - allAds = service.getRandomAds(); - } - if (allAds.isEmpty()) { - // Serve random ads. - span.addAnnotation("No Ads found based on context. Constructing random Ads."); - allAds = service.getRandomAds(); - } - AdResponse reply = AdResponse.newBuilder().addAllAds(allAds).build(); - responseObserver.onNext(reply); - responseObserver.onCompleted(); - } catch (StatusRuntimeException e) { - logger.log(Level.WARN, "GetAds Failed", e.getStatus()); - responseObserver.onError(e); - } - } - } - - private static final ImmutableListMultimap adsMap = createAdsMap(); - - private Collection getAdsByCategory(String category) { - return adsMap.get(category); - } - - private static final Random random = new Random(); - - private List getRandomAds() { - List ads = new ArrayList<>(MAX_ADS_TO_SERVE); - Collection allAds = adsMap.values(); - for (int i = 0; i < MAX_ADS_TO_SERVE; i++) { - ads.add(Iterables.get(allAds, random.nextInt(allAds.size()))); - } - return ads; - } - - private static AdService getInstance() { - return service; - } - - /** Await termination on the main thread since the grpc library uses daemon threads. */ - private void blockUntilShutdown() throws InterruptedException { - if (server != null) { - server.awaitTermination(); - } - } - - private static ImmutableListMultimap createAdsMap() { - Ad camera = - Ad.newBuilder() - .setRedirectUrl("/product/2ZYFJ3GM2N") - .setText("Film camera for sale. 50% off.") - .build(); - Ad lens = - Ad.newBuilder() - .setRedirectUrl("/product/66VCHSJNUP") - .setText("Vintage camera lens for sale. 20% off.") - .build(); - Ad recordPlayer = - Ad.newBuilder() - .setRedirectUrl("/product/0PUK6V6EV0") - .setText("Vintage record player for sale. 30% off.") - .build(); - Ad bike = - Ad.newBuilder() - .setRedirectUrl("/product/9SIQT8TOJO") - .setText("City Bike for sale. 10% off.") - .build(); - Ad baristaKit = - Ad.newBuilder() - .setRedirectUrl("/product/1YMWWN1N4O") - .setText("Home Barista kitchen kit for sale. Buy one, get second kit for free") - .build(); - Ad airPlant = - Ad.newBuilder() - .setRedirectUrl("/product/6E92ZMYYFZ") - .setText("Air plants for sale. Buy two, get third one for free") - .build(); - Ad terrarium = - Ad.newBuilder() - .setRedirectUrl("/product/L9ECAV7KIM") - .setText("Terrarium for sale. Buy one, get second one for free") - .build(); - return ImmutableListMultimap.builder() - .putAll("photography", camera, lens) - .putAll("vintage", camera, lens, recordPlayer) - .put("cycling", bike) - .put("cookware", baristaKit) - .putAll("gardening", airPlant, terrarium) - .build(); - } - - private static void initStackdriver() { - logger.info("Initialize StackDriver"); - - long sleepTime = 10; /* seconds */ - int maxAttempts = 5; - boolean statsExporterRegistered = false; - boolean traceExporterRegistered = false; - - for (int i = 0; i < maxAttempts; i++) { - try { - if (!traceExporterRegistered) { - StackdriverTraceExporter.createAndRegister( - StackdriverTraceConfiguration.builder().build()); - traceExporterRegistered = true; - } - if (!statsExporterRegistered) { - StackdriverStatsExporter.createAndRegister( - StackdriverStatsConfiguration.builder() - .setExportInterval(Duration.create(60, 0)) - .build()); - statsExporterRegistered = true; - } - } catch (Exception e) { - if (i == (maxAttempts - 1)) { - logger.log( - Level.WARN, - "Failed to register Stackdriver Exporter." - + " Tracing and Stats data will not reported to Stackdriver. Error message: " - + e.toString()); - } else { - logger.info("Attempt to register Stackdriver Exporter in " + sleepTime + " seconds "); - try { - Thread.sleep(TimeUnit.SECONDS.toMillis(sleepTime)); - } catch (Exception se) { - logger.log(Level.WARN, "Exception while sleeping" + se.toString()); - } - } - } - } - logger.info("StackDriver initialization complete."); - } - - /** Main launches the server from the command line. */ - public static void main(String[] args) throws IOException, InterruptedException { - // Registers all RPC views. - RpcViews.registerAllGrpcViews(); - - new Thread( - new Runnable() { - public void run() { - initStackdriver(); - } - }) - .start(); - - // Start the RPC server. You shouldn't see any output from gRPC before this. - logger.info("AdService starting."); - final AdService service = AdService.getInstance(); - service.start(); - service.blockUntilShutdown(); - } -} diff --git a/src/adservice/src/main/java/hipstershop/AdServiceClient.java b/src/adservice/src/main/java/hipstershop/AdServiceClient.java deleted file mode 100644 index b61e8e691..000000000 --- a/src/adservice/src/main/java/hipstershop/AdServiceClient.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * 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 hipstershop; - -import hipstershop.Demo.Ad; -import hipstershop.Demo.AdRequest; -import hipstershop.Demo.AdResponse; -import io.grpc.ManagedChannel; -import io.grpc.ManagedChannelBuilder; -import io.grpc.StatusRuntimeException; -import io.opencensus.common.Duration; -import io.opencensus.common.Scope; -import io.opencensus.contrib.grpc.metrics.RpcViews; -import io.opencensus.contrib.grpc.util.StatusConverter; -import io.opencensus.exporter.stats.stackdriver.StackdriverStatsConfiguration; -import io.opencensus.exporter.stats.stackdriver.StackdriverStatsExporter; -import io.opencensus.exporter.trace.stackdriver.StackdriverTraceConfiguration; -import io.opencensus.exporter.trace.stackdriver.StackdriverTraceExporter; -import io.opencensus.trace.Span; -import io.opencensus.trace.Tracer; -import io.opencensus.trace.Tracing; -import io.opencensus.trace.samplers.Samplers; -import java.util.concurrent.TimeUnit; -import javax.annotation.Nullable; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -/** A simple client that requests ads from the Ads Service. */ -public class AdServiceClient { - - private static final Logger logger = LogManager.getLogger(AdServiceClient.class); - private static final Tracer tracer = Tracing.getTracer(); - - private final ManagedChannel channel; - private final hipstershop.AdServiceGrpc.AdServiceBlockingStub blockingStub; - - /** Construct client connecting to Ad Service at {@code host:port}. */ - private AdServiceClient(String host, int port) { - this( - ManagedChannelBuilder.forAddress(host, port) - // Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid - // needing certificates. - .usePlaintext() - .build()); - } - - /** Construct client for accessing RouteGuide server using the existing channel. */ - private AdServiceClient(ManagedChannel channel) { - this.channel = channel; - blockingStub = hipstershop.AdServiceGrpc.newBlockingStub(channel); - } - - private void shutdown() throws InterruptedException { - channel.shutdown().awaitTermination(5, TimeUnit.SECONDS); - } - - /** Get Ads from Server. */ - public void getAds(String contextKey) { - logger.info("Get Ads with context " + contextKey + " ..."); - AdRequest request = AdRequest.newBuilder().addContextKeys(contextKey).build(); - AdResponse response; - - Span span = - tracer - .spanBuilder("AdsClient") - .setRecordEvents(true) - .setSampler(Samplers.alwaysSample()) - .startSpan(); - try (Scope scope = tracer.withSpan(span)) { - tracer.getCurrentSpan().addAnnotation("Getting Ads"); - response = blockingStub.getAds(request); - tracer.getCurrentSpan().addAnnotation("Received response from Ads Service."); - } catch (StatusRuntimeException e) { - tracer.getCurrentSpan().setStatus(StatusConverter.fromGrpcStatus(e.getStatus())); - logger.log(Level.WARN, "RPC failed: " + e.getStatus()); - return; - } finally { - span.end(); - } - for (Ad ads : response.getAdsList()) { - logger.info("Ads: " + ads.getText()); - } - } - - private static int getPortOrDefaultFromArgs(String[] args, int index, int defaultPort) { - int portNumber = defaultPort; - if (index < args.length) { - try { - portNumber = Integer.parseInt(args[index]); - } catch (NumberFormatException e) { - logger.warn( - String.format("Port %s is invalid, use default port %d.", args[index], defaultPort)); - } - } - return portNumber; - } - - private static String getStringOrDefaultFromArgs( - String[] args, int index, @Nullable String defaultString) { - String s = defaultString; - if (index < args.length) { - s = args[index]; - } - return s; - } - - /** - * Ads Service Client main. If provided, the first element of {@code args} is the context key to - * get the ads from the Ads Service - */ - public static void main(String[] args) throws InterruptedException { - // Add final keyword to pass checkStyle. - final String contextKeys = getStringOrDefaultFromArgs(args, 0, "camera"); - final String host = getStringOrDefaultFromArgs(args, 1, "localhost"); - final int serverPort = getPortOrDefaultFromArgs(args, 2, 9555); - - // Registers all RPC views. - RpcViews.registerAllGrpcViews(); - - // Registers Stackdriver exporters. - long sleepTime = 10; /* seconds */ - int maxAttempts = 3; - - for (int i = 0; i < maxAttempts; i++) { - try { - StackdriverTraceExporter.createAndRegister(StackdriverTraceConfiguration.builder().build()); - StackdriverStatsExporter.createAndRegister( - StackdriverStatsConfiguration.builder() - .setExportInterval(Duration.create(15, 0)) - .build()); - } catch (Exception e) { - if (i == (maxAttempts - 1)) { - logger.log( - Level.WARN, - "Failed to register Stackdriver Exporter." - + " Tracing and Stats data will not reported to Stackdriver. Error message: " - + e.toString()); - } else { - logger.info("Attempt to register Stackdriver Exporter in " + sleepTime + " seconds"); - try { - Thread.sleep(TimeUnit.SECONDS.toMillis(sleepTime)); - } catch (Exception se) { - logger.log(Level.WARN, "Exception while sleeping" + e.toString()); - } - } - } - } - - // Register Prometheus exporters and export metrics to a Prometheus HTTPServer. - // PrometheusStatsCollector.createAndRegister(); - - AdServiceClient client = new AdServiceClient(host, serverPort); - try { - client.getAds(contextKeys); - } finally { - client.shutdown(); - } - - logger.info("Exiting AdServiceClient..."); - } -} diff --git a/src/adservice/src/main/proto/demo.proto b/src/adservice/src/main/proto/demo.proto deleted file mode 100644 index e5981af58..000000000 --- a/src/adservice/src/main/proto/demo.proto +++ /dev/null @@ -1,260 +0,0 @@ -// 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 "vintage" or "gardening" 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; -} diff --git a/src/adservice/src/main/resources/log4j2.xml b/src/adservice/src/main/resources/log4j2.xml deleted file mode 100644 index 22098f7d7..000000000 --- a/src/adservice/src/main/resources/log4j2.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/cartservice/.dockerignore b/src/cartservice/.dockerignore deleted file mode 100644 index 71edc2f29..000000000 --- a/src/cartservice/.dockerignore +++ /dev/null @@ -1,7 +0,0 @@ -**/*.bat -tests/ -**/bin/ -**/obj/ -**/out/ -Dockerfile* -docker-compose* \ No newline at end of file diff --git a/src/cartservice/.gitignore b/src/cartservice/.gitignore deleted file mode 100644 index f983350be..000000000 --- a/src/cartservice/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/bin/* -/obj/* -.vs/*.* diff --git a/src/cartservice/Dockerfile b/src/cartservice/Dockerfile deleted file mode 100644 index d053634d7..000000000 --- a/src/cartservice/Dockerfile +++ /dev/null @@ -1,28 +0,0 @@ -# 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 mcr.microsoft.com/dotnet/sdk:5.0.102-ca-patch-buster-slim 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 cart_out --no-restore - -FROM mcr.microsoft.com/dotnet/runtime-deps:5.0.1-alpine3.12-amd64 -RUN GRPC_HEALTH_PROBE_VERSION=v0.3.5 && \ - 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 /app/cart_out ./ -ENTRYPOINT ["/app/cartservice"] diff --git a/src/cartservice/Program.cs b/src/cartservice/Program.cs deleted file mode 100644 index b9ae18d0f..000000000 --- a/src/cartservice/Program.cs +++ /dev/null @@ -1,37 +0,0 @@ -// 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 Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Hosting; - -namespace cartservice -{ - public class Program - { - public static void Main(string[] args) - { - CreateHostBuilder(args).Build().Run(); - } - - // Additional configuration is required to successfully run gRPC on macOS. - // For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682 - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }); - } -} \ No newline at end of file diff --git a/src/cartservice/Properties/launchSettings.json b/src/cartservice/Properties/launchSettings.json deleted file mode 100644 index d3c93715b..000000000 --- a/src/cartservice/Properties/launchSettings.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "profiles": { - "cart-grpc": { - "commandName": "Project", - "launchBrowser": false, - "applicationUrl": "https://localhost:8080", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} diff --git a/src/cartservice/Protos/Cart.proto b/src/cartservice/Protos/Cart.proto deleted file mode 100644 index b2974cb6f..000000000 --- a/src/cartservice/Protos/Cart.proto +++ /dev/null @@ -1,50 +0,0 @@ -// 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 {} diff --git a/src/cartservice/README.md b/src/cartservice/README.md deleted file mode 100644 index b94224398..000000000 --- a/src/cartservice/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Cart Service - -The Cart Service is a microservice written in C# and -the [.NET 5](https://docs.microsoft.com/en-us/dotnet/core/dotnet-five) framework. It manages -shopping cart state for users of the Hipster Shop. - -## Overview - -The Cart Service communicates over gRPC and stores cart information in a Redis database. It exposes -a GET endpoint to retrieve a cart for a given user, as well as POST endpoints for adding items to -carts and emptying carts. - -## OpenTelemetry Configuration - -The Cart Services uses [OpenTelemetry](https://opentelemetry.io/) to collect trace information from -the microservice and forward it to [Cloud Trace](https://cloud.google.com/trace). Specifically, it -forwards trace information to an instance of -the [OpenTelemetry Collector](https://github.com/open-telemetry/opentelemetry-collector) which is -running as a sidecar container in the same pod. This lightweight process (often referred to as -an [agent](https://opentelemetry.io/docs/collector/getting-started/)) then forwards the trace -information to a separate deployment of the OpenTelemetryCollector which is able to batch traces -from multiple microservices and forward them to Cloud Trace. This collector runs the same binary but -can be configured to use more memory and computational resources. This standalone collector is -referred to as a [gateway](https://opentelemetry.io/docs/collector/getting-started/). - -[![OpenTelemetry Collector Agent/Gateway Pattern](../../docs/img/cartservice-opentelemetry-diagram.png)](../../docs/img/cartservice-opentelemetry-diagram.png) - diff --git a/src/cartservice/Services/CartServiceController.cs b/src/cartservice/Services/CartServiceController.cs deleted file mode 100644 index 221ea05be..000000000 --- a/src/cartservice/Services/CartServiceController.cs +++ /dev/null @@ -1,50 +0,0 @@ -// 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.Core; -using Hipstershop; -using Microsoft.Extensions.Logging; - -namespace cartservice -{ - public sealed class CartServiceController : Hipstershop.CartService.CartServiceBase - { - private readonly static Empty Empty = new Empty(); - private readonly ICartStore _cartStore; - - public CartServiceController(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; - } - } -} diff --git a/src/cartservice/Services/HealthCheckService.cs b/src/cartservice/Services/HealthCheckService.cs deleted file mode 100644 index 0d4437e07..000000000 --- a/src/cartservice/Services/HealthCheckService.cs +++ /dev/null @@ -1,41 +0,0 @@ -// 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. - -using System; -using System.Threading.Tasks; -using Grpc.Core; -using Grpc.Health.V1; -using static Grpc.Health.V1.Health; - -namespace cartservice -{ - internal class HealthCheckService : HealthBase - { - private ICartStore _dependency { get; } - - public HealthCheckService (ICartStore dependency) - { - this._dependency = dependency; - } - - public override Task Check(HealthCheckRequest request, ServerCallContext context) - { - Console.WriteLine ("Checking CartService Health"); - - return Task.FromResult(new HealthCheckResponse { - Status = _dependency.Ping() ? HealthCheckResponse.Types.ServingStatus.Serving : HealthCheckResponse.Types.ServingStatus.NotServing - }); - } - } -} diff --git a/src/cartservice/Startup.cs b/src/cartservice/Startup.cs deleted file mode 100644 index 44c2258fb..000000000 --- a/src/cartservice/Startup.cs +++ /dev/null @@ -1,100 +0,0 @@ -// 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 cartservice.cartstore; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using OpenTelemetry.Trace; - -namespace cartservice -{ - public class Startup - { - private readonly IConfiguration Configuration; - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - // 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"]; - ICartStore cartStore = null; - if (!string.IsNullOrEmpty(redisAddress)) - { - - cartStore = new RedisCartStore(redisAddress); - } - else - { - Console.WriteLine("Redis cache host(hostname+port) was not specified. Starting a cart service using local store"); - Console.WriteLine("If you wanted to use Redis Cache as a backup store, you should provide its address via command line or REDIS_ADDR environment variable."); - cartStore = new LocalCartStore(); - } - - // Initialize the redis store - cartStore.InitializeAsync().GetAwaiter().GetResult(); - Console.WriteLine("Initialization completed"); - - services.AddSingleton(cartStore); - services.AddGrpc(); - - // Adding the OtlpExporter creates a GrpcChannel. - // This switch must be set before creating a GrpcChannel/HttpClient when calling an insecure gRPC service. - // See: https://docs.microsoft.com/aspnet/core/grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client - AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); - - services.AddOpenTelemetryTracing(builder => - { - builder.AddAspNetCoreInstrumentation() - .AddOtlpExporter(options => - options.Endpoint = new Uri(Configuration["OTEL_COLLECTOR_ADDR"])); - if (cartStore is RedisCartStore redisCartStore) - { - builder.AddRedisInstrumentation(redisCartStore.RedisConnectionMultiplexer); - } - } - ); - } - - // 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"); - }); - }); - } - } -} diff --git a/src/cartservice/appsettings.Development.json b/src/cartservice/appsettings.Development.json deleted file mode 100644 index eec2e4c53..000000000 --- a/src/cartservice/appsettings.Development.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Grpc": "Information", - "Microsoft": "Information" - } - } -} diff --git a/src/cartservice/appsettings.json b/src/cartservice/appsettings.json deleted file mode 100644 index f5ef230f6..000000000 --- a/src/cartservice/appsettings.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" - } - }, - "AllowedHosts": "*", - "Kestrel": { - "EndpointDefaults": { - "Protocols": "Http2" - } - } -} diff --git a/src/cartservice/cartservice.csproj b/src/cartservice/cartservice.csproj deleted file mode 100644 index 467970d65..000000000 --- a/src/cartservice/cartservice.csproj +++ /dev/null @@ -1,22 +0,0 @@ - - - - net5.0 - - - - - - - - - - - - - - - - - - diff --git a/src/cartservice/cartstore/LocalCartStore.cs b/src/cartservice/cartstore/LocalCartStore.cs deleted file mode 100644 index 10b6717e0..000000000 --- a/src/cartservice/cartstore/LocalCartStore.cs +++ /dev/null @@ -1,89 +0,0 @@ -// 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.Collections.Concurrent; -using System.Threading.Tasks; -using System.Linq; - -namespace cartservice.cartstore -{ - internal class LocalCartStore : ICartStore - { - // Maps between user and their cart - private ConcurrentDictionary userCartItems = new ConcurrentDictionary(); - private readonly Hipstershop.Cart emptyCart = new Hipstershop.Cart(); - - public Task InitializeAsync() - { - Console.WriteLine("Local Cart Store was initialized"); - - return Task.CompletedTask; - } - - public Task AddItemAsync(string userId, string productId, int quantity) - { - Console.WriteLine($"AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity}"); - var newCart = new Hipstershop.Cart - { - UserId = userId, - Items = { new Hipstershop.CartItem { ProductId = productId, Quantity = quantity } } - }; - userCartItems.AddOrUpdate(userId, newCart, - (k, exVal) => - { - // If the item exists, we update its quantity - var existingItem = exVal.Items.SingleOrDefault(item => item.ProductId == productId); - if (existingItem != null) - { - existingItem.Quantity += quantity; - } - else - { - exVal.Items.Add(new Hipstershop.CartItem { ProductId = productId, Quantity = quantity }); - } - - return exVal; - }); - - return Task.CompletedTask; - } - - public Task EmptyCartAsync(string userId) - { - Console.WriteLine($"EmptyCartAsync called with userId={userId}"); - userCartItems[userId] = emptyCart; - - return Task.CompletedTask; - } - - public Task GetCartAsync(string userId) - { - Console.WriteLine($"GetCartAsync called with userId={userId}"); - Hipstershop.Cart cart = null; - if (!userCartItems.TryGetValue(userId, out cart)) - { - Console.WriteLine($"No carts for user {userId}"); - return Task.FromResult(emptyCart); - } - - return Task.FromResult(cart); - } - - public bool Ping() - { - return true; - } - } -} \ No newline at end of file diff --git a/src/cartservice/cartstore/RedisCartStore.cs b/src/cartservice/cartstore/RedisCartStore.cs deleted file mode 100644 index fe9ba1e53..000000000 --- a/src/cartservice/cartstore/RedisCartStore.cs +++ /dev/null @@ -1,222 +0,0 @@ -// 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 StackExchange.Redis; -using Google.Protobuf; - -namespace cartservice.cartstore -{ - public class RedisCartStore : ICartStore - { - private const string CART_FIELD_NAME = "cart"; - private const int REDIS_RETRY_NUM = 5; - - private volatile ConnectionMultiplexer redis; - private volatile bool isRedisConnectionOpened = false; - - private readonly object locker = new object(); - private readonly byte[] emptyCartBytes; - private readonly string connectionString; - - public IConnectionMultiplexer RedisConnectionMultiplexer => redis; - - private readonly ConfigurationOptions redisConnectionOptions; - - public RedisCartStore(string redisAddress) - { - // Serialize empty cart into byte array. - var cart = new Hipstershop.Cart(); - emptyCartBytes = ToByteArray(cart); - connectionString = $"{redisAddress},ssl=false,allowAdmin=true,connectRetry=5"; - - redisConnectionOptions = ConfigurationOptions.Parse(connectionString); - - // Try to reconnect if first retry failed (up to 5 times with exponential backoff) - redisConnectionOptions.ConnectRetry = REDIS_RETRY_NUM; - redisConnectionOptions.ReconnectRetryPolicy = new ExponentialRetry(100); - - redisConnectionOptions.KeepAlive = 180; - } - - public Task InitializeAsync() - { - EnsureRedisConnected(); - return Task.CompletedTask; - } - - private void EnsureRedisConnected() - { - if (isRedisConnectionOpened) - { - return; - } - - // Connection is closed or failed - open a new one but only at the first thread - lock (locker) - { - if (isRedisConnectionOpened) - { - return; - } - - Console.WriteLine("Connecting to Redis: " + connectionString); - redis = ConnectionMultiplexer.Connect(redisConnectionOptions); - if (redis == null || !redis.IsConnected) - { - Console.WriteLine("Wasn't able to connect to redis"); - - // We weren't able to connect to redis despite 5 retries with exponential backoff - throw new ApplicationException("Wasn't able to connect to redis"); - } - - Console.WriteLine("Successfully connected to Redis"); - var cache = redis.GetDatabase(); - - Console.WriteLine("Performing small test"); - cache.StringSet("cart", "OK" ); - object res = cache.StringGet("cart"); - Console.WriteLine($"Small test result: {res}"); - - redis.InternalError += (o, e) => { Console.WriteLine(e.Exception); }; - redis.ConnectionRestored += (o, e) => - { - isRedisConnectionOpened = true; - Console.WriteLine("Connection to redis was restored successfully"); - }; - redis.ConnectionFailed += (o, e) => - { - Console.WriteLine("Connection failed. Disposing the object"); - isRedisConnectionOpened = false; - }; - - isRedisConnectionOpened = true; - } - } - - public async Task AddItemAsync(string userId, string productId, int quantity) - { - Console.WriteLine($"AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity}"); - - try - { - EnsureRedisConnected(); - - var db = redis.GetDatabase(); - - // Access the cart from the cache - var value = await db.HashGetAsync(userId, CART_FIELD_NAME); - - Hipstershop.Cart cart; - if (value.IsNull) - { - 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 db.HashSetAsync(userId, new[]{ new HashEntry(CART_FIELD_NAME, ToByteArray(cart)) }); - } - catch (Exception ex) - { - throw new RpcException(new Grpc.Core.Status(StatusCode.FailedPrecondition, $"Can't access cart storage. {ex}")); - } - } - - public async Task EmptyCartAsync(string userId) - { - Console.WriteLine($"EmptyCartAsync called with userId={userId}"); - - try - { - EnsureRedisConnected(); - var db = redis.GetDatabase(); - - // Update the cache with empty cart for given user - await db.HashSetAsync(userId, new[] { new HashEntry(CART_FIELD_NAME, emptyCartBytes) }); - } - catch (Exception ex) - { - throw new RpcException(new Grpc.Core.Status(StatusCode.FailedPrecondition, $"Can't access cart storage. {ex}")); - } - } - - public async Task GetCartAsync(string userId) - { - Console.WriteLine($"GetCartAsync called with userId={userId}"); - - try - { - EnsureRedisConnected(); - - var db = redis.GetDatabase(); - - // Access the cart from the cache - var value = await db.HashGetAsync(userId, CART_FIELD_NAME); - - if (!value.IsNull) - { - 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 Grpc.Core.Status(StatusCode.FailedPrecondition, $"Can't access cart storage. {ex}")); - } - } - - public bool Ping() - { - try - { - var redis = ConnectionMultiplexer.Connect(redisConnectionOptions); - var cache = redis.GetDatabase(); - var res = cache.Ping(); - return res != TimeSpan.Zero; - } - catch (Exception) - { - return false; - } - } - - private static byte[] ToByteArray(Hipstershop.Cart cart) - { - if (cart == null) - { - return null; - } - return cart.ToByteArray(); - } - } -} diff --git a/src/cartservice/docker-compose.yaml b/src/cartservice/docker-compose.yaml deleted file mode 100644 index 7a4d10545..000000000 --- a/src/cartservice/docker-compose.yaml +++ /dev/null @@ -1,29 +0,0 @@ -# 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. -# -# test redis with cart service with -# docker-compose up --build -# -version: "3.8" -services: - web: - build: . - ports: - - "7070:7070" - environment: - REDIS_ADDR: "redis:6379" - ASPNETCORE_URLS: "http://0.0.0.0:7070" - OTEL_COLLECTOR_ADDR: "http://localhost:4317" - redis: - image: "redis:alpine" \ No newline at end of file diff --git a/src/cartservice/interfaces/ICartStore.cs b/src/cartservice/interfaces/ICartStore.cs deleted file mode 100644 index a98552ea4..000000000 --- a/src/cartservice/interfaces/ICartStore.cs +++ /dev/null @@ -1,30 +0,0 @@ -// 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 -{ - public interface ICartStore - { - Task InitializeAsync(); - - Task AddItemAsync(string userId, string productId, int quantity); - Task EmptyCartAsync(string userId); - - Task GetCartAsync(string userId); - - bool Ping(); - } -} \ No newline at end of file diff --git a/src/cartservice/scripts/build_image.bat b/src/cartservice/scripts/build_image.bat deleted file mode 100644 index 83f675f92..000000000 --- a/src/cartservice/scripts/build_image.bat +++ /dev/null @@ -1,20 +0,0 @@ -@echo off -@REM Copyright 2018 Google LLC -@REM -@REM Licensed under the Apache License, Version 2.0 (the "License"); -@REM you may not use this file except in compliance with the License. -@REM You may obtain a copy of the License at -@REM -@REM http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, software -@REM distributed under the License is distributed on an "AS IS" BASIS, -@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@REM See the License for the specific language governing permissions and -@REM limitations under the License. - -echo building container image for cart service -docker build -t cartservice ..\. - -echo running the image, mapping the port -rem echo docker run -it --rm -p 5000:8080 --name diff --git a/src/cartservice/scripts/docker_setup.bat b/src/cartservice/scripts/docker_setup.bat deleted file mode 100644 index 62f27616a..000000000 --- a/src/cartservice/scripts/docker_setup.bat +++ /dev/null @@ -1,65 +0,0 @@ -@echo off -@REM Copyright 2018 Google LLC -@REM -@REM Licensed under the Apache License, Version 2.0 (the "License"); -@REM you may not use this file except in compliance with the License. -@REM You may obtain a copy of the License at -@REM -@REM http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, software -@REM distributed under the License is distributed on an "AS IS" BASIS, -@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@REM See the License for the specific language governing permissions and -@REM limitations under the License. - -set ENV=%1 - -IF %ENV%==local GOTO local -IF %ENV%==docker GOTO docker_local -GOTO End1 - -:local - set REDIS_PORT=6379 - set REDIS_ADDR=localhost:%REDIS_PORT% - set LISTEN_ADDR=localhost - set PORT=7070 - set GRPC_TRACE=all - - echo running redis emulator locally on a separate window - taskkill /f /im "redis-server.exe" - start redis-server "C:\ProgramData\chocolatey\lib\redis-64\redis.windows.conf" - - echo running the cart service locally - dotnet build ..\. - dotnet run --project ../cartservice.csproj start -GOTO End1 - -:docker_local - set REDIS_PORT=6379 - rem set REDIS_ADDR=redis:%REDIS_PORT% - set LISTEN_ADDR=localhost - set PORT=7070 - - echo run docker container with redis - - echo Forcing to remove redis cache so we always start the container from scratch - docker rm --force redis > nul 2>&1 - echo Starting out redis container - docker run -d --name=redis redis > nul 2>&1 - rem This assigns the output of ip4 addr of redis container into REDIS_ADDR - FOR /F "tokens=*" %%g IN ('docker inspect -f "{{ .NetworkSettings.Networks.bridge.IPAddress }}" redis') do (SET REDIS_ADDR=%%g) - echo addr=%REDIS_ADDR% - echo building container image for cart service - docker build -t cartservice ..\. - - echo run container image for cart service - docker run -it --name=cartservice --rm -e REDIS_ADDR=%REDIS_ADDR%:%REDIS_PORT% -e LISTEN_ADDR=%LISTEN_ADDR% -e PORT=%PORT% -p %PORT%:%PORT% cartservice - -GOTO End1 - -:End1 - -rem run docker container with cart service -rem docker run -it --rm -e REDIS_ADDR=%REDIS_ADDR%:%REDIS_PORT% -e CART_SERVICE_ADDR=%CART_SERVICE_ADDR% -e CART_SERVICE_PORT=%CART_SERVICE_PORT% -p %CART_SERVICE_PORT%:%CART_SERVICE_PORT% cartservice -rem -e GRPC_TRACE=all -e GRPC_VERBOSITY=debug diff --git a/src/cartservice/scripts/run_redis_emulator_windows.bat b/src/cartservice/scripts/run_redis_emulator_windows.bat deleted file mode 100644 index 1b7e97ce2..000000000 --- a/src/cartservice/scripts/run_redis_emulator_windows.bat +++ /dev/null @@ -1,25 +0,0 @@ -@echo off -@REM Copyright 2018 Google LLC -@REM -@REM Licensed under the Apache License, Version 2.0 (the "License"); -@REM you may not use this file except in compliance with the License. -@REM You may obtain a copy of the License at -@REM -@REM http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, software -@REM distributed under the License is distributed on an "AS IS" BASIS, -@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@REM See the License for the specific language governing permissions and -@REM limitations under the License. - -rem install redis on windows using choco -rem choco install redis-64 - -rem run redis -redis-server --daemonize yes - -rem testing locally -rem redis-cli -rem SET foo bar -rem GET foo diff --git a/src/checkoutservice/.dockerignore b/src/checkoutservice/.dockerignore deleted file mode 100644 index 48b8bf907..000000000 --- a/src/checkoutservice/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -vendor/ diff --git a/src/checkoutservice/Dockerfile b/src/checkoutservice/Dockerfile deleted file mode 100644 index 3596571b5..000000000 --- a/src/checkoutservice/Dockerfile +++ /dev/null @@ -1,36 +0,0 @@ -# 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.16-alpine as builder -RUN apk add --no-cache ca-certificates git -ENV PROJECT github.com/GoogleCloudPlatform/microservices-demo/src/checkoutservice -WORKDIR /go/src/$PROJECT - -# restore dependencies -COPY main.go go.mod go.sum ./ -COPY genproto ./genproto/ -COPY money ./money/ -RUN go mod vendor -v - -COPY . . -RUN go build -gcflags='-N -l' -o /checkoutservice - -FROM alpine as release -RUN apk add --no-cache ca-certificates -RUN GRPC_HEALTH_PROBE_VERSION=v0.4.2 && \ - 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 -COPY --from=builder /checkoutservice /checkoutservice -EXPOSE 5050 -ENTRYPOINT ["/checkoutservice"] diff --git a/src/checkoutservice/README.md b/src/checkoutservice/README.md deleted file mode 100644 index c68ccb33d..000000000 --- a/src/checkoutservice/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# checkoutservice - -Run the following command to restore dependencies to `vendor/` directory: - - go mod vendor -v diff --git a/src/checkoutservice/genproto/demo.pb.go b/src/checkoutservice/genproto/demo.pb.go deleted file mode 100644 index d3ef85c1c..000000000 --- a/src/checkoutservice/genproto/demo.pb.go +++ /dev/null @@ -1,2607 +0,0 @@ -// 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. -// versions: -// protoc-gen-go v1.26.0 -// protoc v3.12.4 -// source: demo.proto - -package hipstershop - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type CartItem struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *CartItem) Reset() { - *x = CartItem{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CartItem) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CartItem) ProtoMessage() {} - -func (x *CartItem) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CartItem.ProtoReflect.Descriptor instead. -func (*CartItem) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{0} -} - -func (x *CartItem) GetProductId() string { - if x != nil { - return x.ProductId - } - return "" -} - -func (x *CartItem) GetQuantity() int32 { - if x != nil { - return x.Quantity - } - return 0 -} - -type AddItemRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *AddItemRequest) Reset() { - *x = AddItemRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AddItemRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AddItemRequest) ProtoMessage() {} - -func (x *AddItemRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AddItemRequest.ProtoReflect.Descriptor instead. -func (*AddItemRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{1} -} - -func (x *AddItemRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -func (x *AddItemRequest) GetItem() *CartItem { - if x != nil { - return x.Item - } - return nil -} - -type EmptyCartRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` -} - -func (x *EmptyCartRequest) Reset() { - *x = EmptyCartRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *EmptyCartRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EmptyCartRequest) ProtoMessage() {} - -func (x *EmptyCartRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use EmptyCartRequest.ProtoReflect.Descriptor instead. -func (*EmptyCartRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{2} -} - -func (x *EmptyCartRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -type GetCartRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` -} - -func (x *GetCartRequest) Reset() { - *x = GetCartRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetCartRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetCartRequest) ProtoMessage() {} - -func (x *GetCartRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetCartRequest.ProtoReflect.Descriptor instead. -func (*GetCartRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{3} -} - -func (x *GetCartRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -type Cart struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *Cart) Reset() { - *x = Cart{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Cart) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Cart) ProtoMessage() {} - -func (x *Cart) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Cart.ProtoReflect.Descriptor instead. -func (*Cart) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{4} -} - -func (x *Cart) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -func (x *Cart) GetItems() []*CartItem { - if x != nil { - return x.Items - } - return nil -} - -type Empty struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *Empty) Reset() { - *x = Empty{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Empty) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Empty) ProtoMessage() {} - -func (x *Empty) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Empty.ProtoReflect.Descriptor instead. -func (*Empty) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{5} -} - -type ListRecommendationsRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *ListRecommendationsRequest) Reset() { - *x = ListRecommendationsRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListRecommendationsRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListRecommendationsRequest) ProtoMessage() {} - -func (x *ListRecommendationsRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListRecommendationsRequest.ProtoReflect.Descriptor instead. -func (*ListRecommendationsRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{6} -} - -func (x *ListRecommendationsRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -func (x *ListRecommendationsRequest) GetProductIds() []string { - if x != nil { - return x.ProductIds - } - return nil -} - -type ListRecommendationsResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ProductIds []string `protobuf:"bytes,1,rep,name=product_ids,json=productIds,proto3" json:"product_ids,omitempty"` -} - -func (x *ListRecommendationsResponse) Reset() { - *x = ListRecommendationsResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListRecommendationsResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListRecommendationsResponse) ProtoMessage() {} - -func (x *ListRecommendationsResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListRecommendationsResponse.ProtoReflect.Descriptor instead. -func (*ListRecommendationsResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{7} -} - -func (x *ListRecommendationsResponse) GetProductIds() []string { - if x != nil { - return x.ProductIds - } - return nil -} - -type Product struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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 "vintage" or "gardening" that can be used to look up - // other related products. - Categories []string `protobuf:"bytes,6,rep,name=categories,proto3" json:"categories,omitempty"` -} - -func (x *Product) Reset() { - *x = Product{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Product) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Product) ProtoMessage() {} - -func (x *Product) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Product.ProtoReflect.Descriptor instead. -func (*Product) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{8} -} - -func (x *Product) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Product) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Product) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} - -func (x *Product) GetPicture() string { - if x != nil { - return x.Picture - } - return "" -} - -func (x *Product) GetPriceUsd() *Money { - if x != nil { - return x.PriceUsd - } - return nil -} - -func (x *Product) GetCategories() []string { - if x != nil { - return x.Categories - } - return nil -} - -type ListProductsResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Products []*Product `protobuf:"bytes,1,rep,name=products,proto3" json:"products,omitempty"` -} - -func (x *ListProductsResponse) Reset() { - *x = ListProductsResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListProductsResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListProductsResponse) ProtoMessage() {} - -func (x *ListProductsResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListProductsResponse.ProtoReflect.Descriptor instead. -func (*ListProductsResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{9} -} - -func (x *ListProductsResponse) GetProducts() []*Product { - if x != nil { - return x.Products - } - return nil -} - -type GetProductRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` -} - -func (x *GetProductRequest) Reset() { - *x = GetProductRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetProductRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetProductRequest) ProtoMessage() {} - -func (x *GetProductRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetProductRequest.ProtoReflect.Descriptor instead. -func (*GetProductRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{10} -} - -func (x *GetProductRequest) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -type SearchProductsRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` -} - -func (x *SearchProductsRequest) Reset() { - *x = SearchProductsRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SearchProductsRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SearchProductsRequest) ProtoMessage() {} - -func (x *SearchProductsRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SearchProductsRequest.ProtoReflect.Descriptor instead. -func (*SearchProductsRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{11} -} - -func (x *SearchProductsRequest) GetQuery() string { - if x != nil { - return x.Query - } - return "" -} - -type SearchProductsResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Results []*Product `protobuf:"bytes,1,rep,name=results,proto3" json:"results,omitempty"` -} - -func (x *SearchProductsResponse) Reset() { - *x = SearchProductsResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SearchProductsResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SearchProductsResponse) ProtoMessage() {} - -func (x *SearchProductsResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SearchProductsResponse.ProtoReflect.Descriptor instead. -func (*SearchProductsResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{12} -} - -func (x *SearchProductsResponse) GetResults() []*Product { - if x != nil { - return x.Results - } - return nil -} - -type GetQuoteRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Address *Address `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` - Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` -} - -func (x *GetQuoteRequest) Reset() { - *x = GetQuoteRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetQuoteRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetQuoteRequest) ProtoMessage() {} - -func (x *GetQuoteRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetQuoteRequest.ProtoReflect.Descriptor instead. -func (*GetQuoteRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{13} -} - -func (x *GetQuoteRequest) GetAddress() *Address { - if x != nil { - return x.Address - } - return nil -} - -func (x *GetQuoteRequest) GetItems() []*CartItem { - if x != nil { - return x.Items - } - return nil -} - -type GetQuoteResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - CostUsd *Money `protobuf:"bytes,1,opt,name=cost_usd,json=costUsd,proto3" json:"cost_usd,omitempty"` -} - -func (x *GetQuoteResponse) Reset() { - *x = GetQuoteResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetQuoteResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetQuoteResponse) ProtoMessage() {} - -func (x *GetQuoteResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetQuoteResponse.ProtoReflect.Descriptor instead. -func (*GetQuoteResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{14} -} - -func (x *GetQuoteResponse) GetCostUsd() *Money { - if x != nil { - return x.CostUsd - } - return nil -} - -type ShipOrderRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Address *Address `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` - Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` -} - -func (x *ShipOrderRequest) Reset() { - *x = ShipOrderRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ShipOrderRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ShipOrderRequest) ProtoMessage() {} - -func (x *ShipOrderRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ShipOrderRequest.ProtoReflect.Descriptor instead. -func (*ShipOrderRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{15} -} - -func (x *ShipOrderRequest) GetAddress() *Address { - if x != nil { - return x.Address - } - return nil -} - -func (x *ShipOrderRequest) GetItems() []*CartItem { - if x != nil { - return x.Items - } - return nil -} - -type ShipOrderResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - TrackingId string `protobuf:"bytes,1,opt,name=tracking_id,json=trackingId,proto3" json:"tracking_id,omitempty"` -} - -func (x *ShipOrderResponse) Reset() { - *x = ShipOrderResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ShipOrderResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ShipOrderResponse) ProtoMessage() {} - -func (x *ShipOrderResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[16] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ShipOrderResponse.ProtoReflect.Descriptor instead. -func (*ShipOrderResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{16} -} - -func (x *ShipOrderResponse) GetTrackingId() string { - if x != nil { - return x.TrackingId - } - return "" -} - -type Address struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *Address) Reset() { - *x = Address{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Address) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Address) ProtoMessage() {} - -func (x *Address) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[17] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Address.ProtoReflect.Descriptor instead. -func (*Address) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{17} -} - -func (x *Address) GetStreetAddress() string { - if x != nil { - return x.StreetAddress - } - return "" -} - -func (x *Address) GetCity() string { - if x != nil { - return x.City - } - return "" -} - -func (x *Address) GetState() string { - if x != nil { - return x.State - } - return "" -} - -func (x *Address) GetCountry() string { - if x != nil { - return x.Country - } - return "" -} - -func (x *Address) GetZipCode() int32 { - if x != nil { - return x.ZipCode - } - return 0 -} - -// Represents an amount of money with its currency type. -type Money struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // 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"` -} - -func (x *Money) Reset() { - *x = Money{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Money) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Money) ProtoMessage() {} - -func (x *Money) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[18] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Money.ProtoReflect.Descriptor instead. -func (*Money) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{18} -} - -func (x *Money) GetCurrencyCode() string { - if x != nil { - return x.CurrencyCode - } - return "" -} - -func (x *Money) GetUnits() int64 { - if x != nil { - return x.Units - } - return 0 -} - -func (x *Money) GetNanos() int32 { - if x != nil { - return x.Nanos - } - return 0 -} - -type GetSupportedCurrenciesResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // 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"` -} - -func (x *GetSupportedCurrenciesResponse) Reset() { - *x = GetSupportedCurrenciesResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetSupportedCurrenciesResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetSupportedCurrenciesResponse) ProtoMessage() {} - -func (x *GetSupportedCurrenciesResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[19] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetSupportedCurrenciesResponse.ProtoReflect.Descriptor instead. -func (*GetSupportedCurrenciesResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{19} -} - -func (x *GetSupportedCurrenciesResponse) GetCurrencyCodes() []string { - if x != nil { - return x.CurrencyCodes - } - return nil -} - -type CurrencyConversionRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *CurrencyConversionRequest) Reset() { - *x = CurrencyConversionRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CurrencyConversionRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CurrencyConversionRequest) ProtoMessage() {} - -func (x *CurrencyConversionRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[20] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CurrencyConversionRequest.ProtoReflect.Descriptor instead. -func (*CurrencyConversionRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{20} -} - -func (x *CurrencyConversionRequest) GetFrom() *Money { - if x != nil { - return x.From - } - return nil -} - -func (x *CurrencyConversionRequest) GetToCode() string { - if x != nil { - return x.ToCode - } - return "" -} - -type CreditCardInfo struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *CreditCardInfo) Reset() { - *x = CreditCardInfo{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreditCardInfo) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreditCardInfo) ProtoMessage() {} - -func (x *CreditCardInfo) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[21] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreditCardInfo.ProtoReflect.Descriptor instead. -func (*CreditCardInfo) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{21} -} - -func (x *CreditCardInfo) GetCreditCardNumber() string { - if x != nil { - return x.CreditCardNumber - } - return "" -} - -func (x *CreditCardInfo) GetCreditCardCvv() int32 { - if x != nil { - return x.CreditCardCvv - } - return 0 -} - -func (x *CreditCardInfo) GetCreditCardExpirationYear() int32 { - if x != nil { - return x.CreditCardExpirationYear - } - return 0 -} - -func (x *CreditCardInfo) GetCreditCardExpirationMonth() int32 { - if x != nil { - return x.CreditCardExpirationMonth - } - return 0 -} - -type ChargeRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *ChargeRequest) Reset() { - *x = ChargeRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ChargeRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ChargeRequest) ProtoMessage() {} - -func (x *ChargeRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[22] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ChargeRequest.ProtoReflect.Descriptor instead. -func (*ChargeRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{22} -} - -func (x *ChargeRequest) GetAmount() *Money { - if x != nil { - return x.Amount - } - return nil -} - -func (x *ChargeRequest) GetCreditCard() *CreditCardInfo { - if x != nil { - return x.CreditCard - } - return nil -} - -type ChargeResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - TransactionId string `protobuf:"bytes,1,opt,name=transaction_id,json=transactionId,proto3" json:"transaction_id,omitempty"` -} - -func (x *ChargeResponse) Reset() { - *x = ChargeResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[23] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ChargeResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ChargeResponse) ProtoMessage() {} - -func (x *ChargeResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[23] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ChargeResponse.ProtoReflect.Descriptor instead. -func (*ChargeResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{23} -} - -func (x *ChargeResponse) GetTransactionId() string { - if x != nil { - return x.TransactionId - } - return "" -} - -type OrderItem struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Item *CartItem `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` - Cost *Money `protobuf:"bytes,2,opt,name=cost,proto3" json:"cost,omitempty"` -} - -func (x *OrderItem) Reset() { - *x = OrderItem{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[24] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *OrderItem) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*OrderItem) ProtoMessage() {} - -func (x *OrderItem) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[24] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use OrderItem.ProtoReflect.Descriptor instead. -func (*OrderItem) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{24} -} - -func (x *OrderItem) GetItem() *CartItem { - if x != nil { - return x.Item - } - return nil -} - -func (x *OrderItem) GetCost() *Money { - if x != nil { - return x.Cost - } - return nil -} - -type OrderResult struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *OrderResult) Reset() { - *x = OrderResult{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[25] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *OrderResult) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*OrderResult) ProtoMessage() {} - -func (x *OrderResult) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[25] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use OrderResult.ProtoReflect.Descriptor instead. -func (*OrderResult) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{25} -} - -func (x *OrderResult) GetOrderId() string { - if x != nil { - return x.OrderId - } - return "" -} - -func (x *OrderResult) GetShippingTrackingId() string { - if x != nil { - return x.ShippingTrackingId - } - return "" -} - -func (x *OrderResult) GetShippingCost() *Money { - if x != nil { - return x.ShippingCost - } - return nil -} - -func (x *OrderResult) GetShippingAddress() *Address { - if x != nil { - return x.ShippingAddress - } - return nil -} - -func (x *OrderResult) GetItems() []*OrderItem { - if x != nil { - return x.Items - } - return nil -} - -type SendOrderConfirmationRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` - Order *OrderResult `protobuf:"bytes,2,opt,name=order,proto3" json:"order,omitempty"` -} - -func (x *SendOrderConfirmationRequest) Reset() { - *x = SendOrderConfirmationRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[26] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SendOrderConfirmationRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SendOrderConfirmationRequest) ProtoMessage() {} - -func (x *SendOrderConfirmationRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[26] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SendOrderConfirmationRequest.ProtoReflect.Descriptor instead. -func (*SendOrderConfirmationRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{26} -} - -func (x *SendOrderConfirmationRequest) GetEmail() string { - if x != nil { - return x.Email - } - return "" -} - -func (x *SendOrderConfirmationRequest) GetOrder() *OrderResult { - if x != nil { - return x.Order - } - return nil -} - -type PlaceOrderRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *PlaceOrderRequest) Reset() { - *x = PlaceOrderRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[27] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PlaceOrderRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PlaceOrderRequest) ProtoMessage() {} - -func (x *PlaceOrderRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[27] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PlaceOrderRequest.ProtoReflect.Descriptor instead. -func (*PlaceOrderRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{27} -} - -func (x *PlaceOrderRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -func (x *PlaceOrderRequest) GetUserCurrency() string { - if x != nil { - return x.UserCurrency - } - return "" -} - -func (x *PlaceOrderRequest) GetAddress() *Address { - if x != nil { - return x.Address - } - return nil -} - -func (x *PlaceOrderRequest) GetEmail() string { - if x != nil { - return x.Email - } - return "" -} - -func (x *PlaceOrderRequest) GetCreditCard() *CreditCardInfo { - if x != nil { - return x.CreditCard - } - return nil -} - -type PlaceOrderResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Order *OrderResult `protobuf:"bytes,1,opt,name=order,proto3" json:"order,omitempty"` -} - -func (x *PlaceOrderResponse) Reset() { - *x = PlaceOrderResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[28] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PlaceOrderResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PlaceOrderResponse) ProtoMessage() {} - -func (x *PlaceOrderResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[28] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PlaceOrderResponse.ProtoReflect.Descriptor instead. -func (*PlaceOrderResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{28} -} - -func (x *PlaceOrderResponse) GetOrder() *OrderResult { - if x != nil { - return x.Order - } - return nil -} - -type AdRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // 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"` -} - -func (x *AdRequest) Reset() { - *x = AdRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[29] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AdRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AdRequest) ProtoMessage() {} - -func (x *AdRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[29] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AdRequest.ProtoReflect.Descriptor instead. -func (*AdRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{29} -} - -func (x *AdRequest) GetContextKeys() []string { - if x != nil { - return x.ContextKeys - } - return nil -} - -type AdResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Ads []*Ad `protobuf:"bytes,1,rep,name=ads,proto3" json:"ads,omitempty"` -} - -func (x *AdResponse) Reset() { - *x = AdResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[30] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AdResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AdResponse) ProtoMessage() {} - -func (x *AdResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[30] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AdResponse.ProtoReflect.Descriptor instead. -func (*AdResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{30} -} - -func (x *AdResponse) GetAds() []*Ad { - if x != nil { - return x.Ads - } - return nil -} - -type Ad struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // 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"` -} - -func (x *Ad) Reset() { - *x = Ad{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[31] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Ad) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Ad) ProtoMessage() {} - -func (x *Ad) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[31] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Ad.ProtoReflect.Descriptor instead. -func (*Ad) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{31} -} - -func (x *Ad) GetRedirectUrl() string { - if x != nil { - return x.RedirectUrl - } - return "" -} - -func (x *Ad) GetText() string { - if x != nil { - return x.Text - } - return "" -} - -var File_demo_proto protoreflect.FileDescriptor - -var file_demo_proto_rawDesc = []byte{ - 0x0a, 0x0a, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x68, 0x69, - 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x22, 0x45, 0x0a, 0x08, 0x43, 0x61, 0x72, - 0x74, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, - 0x63, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x22, 0x54, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x04, 0x69, - 0x74, 0x65, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x69, 0x70, 0x73, - 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x61, 0x72, 0x74, 0x49, 0x74, 0x65, 0x6d, - 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x2b, 0x0a, 0x10, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x43, - 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, - 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, - 0x72, 0x49, 0x64, 0x22, 0x29, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x43, 0x61, 0x72, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x4c, - 0x0a, 0x04, 0x43, 0x61, 0x72, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, - 0x2b, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, - 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x61, 0x72, - 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x07, 0x0a, 0x05, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x56, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, - 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, - 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x73, 0x22, 0x3e, 0x0a, - 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, - 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x73, 0x22, 0xba, 0x01, - 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, - 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x18, 0x0a, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x70, 0x72, 0x69, - 0x63, 0x65, 0x5f, 0x75, 0x73, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x68, - 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, - 0x52, 0x08, 0x70, 0x72, 0x69, 0x63, 0x65, 0x55, 0x73, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x61, - 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, - 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x22, 0x48, 0x0a, 0x14, 0x4c, 0x69, - 0x73, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x30, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, - 0x6f, 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x64, - 0x75, 0x63, 0x74, 0x73, 0x22, 0x23, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, - 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x2d, 0x0a, 0x15, 0x53, 0x65, 0x61, - 0x72, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x48, 0x0a, 0x16, 0x53, 0x65, 0x61, 0x72, - 0x63, 0x68, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, - 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x73, 0x22, 0x6e, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, - 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x07, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2b, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, - 0x6f, 0x70, 0x2e, 0x43, 0x61, 0x72, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, - 0x6d, 0x73, 0x22, 0x41, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x08, 0x63, 0x6f, 0x73, 0x74, 0x5f, 0x75, - 0x73, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, - 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x07, 0x63, 0x6f, - 0x73, 0x74, 0x55, 0x73, 0x64, 0x22, 0x6f, 0x0a, 0x10, 0x53, 0x68, 0x69, 0x70, 0x4f, 0x72, 0x64, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x07, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x68, 0x69, 0x70, - 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2b, 0x0a, 0x05, 0x69, 0x74, 0x65, - 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, - 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x61, 0x72, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, - 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x34, 0x0a, 0x11, 0x53, 0x68, 0x69, 0x70, 0x4f, 0x72, - 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, - 0x72, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x64, 0x22, 0x8f, 0x01, 0x0a, - 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x74, 0x72, 0x65, - 0x65, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0d, 0x73, 0x74, 0x72, 0x65, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, - 0x12, 0x0a, 0x04, 0x63, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, - 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x7a, 0x69, 0x70, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x7a, 0x69, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x58, - 0x0a, 0x05, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65, - 0x6e, 0x63, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, - 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x75, 0x6e, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x75, 0x6e, 0x69, - 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x05, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x22, 0x47, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x53, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x69, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x75, - 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x64, 0x65, - 0x73, 0x22, 0x5c, 0x0a, 0x19, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x6e, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, - 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x68, - 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, - 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x64, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x22, - 0xe6, 0x01, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x49, 0x6e, - 0x66, 0x6f, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5f, 0x63, 0x61, 0x72, - 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, - 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, - 0x12, 0x26, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x5f, - 0x63, 0x76, 0x76, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x63, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x43, 0x61, 0x72, 0x64, 0x43, 0x76, 0x76, 0x12, 0x3d, 0x0a, 0x1b, 0x63, 0x72, 0x65, 0x64, - 0x69, 0x74, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x79, 0x65, 0x61, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x18, 0x63, - 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x59, 0x65, 0x61, 0x72, 0x12, 0x3f, 0x0a, 0x1c, 0x63, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x19, 0x63, - 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x22, 0x79, 0x0a, 0x0d, 0x43, 0x68, 0x61, 0x72, - 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x06, 0x61, 0x6d, 0x6f, - 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x68, 0x69, 0x70, 0x73, - 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x06, 0x61, - 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3c, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5f, - 0x63, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x68, 0x69, 0x70, - 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, - 0x61, 0x72, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, - 0x61, 0x72, 0x64, 0x22, 0x37, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, - 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x5e, 0x0a, 0x09, - 0x4f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x29, 0x0a, 0x04, 0x69, 0x74, 0x65, - 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, - 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x61, 0x72, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, - 0x69, 0x74, 0x65, 0x6d, 0x12, 0x26, 0x0a, 0x04, 0x63, 0x6f, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, - 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x04, 0x63, 0x6f, 0x73, 0x74, 0x22, 0x82, 0x02, 0x0a, - 0x0b, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x19, 0x0a, 0x08, - 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x6f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x68, 0x69, 0x70, 0x70, - 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x68, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x54, - 0x72, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x64, 0x12, 0x37, 0x0a, 0x0d, 0x73, 0x68, 0x69, - 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x12, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4d, - 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x0c, 0x73, 0x68, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x43, 0x6f, - 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x10, 0x73, 0x68, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x68, - 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x52, 0x0f, 0x73, 0x68, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x41, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x12, 0x2c, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, - 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, - 0x73, 0x22, 0x64, 0x0a, 0x1c, 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x2e, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, - 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x22, 0xd5, 0x01, 0x0a, 0x11, 0x50, 0x6c, 0x61, 0x63, - 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, - 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, - 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x75, - 0x73, 0x65, 0x72, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x2e, 0x0a, 0x07, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x68, - 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, - 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, - 0x6c, 0x12, 0x3c, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5f, 0x63, 0x61, 0x72, 0x64, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, - 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x22, - 0x44, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x63, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, - 0x6f, 0x70, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x05, - 0x6f, 0x72, 0x64, 0x65, 0x72, 0x22, 0x2e, 0x0a, 0x09, 0x41, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x6b, 0x65, - 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, - 0x74, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x2f, 0x0a, 0x0a, 0x41, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x03, 0x61, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0f, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, - 0x64, 0x52, 0x03, 0x61, 0x64, 0x73, 0x22, 0x3b, 0x0a, 0x02, 0x41, 0x64, 0x12, 0x21, 0x0a, 0x0c, - 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x55, 0x72, 0x6c, 0x12, - 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, - 0x65, 0x78, 0x74, 0x32, 0xca, 0x01, 0x0a, 0x0b, 0x43, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x3c, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x1b, - 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, 0x64, 0x64, - 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x68, 0x69, - 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, - 0x00, 0x12, 0x3b, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x43, 0x61, 0x72, 0x74, 0x12, 0x1b, 0x2e, 0x68, - 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x61, - 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x68, 0x69, 0x70, 0x73, - 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x61, 0x72, 0x74, 0x22, 0x00, 0x12, 0x40, - 0x0a, 0x09, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x43, 0x61, 0x72, 0x74, 0x12, 0x1d, 0x2e, 0x68, 0x69, - 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x43, - 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x68, 0x69, 0x70, - 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, - 0x32, 0x83, 0x01, 0x0a, 0x15, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6a, 0x0a, 0x13, 0x4c, 0x69, - 0x73, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x27, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x69, 0x70, - 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, - 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0x83, 0x02, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x64, 0x75, - 0x63, 0x74, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x47, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, - 0x12, 0x12, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x21, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, - 0x6f, 0x70, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x0a, 0x47, 0x65, 0x74, - 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x1e, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, - 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, - 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x22, 0x00, 0x12, - 0x5b, 0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, - 0x73, 0x12, 0x22, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, - 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, - 0x68, 0x6f, 0x70, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, - 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0xaa, 0x01, 0x0a, - 0x0f, 0x53, 0x68, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x49, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x1c, 0x2e, 0x68, - 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x51, 0x75, - 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x68, 0x69, 0x70, - 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x09, 0x53, - 0x68, 0x69, 0x70, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x1d, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, - 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x53, 0x68, 0x69, 0x70, 0x4f, 0x72, 0x64, 0x65, 0x72, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, - 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x53, 0x68, 0x69, 0x70, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0xb7, 0x01, 0x0a, 0x0f, 0x43, 0x75, - 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5b, 0x0a, - 0x16, 0x47, 0x65, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x43, 0x75, 0x72, - 0x72, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x12, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, - 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x2b, 0x2e, 0x68, 0x69, - 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x07, 0x43, 0x6f, - 0x6e, 0x76, 0x65, 0x72, 0x74, 0x12, 0x26, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, - 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x6e, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, - 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4d, 0x6f, 0x6e, 0x65, - 0x79, 0x22, 0x00, 0x32, 0x55, 0x0a, 0x0e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x12, - 0x1a, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x68, - 0x61, 0x72, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x68, 0x69, - 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0x68, 0x0a, 0x0c, 0x45, 0x6d, - 0x61, 0x69, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x58, 0x0a, 0x15, 0x53, 0x65, - 0x6e, 0x64, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, - 0x70, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, - 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x22, 0x00, 0x32, 0x62, 0x0a, 0x0f, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4f, 0x0a, 0x0a, 0x50, 0x6c, 0x61, 0x63, 0x65, - 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x1e, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, - 0x68, 0x6f, 0x70, 0x2e, 0x50, 0x6c, 0x61, 0x63, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, - 0x68, 0x6f, 0x70, 0x2e, 0x50, 0x6c, 0x61, 0x63, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0x48, 0x0a, 0x09, 0x41, 0x64, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x41, 0x64, 0x73, 0x12, - 0x16, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, 0x64, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, - 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x42, 0x10, 0x5a, 0x0e, 0x2e, 0x2f, 0x3b, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, - 0x73, 0x68, 0x6f, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_demo_proto_rawDescOnce sync.Once - file_demo_proto_rawDescData = file_demo_proto_rawDesc -) - -func file_demo_proto_rawDescGZIP() []byte { - file_demo_proto_rawDescOnce.Do(func() { - file_demo_proto_rawDescData = protoimpl.X.CompressGZIP(file_demo_proto_rawDescData) - }) - return file_demo_proto_rawDescData -} - -var file_demo_proto_msgTypes = make([]protoimpl.MessageInfo, 32) -var file_demo_proto_goTypes = []interface{}{ - (*CartItem)(nil), // 0: hipstershop.CartItem - (*AddItemRequest)(nil), // 1: hipstershop.AddItemRequest - (*EmptyCartRequest)(nil), // 2: hipstershop.EmptyCartRequest - (*GetCartRequest)(nil), // 3: hipstershop.GetCartRequest - (*Cart)(nil), // 4: hipstershop.Cart - (*Empty)(nil), // 5: hipstershop.Empty - (*ListRecommendationsRequest)(nil), // 6: hipstershop.ListRecommendationsRequest - (*ListRecommendationsResponse)(nil), // 7: hipstershop.ListRecommendationsResponse - (*Product)(nil), // 8: hipstershop.Product - (*ListProductsResponse)(nil), // 9: hipstershop.ListProductsResponse - (*GetProductRequest)(nil), // 10: hipstershop.GetProductRequest - (*SearchProductsRequest)(nil), // 11: hipstershop.SearchProductsRequest - (*SearchProductsResponse)(nil), // 12: hipstershop.SearchProductsResponse - (*GetQuoteRequest)(nil), // 13: hipstershop.GetQuoteRequest - (*GetQuoteResponse)(nil), // 14: hipstershop.GetQuoteResponse - (*ShipOrderRequest)(nil), // 15: hipstershop.ShipOrderRequest - (*ShipOrderResponse)(nil), // 16: hipstershop.ShipOrderResponse - (*Address)(nil), // 17: hipstershop.Address - (*Money)(nil), // 18: hipstershop.Money - (*GetSupportedCurrenciesResponse)(nil), // 19: hipstershop.GetSupportedCurrenciesResponse - (*CurrencyConversionRequest)(nil), // 20: hipstershop.CurrencyConversionRequest - (*CreditCardInfo)(nil), // 21: hipstershop.CreditCardInfo - (*ChargeRequest)(nil), // 22: hipstershop.ChargeRequest - (*ChargeResponse)(nil), // 23: hipstershop.ChargeResponse - (*OrderItem)(nil), // 24: hipstershop.OrderItem - (*OrderResult)(nil), // 25: hipstershop.OrderResult - (*SendOrderConfirmationRequest)(nil), // 26: hipstershop.SendOrderConfirmationRequest - (*PlaceOrderRequest)(nil), // 27: hipstershop.PlaceOrderRequest - (*PlaceOrderResponse)(nil), // 28: hipstershop.PlaceOrderResponse - (*AdRequest)(nil), // 29: hipstershop.AdRequest - (*AdResponse)(nil), // 30: hipstershop.AdResponse - (*Ad)(nil), // 31: hipstershop.Ad -} -var file_demo_proto_depIdxs = []int32{ - 0, // 0: hipstershop.AddItemRequest.item:type_name -> hipstershop.CartItem - 0, // 1: hipstershop.Cart.items:type_name -> hipstershop.CartItem - 18, // 2: hipstershop.Product.price_usd:type_name -> hipstershop.Money - 8, // 3: hipstershop.ListProductsResponse.products:type_name -> hipstershop.Product - 8, // 4: hipstershop.SearchProductsResponse.results:type_name -> hipstershop.Product - 17, // 5: hipstershop.GetQuoteRequest.address:type_name -> hipstershop.Address - 0, // 6: hipstershop.GetQuoteRequest.items:type_name -> hipstershop.CartItem - 18, // 7: hipstershop.GetQuoteResponse.cost_usd:type_name -> hipstershop.Money - 17, // 8: hipstershop.ShipOrderRequest.address:type_name -> hipstershop.Address - 0, // 9: hipstershop.ShipOrderRequest.items:type_name -> hipstershop.CartItem - 18, // 10: hipstershop.CurrencyConversionRequest.from:type_name -> hipstershop.Money - 18, // 11: hipstershop.ChargeRequest.amount:type_name -> hipstershop.Money - 21, // 12: hipstershop.ChargeRequest.credit_card:type_name -> hipstershop.CreditCardInfo - 0, // 13: hipstershop.OrderItem.item:type_name -> hipstershop.CartItem - 18, // 14: hipstershop.OrderItem.cost:type_name -> hipstershop.Money - 18, // 15: hipstershop.OrderResult.shipping_cost:type_name -> hipstershop.Money - 17, // 16: hipstershop.OrderResult.shipping_address:type_name -> hipstershop.Address - 24, // 17: hipstershop.OrderResult.items:type_name -> hipstershop.OrderItem - 25, // 18: hipstershop.SendOrderConfirmationRequest.order:type_name -> hipstershop.OrderResult - 17, // 19: hipstershop.PlaceOrderRequest.address:type_name -> hipstershop.Address - 21, // 20: hipstershop.PlaceOrderRequest.credit_card:type_name -> hipstershop.CreditCardInfo - 25, // 21: hipstershop.PlaceOrderResponse.order:type_name -> hipstershop.OrderResult - 31, // 22: hipstershop.AdResponse.ads:type_name -> hipstershop.Ad - 1, // 23: hipstershop.CartService.AddItem:input_type -> hipstershop.AddItemRequest - 3, // 24: hipstershop.CartService.GetCart:input_type -> hipstershop.GetCartRequest - 2, // 25: hipstershop.CartService.EmptyCart:input_type -> hipstershop.EmptyCartRequest - 6, // 26: hipstershop.RecommendationService.ListRecommendations:input_type -> hipstershop.ListRecommendationsRequest - 5, // 27: hipstershop.ProductCatalogService.ListProducts:input_type -> hipstershop.Empty - 10, // 28: hipstershop.ProductCatalogService.GetProduct:input_type -> hipstershop.GetProductRequest - 11, // 29: hipstershop.ProductCatalogService.SearchProducts:input_type -> hipstershop.SearchProductsRequest - 13, // 30: hipstershop.ShippingService.GetQuote:input_type -> hipstershop.GetQuoteRequest - 15, // 31: hipstershop.ShippingService.ShipOrder:input_type -> hipstershop.ShipOrderRequest - 5, // 32: hipstershop.CurrencyService.GetSupportedCurrencies:input_type -> hipstershop.Empty - 20, // 33: hipstershop.CurrencyService.Convert:input_type -> hipstershop.CurrencyConversionRequest - 22, // 34: hipstershop.PaymentService.Charge:input_type -> hipstershop.ChargeRequest - 26, // 35: hipstershop.EmailService.SendOrderConfirmation:input_type -> hipstershop.SendOrderConfirmationRequest - 27, // 36: hipstershop.CheckoutService.PlaceOrder:input_type -> hipstershop.PlaceOrderRequest - 29, // 37: hipstershop.AdService.GetAds:input_type -> hipstershop.AdRequest - 5, // 38: hipstershop.CartService.AddItem:output_type -> hipstershop.Empty - 4, // 39: hipstershop.CartService.GetCart:output_type -> hipstershop.Cart - 5, // 40: hipstershop.CartService.EmptyCart:output_type -> hipstershop.Empty - 7, // 41: hipstershop.RecommendationService.ListRecommendations:output_type -> hipstershop.ListRecommendationsResponse - 9, // 42: hipstershop.ProductCatalogService.ListProducts:output_type -> hipstershop.ListProductsResponse - 8, // 43: hipstershop.ProductCatalogService.GetProduct:output_type -> hipstershop.Product - 12, // 44: hipstershop.ProductCatalogService.SearchProducts:output_type -> hipstershop.SearchProductsResponse - 14, // 45: hipstershop.ShippingService.GetQuote:output_type -> hipstershop.GetQuoteResponse - 16, // 46: hipstershop.ShippingService.ShipOrder:output_type -> hipstershop.ShipOrderResponse - 19, // 47: hipstershop.CurrencyService.GetSupportedCurrencies:output_type -> hipstershop.GetSupportedCurrenciesResponse - 18, // 48: hipstershop.CurrencyService.Convert:output_type -> hipstershop.Money - 23, // 49: hipstershop.PaymentService.Charge:output_type -> hipstershop.ChargeResponse - 5, // 50: hipstershop.EmailService.SendOrderConfirmation:output_type -> hipstershop.Empty - 28, // 51: hipstershop.CheckoutService.PlaceOrder:output_type -> hipstershop.PlaceOrderResponse - 30, // 52: hipstershop.AdService.GetAds:output_type -> hipstershop.AdResponse - 38, // [38:53] is the sub-list for method output_type - 23, // [23:38] is the sub-list for method input_type - 23, // [23:23] is the sub-list for extension type_name - 23, // [23:23] is the sub-list for extension extendee - 0, // [0:23] is the sub-list for field type_name -} - -func init() { file_demo_proto_init() } -func file_demo_proto_init() { - if File_demo_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_demo_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CartItem); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddItemRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EmptyCartRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetCartRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Cart); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Empty); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListRecommendationsRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListRecommendationsResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Product); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListProductsResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetProductRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SearchProductsRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SearchProductsResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetQuoteRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetQuoteResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ShipOrderRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ShipOrderResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Address); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Money); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSupportedCurrenciesResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CurrencyConversionRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreditCardInfo); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ChargeRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ChargeResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OrderItem); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OrderResult); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SendOrderConfirmationRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PlaceOrderRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PlaceOrderResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AdRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AdResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Ad); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_demo_proto_rawDesc, - NumEnums: 0, - NumMessages: 32, - NumExtensions: 0, - NumServices: 9, - }, - GoTypes: file_demo_proto_goTypes, - DependencyIndexes: file_demo_proto_depIdxs, - MessageInfos: file_demo_proto_msgTypes, - }.Build() - File_demo_proto = out.File - file_demo_proto_rawDesc = nil - file_demo_proto_goTypes = nil - file_demo_proto_depIdxs = nil -} diff --git a/src/checkoutservice/genproto/demo_grpc.pb.go b/src/checkoutservice/genproto/demo_grpc.pb.go deleted file mode 100644 index f4c37599a..000000000 --- a/src/checkoutservice/genproto/demo_grpc.pb.go +++ /dev/null @@ -1,1019 +0,0 @@ -// 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. - -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. - -package hipstershop - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 - -// CartServiceClient is the client API for CartService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type 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.ClientConnInterface -} - -func NewCartServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedCartServiceServer -// for forward compatibility -type CartServiceServer interface { - AddItem(context.Context, *AddItemRequest) (*Empty, error) - GetCart(context.Context, *GetCartRequest) (*Cart, error) - EmptyCart(context.Context, *EmptyCartRequest) (*Empty, error) - mustEmbedUnimplementedCartServiceServer() -} - -// UnimplementedCartServiceServer must be embedded to have forward compatible implementations. -type UnimplementedCartServiceServer struct { -} - -func (UnimplementedCartServiceServer) AddItem(context.Context, *AddItemRequest) (*Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method AddItem not implemented") -} -func (UnimplementedCartServiceServer) GetCart(context.Context, *GetCartRequest) (*Cart, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetCart not implemented") -} -func (UnimplementedCartServiceServer) EmptyCart(context.Context, *EmptyCartRequest) (*Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method EmptyCart not implemented") -} -func (UnimplementedCartServiceServer) mustEmbedUnimplementedCartServiceServer() {} - -// UnsafeCartServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to CartServiceServer will -// result in compilation errors. -type UnsafeCartServiceServer interface { - mustEmbedUnimplementedCartServiceServer() -} - -func RegisterCartServiceServer(s grpc.ServiceRegistrar, 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) -} - -// CartService_ServiceDesc is the grpc.ServiceDesc for CartService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type RecommendationServiceClient interface { - ListRecommendations(ctx context.Context, in *ListRecommendationsRequest, opts ...grpc.CallOption) (*ListRecommendationsResponse, error) -} - -type recommendationServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewRecommendationServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedRecommendationServiceServer -// for forward compatibility -type RecommendationServiceServer interface { - ListRecommendations(context.Context, *ListRecommendationsRequest) (*ListRecommendationsResponse, error) - mustEmbedUnimplementedRecommendationServiceServer() -} - -// UnimplementedRecommendationServiceServer must be embedded to have forward compatible implementations. -type UnimplementedRecommendationServiceServer struct { -} - -func (UnimplementedRecommendationServiceServer) ListRecommendations(context.Context, *ListRecommendationsRequest) (*ListRecommendationsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListRecommendations not implemented") -} -func (UnimplementedRecommendationServiceServer) mustEmbedUnimplementedRecommendationServiceServer() {} - -// UnsafeRecommendationServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to RecommendationServiceServer will -// result in compilation errors. -type UnsafeRecommendationServiceServer interface { - mustEmbedUnimplementedRecommendationServiceServer() -} - -func RegisterRecommendationServiceServer(s grpc.ServiceRegistrar, 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) -} - -// RecommendationService_ServiceDesc is the grpc.ServiceDesc for RecommendationService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#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.ClientConnInterface -} - -func NewProductCatalogServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedProductCatalogServiceServer -// for forward compatibility -type ProductCatalogServiceServer interface { - ListProducts(context.Context, *Empty) (*ListProductsResponse, error) - GetProduct(context.Context, *GetProductRequest) (*Product, error) - SearchProducts(context.Context, *SearchProductsRequest) (*SearchProductsResponse, error) - mustEmbedUnimplementedProductCatalogServiceServer() -} - -// UnimplementedProductCatalogServiceServer must be embedded to have forward compatible implementations. -type UnimplementedProductCatalogServiceServer struct { -} - -func (UnimplementedProductCatalogServiceServer) ListProducts(context.Context, *Empty) (*ListProductsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListProducts not implemented") -} -func (UnimplementedProductCatalogServiceServer) GetProduct(context.Context, *GetProductRequest) (*Product, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetProduct not implemented") -} -func (UnimplementedProductCatalogServiceServer) SearchProducts(context.Context, *SearchProductsRequest) (*SearchProductsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method SearchProducts not implemented") -} -func (UnimplementedProductCatalogServiceServer) mustEmbedUnimplementedProductCatalogServiceServer() {} - -// UnsafeProductCatalogServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to ProductCatalogServiceServer will -// result in compilation errors. -type UnsafeProductCatalogServiceServer interface { - mustEmbedUnimplementedProductCatalogServiceServer() -} - -func RegisterProductCatalogServiceServer(s grpc.ServiceRegistrar, 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) -} - -// ProductCatalogService_ServiceDesc is the grpc.ServiceDesc for ProductCatalogService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#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.ClientConnInterface -} - -func NewShippingServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedShippingServiceServer -// for forward compatibility -type ShippingServiceServer interface { - GetQuote(context.Context, *GetQuoteRequest) (*GetQuoteResponse, error) - ShipOrder(context.Context, *ShipOrderRequest) (*ShipOrderResponse, error) - mustEmbedUnimplementedShippingServiceServer() -} - -// UnimplementedShippingServiceServer must be embedded to have forward compatible implementations. -type UnimplementedShippingServiceServer struct { -} - -func (UnimplementedShippingServiceServer) GetQuote(context.Context, *GetQuoteRequest) (*GetQuoteResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetQuote not implemented") -} -func (UnimplementedShippingServiceServer) ShipOrder(context.Context, *ShipOrderRequest) (*ShipOrderResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ShipOrder not implemented") -} -func (UnimplementedShippingServiceServer) mustEmbedUnimplementedShippingServiceServer() {} - -// UnsafeShippingServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to ShippingServiceServer will -// result in compilation errors. -type UnsafeShippingServiceServer interface { - mustEmbedUnimplementedShippingServiceServer() -} - -func RegisterShippingServiceServer(s grpc.ServiceRegistrar, 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) -} - -// ShippingService_ServiceDesc is the grpc.ServiceDesc for ShippingService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#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.ClientConnInterface -} - -func NewCurrencyServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedCurrencyServiceServer -// for forward compatibility -type CurrencyServiceServer interface { - GetSupportedCurrencies(context.Context, *Empty) (*GetSupportedCurrenciesResponse, error) - Convert(context.Context, *CurrencyConversionRequest) (*Money, error) - mustEmbedUnimplementedCurrencyServiceServer() -} - -// UnimplementedCurrencyServiceServer must be embedded to have forward compatible implementations. -type UnimplementedCurrencyServiceServer struct { -} - -func (UnimplementedCurrencyServiceServer) GetSupportedCurrencies(context.Context, *Empty) (*GetSupportedCurrenciesResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetSupportedCurrencies not implemented") -} -func (UnimplementedCurrencyServiceServer) Convert(context.Context, *CurrencyConversionRequest) (*Money, error) { - return nil, status.Errorf(codes.Unimplemented, "method Convert not implemented") -} -func (UnimplementedCurrencyServiceServer) mustEmbedUnimplementedCurrencyServiceServer() {} - -// UnsafeCurrencyServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to CurrencyServiceServer will -// result in compilation errors. -type UnsafeCurrencyServiceServer interface { - mustEmbedUnimplementedCurrencyServiceServer() -} - -func RegisterCurrencyServiceServer(s grpc.ServiceRegistrar, 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) -} - -// CurrencyService_ServiceDesc is the grpc.ServiceDesc for CurrencyService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type PaymentServiceClient interface { - Charge(ctx context.Context, in *ChargeRequest, opts ...grpc.CallOption) (*ChargeResponse, error) -} - -type paymentServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewPaymentServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedPaymentServiceServer -// for forward compatibility -type PaymentServiceServer interface { - Charge(context.Context, *ChargeRequest) (*ChargeResponse, error) - mustEmbedUnimplementedPaymentServiceServer() -} - -// UnimplementedPaymentServiceServer must be embedded to have forward compatible implementations. -type UnimplementedPaymentServiceServer struct { -} - -func (UnimplementedPaymentServiceServer) Charge(context.Context, *ChargeRequest) (*ChargeResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Charge not implemented") -} -func (UnimplementedPaymentServiceServer) mustEmbedUnimplementedPaymentServiceServer() {} - -// UnsafePaymentServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to PaymentServiceServer will -// result in compilation errors. -type UnsafePaymentServiceServer interface { - mustEmbedUnimplementedPaymentServiceServer() -} - -func RegisterPaymentServiceServer(s grpc.ServiceRegistrar, 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) -} - -// PaymentService_ServiceDesc is the grpc.ServiceDesc for PaymentService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type EmailServiceClient interface { - SendOrderConfirmation(ctx context.Context, in *SendOrderConfirmationRequest, opts ...grpc.CallOption) (*Empty, error) -} - -type emailServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewEmailServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedEmailServiceServer -// for forward compatibility -type EmailServiceServer interface { - SendOrderConfirmation(context.Context, *SendOrderConfirmationRequest) (*Empty, error) - mustEmbedUnimplementedEmailServiceServer() -} - -// UnimplementedEmailServiceServer must be embedded to have forward compatible implementations. -type UnimplementedEmailServiceServer struct { -} - -func (UnimplementedEmailServiceServer) SendOrderConfirmation(context.Context, *SendOrderConfirmationRequest) (*Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method SendOrderConfirmation not implemented") -} -func (UnimplementedEmailServiceServer) mustEmbedUnimplementedEmailServiceServer() {} - -// UnsafeEmailServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to EmailServiceServer will -// result in compilation errors. -type UnsafeEmailServiceServer interface { - mustEmbedUnimplementedEmailServiceServer() -} - -func RegisterEmailServiceServer(s grpc.ServiceRegistrar, 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) -} - -// EmailService_ServiceDesc is the grpc.ServiceDesc for EmailService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type CheckoutServiceClient interface { - PlaceOrder(ctx context.Context, in *PlaceOrderRequest, opts ...grpc.CallOption) (*PlaceOrderResponse, error) -} - -type checkoutServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewCheckoutServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedCheckoutServiceServer -// for forward compatibility -type CheckoutServiceServer interface { - PlaceOrder(context.Context, *PlaceOrderRequest) (*PlaceOrderResponse, error) - mustEmbedUnimplementedCheckoutServiceServer() -} - -// UnimplementedCheckoutServiceServer must be embedded to have forward compatible implementations. -type UnimplementedCheckoutServiceServer struct { -} - -func (UnimplementedCheckoutServiceServer) PlaceOrder(context.Context, *PlaceOrderRequest) (*PlaceOrderResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method PlaceOrder not implemented") -} -func (UnimplementedCheckoutServiceServer) mustEmbedUnimplementedCheckoutServiceServer() {} - -// UnsafeCheckoutServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to CheckoutServiceServer will -// result in compilation errors. -type UnsafeCheckoutServiceServer interface { - mustEmbedUnimplementedCheckoutServiceServer() -} - -func RegisterCheckoutServiceServer(s grpc.ServiceRegistrar, 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) -} - -// CheckoutService_ServiceDesc is the grpc.ServiceDesc for CheckoutService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type AdServiceClient interface { - GetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error) -} - -type adServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewAdServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedAdServiceServer -// for forward compatibility -type AdServiceServer interface { - GetAds(context.Context, *AdRequest) (*AdResponse, error) - mustEmbedUnimplementedAdServiceServer() -} - -// UnimplementedAdServiceServer must be embedded to have forward compatible implementations. -type UnimplementedAdServiceServer struct { -} - -func (UnimplementedAdServiceServer) GetAds(context.Context, *AdRequest) (*AdResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetAds not implemented") -} -func (UnimplementedAdServiceServer) mustEmbedUnimplementedAdServiceServer() {} - -// UnsafeAdServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to AdServiceServer will -// result in compilation errors. -type UnsafeAdServiceServer interface { - mustEmbedUnimplementedAdServiceServer() -} - -func RegisterAdServiceServer(s grpc.ServiceRegistrar, 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) -} - -// AdService_ServiceDesc is the grpc.ServiceDesc for AdService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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", -} diff --git a/src/checkoutservice/go.mod b/src/checkoutservice/go.mod deleted file mode 100644 index cba86e724..000000000 --- a/src/checkoutservice/go.mod +++ /dev/null @@ -1,22 +0,0 @@ -module github.com/GoogleCloudPlatform/cloud-ops-sandbox/src/checkoutservice - -go 1.16 - -require ( - cloud.google.com/go v0.61.0 - contrib.go.opencensus.io/exporter/stackdriver v0.13.5 - github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v0.20.0 - github.com/aws/aws-sdk-go v1.30.15 // indirect - github.com/golang/protobuf v1.5.2 - github.com/google/uuid v1.1.2 - github.com/sirupsen/logrus v1.6.0 - go.opencensus.io v0.23.0 - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0 - go.opentelemetry.io/otel v0.20.0 - go.opentelemetry.io/otel/sdk v0.20.0 - go.opentelemetry.io/otel/trace v0.20.0 - golang.org/x/net v0.0.0-20210614182718-04defd469f4e - google.golang.org/grpc v1.38.0 - google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 - google.golang.org/protobuf v1.26.0 -) diff --git a/src/checkoutservice/go.sum b/src/checkoutservice/go.sum deleted file mode 100644 index defac0987..000000000 --- a/src/checkoutservice/go.sum +++ /dev/null @@ -1,459 +0,0 @@ -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.61.0 h1:NLQf5e1OMspfNT1RAHOB3ublr1TW3YTXO8OiWwVjK2U= -cloud.google.com/go v0.61.0/go.mod h1:XukKJg4Y7QsUu0Hxg3qQKUWR4VuWivmyMK2+rUyxAqw= -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/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/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= -contrib.go.opencensus.io/exporter/stackdriver v0.13.5 h1:TNaexHK16gPUoc7uzELKOU7JULqccn1NDuqUxmxSqfo= -contrib.go.opencensus.io/exporter/stackdriver v0.13.5/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= -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/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v0.20.0 h1:ExGRyJwOUijAPv/RzCJ3p1CNUxBQGzVO238m1lFjLS4= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v0.20.0/go.mod h1:f4BFp2+kV6s/OKj3IP/34keB/OE7tTTaZZQyX/mQ7Ng= -github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.30.15 h1:Sd8QDVzzE8Sl+xNccmdj0HwMrFowv6uVUx9tGsCE1ZE= -github.com/aws/aws-sdk-go v1.30.15/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= -github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -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-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -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.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -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/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -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/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 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -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.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -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.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/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/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 h1:Ak8CrdlwwXwAZxzS66vgPt4U8yUZX7JwLvVR58FN5jM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -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 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleinterns/cloud-operations-api-mock v0.0.0-20200709193332-a1e58c29bdd3 h1:eHv/jVY/JNop1xg2J9cBb4EzyMpWZoNCP1BslSAIkOI= -github.com/googleinterns/cloud-operations-api-mock v0.0.0-20200709193332-a1e58c29bdd3/go.mod h1:h/KNeRx7oYU4SpA4SoY7W2/NxDKEEVuwA6j9A27L4OI= -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/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc= -github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= -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 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= -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/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -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/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -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/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= -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.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opentelemetry.io/contrib v0.20.0 h1:ubFQUn0VCZ0gPwIoJfBJVpeBlyRMxu8Mm/huKWYd9p0= -go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0 h1:sO4WKdPAudZGKPcpZT4MJn6JaDmpyLrMPDGGyA1SttE= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0 h1:Q3C9yzW6I9jqEc8sawxzxZmY48fs9u220KXq6d5s3XU= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= -go.opentelemetry.io/otel v0.20.0 h1:eaP0Fqu7SXHwvjiqDq83zImeehOHX8doTvU9AwXON8g= -go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= -go.opentelemetry.io/otel/metric v0.20.0 h1:4kzhXFP+btKm4jwxpjIqjs41A7MakRFUS86bqLHTIw8= -go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= -go.opentelemetry.io/otel/oteltest v0.20.0 h1:HiITxCawalo5vQzdHfKeZurV8x7ljcqAgiWzF6Vaeaw= -go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= -go.opentelemetry.io/otel/sdk v0.20.0 h1:JsxtGXd06J8jrnya7fdI/U/MR6yXA5DtbZy+qoHQlr8= -go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= -go.opentelemetry.io/otel/trace v0.20.0 h1:1DL6EXUdcg95gukhuRRvLDO/4X5THh/5dIV52lqtnbw= -go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= -go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -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 h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/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 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= -golang.org/x/mod v0.3.0/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-20190923162816-aa69164e4478/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-20200602114024-627f9648deb9/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-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210510120150-4163338589ed h1:p9UgmWI9wKpfYmgaV/IZKGdXc5qEK45tDwwwDyjS26I= -golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-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 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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-20190422165155-953cdadca894/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-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-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-20201214210602-f9fddec55a1e h1:AyodaIpKjppX+cBfTASF2E1US3H2JFBj920Ot3rtDjs= -golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -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 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -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-20191010075000-0337d82405ff/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-20191108193012-7d206e10da11/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-20200701151220-7cb253f4c4f8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed h1:+qzWo37K31KxduIYaBeMqJ8MUOyTayOQKpH9aDPLMSY= -golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -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 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/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.10.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 h1:BaiDisFir8O4IJxvAabCGGkQ6yCJegNQqSVoYUNAnbk= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -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.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= -google.golang.org/appengine v1.6.6/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-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-20200605102947-12044bf5ea91/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200711021454-869866162049/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200715011427-11fb19a81f2c h1:6DWnZZ6EY/59QRRQttZKiktVL23UuQYs7uy75MhhLRM= -google.golang.org/genproto v0.0.0-20200715011427-11fb19a81f2c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -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.23.1/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.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= -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 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -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.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= diff --git a/src/checkoutservice/main.go b/src/checkoutservice/main.go deleted file mode 100644 index 29cce8255..000000000 --- a/src/checkoutservice/main.go +++ /dev/null @@ -1,442 +0,0 @@ -// 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/stackdriver" - "github.com/google/uuid" - "github.com/sirupsen/logrus" - "go.opencensus.io/plugin/ocgrpc" - "go.opencensus.io/stats/view" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - pb "github.com/GoogleCloudPlatform/cloud-ops-sandbox/src/checkoutservice/genproto" - money "github.com/GoogleCloudPlatform/cloud-ops-sandbox/src/checkoutservice/money" - healthpb "google.golang.org/grpc/health/grpc_health_v1" - - // OpenTelemetry - // OTel traces -> GCP Trace direct exporter - texporter "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace" - "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" - "go.opentelemetry.io/otel" - - "go.opentelemetry.io/otel/sdk/resource" - sdktrace "go.opentelemetry.io/otel/sdk/trace" - "go.opentelemetry.io/otel/semconv" - apitrace "go.opentelemetry.io/otel/trace" -) - -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 - productCatalogSvcConn *grpc.ClientConn - - cartSvcAddr string - cartSvcConn *grpc.ClientConn - - currencySvcAddr string - currencySvcConn *grpc.ClientConn - - shippingSvcAddr string - shippingSvcConn *grpc.ClientConn - - emailSvcAddr string - emailSvcConn *grpc.ClientConn - - paymentSvcAddr string - paymentSvcConn *grpc.ClientConn - - pb.UnimplementedCheckoutServiceServer -} - -func main() { - ctx := context.Background() - go initOpenCensusStats() - initTraceProvider() - go initProfiling("checkoutservice", "1.0.0") - - 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") - - mustConnGRPC(ctx, &svc.shippingSvcConn, svc.shippingSvcAddr) - mustConnGRPC(ctx, &svc.productCatalogSvcConn, svc.productCatalogSvcAddr) - mustConnGRPC(ctx, &svc.cartSvcConn, svc.cartSvcAddr) - mustConnGRPC(ctx, &svc.currencySvcConn, svc.currencySvcAddr) - mustConnGRPC(ctx, &svc.emailSvcConn, svc.emailSvcAddr) - mustConnGRPC(ctx, &svc.paymentSvcConn, svc.paymentSvcAddr) - - log.Infof("service config: %+v", svc) - - lis, err := net.Listen("tcp", fmt.Sprintf(":%s", port)) - if err != nil { - log.Fatal(err) - } - intercepterOpt := otelgrpc.WithTracerProvider(otel.GetTracerProvider()) - srv := grpc.NewServer( - grpc.StatsHandler(&ocgrpc.ServerHandler{}), // TODO: replace with OTel grpc metrics collector - // OpenTelemetry gRPC server channel interceptors receive trace contexts from clients. - grpc.UnaryInterceptor(otelgrpc.UnaryServerInterceptor(intercepterOpt)), - grpc.StreamInterceptor(otelgrpc.StreamServerInterceptor(intercepterOpt)), - ) - 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) -} - -// Initialize Stats collection using OpenCensus -// TOOD: remove this after conversion to OpenTelemetry Metrics -func initOpenCensusStats() { - 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 { - // Register the views to collect server stats. - 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") - } - 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") -} - -// Initialize OTel trace provider that exports to Cloud Trace -func initTraceProvider() { - // When running on GCP, authentication is handled automatically - // using default credentials. This environment variable check - // is to help debug projects running locally. It's possible for this - // warning to be printed while the exporter works normally. See - // https://developers.google.com/identity/protocols/application-default-credentials - // for more details. - projectID := os.Getenv("GOOGLE_CLOUD_PROJECT") - if len(projectID) == 0 { - log.Warn("GOOGLE_CLOUD_PROJECT not set") - } - for i := 1; i <= 3; i++ { - exporter, err := texporter.NewExporter(texporter.WithProjectID(projectID)) - if err != nil { - log.Infof("failed to initialize exporter: %v", err) - } else { - // Create trace provider with the exporter. - // This is a demo app with low QPS. AlwaysSample() is used here - // to make sure traces are available for observation and analysis. - // It should not be used in production environments. - tp := sdktrace.NewTracerProvider( - sdktrace.WithSampler(sdktrace.AlwaysSample()), - sdktrace.WithSyncer(exporter), - // TODO: replace with predefined constant for GKE or autodetection when available - sdktrace.WithResource(resource.NewWithAttributes(semconv.ServiceNameKey.String("GKE")))) - if err == nil { - log.Info("initialized trace provider") - otel.SetTracerProvider(tp) - return - } else { - d := time.Second * 10 * time.Duration(i) - log.Infof("sleeping %v to retry initializing trace provider", d) - time.Sleep(d) - } - } - } - log.Warn("failed to initialize trace provider") -} - -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 -} - -// Watch is for health checking. -func (cs *checkoutService) Check(ctx context.Context, req *healthpb.HealthCheckRequest) (*healthpb.HealthCheckResponse, error) { - return &healthpb.HealthCheckResponse{Status: healthpb.HealthCheckResponse_SERVING}, nil -} - -// Watch is for health checking. -func (cs *checkoutService) Watch(req *healthpb.HealthCheckRequest, server healthpb.Health_WatchServer) error { - return nil -} - -// Acting as gRPC server, handling PlaceOrder request from Frontend. -func (cs *checkoutService) PlaceOrder(ctx context.Context, req *pb.PlaceOrderRequest) (*pb.PlaceOrderResponse, error) { - span := apitrace.SpanFromContext(ctx) - span.AddEvent(fmt.Sprintf("Place Order for user %q", req.UserId)) - 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") - } - - // Dispatch subtasks (as gRPC client) - span.AddEvent("Prepare Items from Cart") - 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 { - total = money.Must(money.Sum(total, *it.Cost)) - } - - span.AddEvent("Charge Credit Card") - 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) - - span.AddEvent("Prepare Shipment") - shippingTrackingID, err := cs.shipOrder(ctx, req.Address, prep.cartItems) - if err != nil { - return nil, status.Errorf(codes.Unavailable, "shipping error: %+v", err) - } - - span.AddEvent("Empty Cart") - _ = cs.emptyUserCart(ctx, req.UserId) - - orderResult := &pb.OrderResult{ - OrderId: orderID.String(), - ShippingTrackingId: shippingTrackingID, - ShippingCost: prep.shippingCostLocalized, - ShippingAddress: req.Address, - Items: prep.orderItems, - } - - span.AddEvent("Send Confirmation Email") - 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 -} - -// Acting as gRPC client -func (cs *checkoutService) quoteShipping(ctx context.Context, address *pb.Address, items []*pb.CartItem) (*pb.Money, error) { - shippingQuote, err := pb.NewShippingServiceClient(cs.shippingSvcConn). - 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 -} - -// Acting as gPRC client -func (cs *checkoutService) getUserCart(ctx context.Context, userID string) ([]*pb.CartItem, error) { - cart, err := pb.NewCartServiceClient(cs.cartSvcConn).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 -} - -// Acting as gPRC client -func (cs *checkoutService) emptyUserCart(ctx context.Context, userID string) error { - if _, err := pb.NewCartServiceClient(cs.cartSvcConn).EmptyCart(ctx, &pb.EmptyCartRequest{UserId: userID}); err != nil { - return fmt.Errorf("failed to empty user cart during checkout: %+v", err) - } - return nil -} - -// Acting as gPRC client -func (cs *checkoutService) prepOrderItems(ctx context.Context, items []*pb.CartItem, userCurrency string) ([]*pb.OrderItem, error) { - out := make([]*pb.OrderItem, len(items)) - - cl := pb.NewProductCatalogServiceClient(cs.productCatalogSvcConn) - - 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()) - } - // Note: This log line is used in a log-based metric. Changes to the log line will not be compatible with the metric. - log.Infof("orderedItem=%q, id=%q", product.Name, product.Id) - 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 -} - -// Acting as gPRC client -func (cs *checkoutService) convertCurrency(ctx context.Context, from *pb.Money, toCurrency string) (*pb.Money, error) { - result, err := pb.NewCurrencyServiceClient(cs.currencySvcConn).Convert(ctx, &pb.CurrencyConversionRequest{ - From: from, - ToCode: toCurrency}) - if err != nil { - return nil, fmt.Errorf("failed to convert currency: %+v", err) - } - return result, err -} - -// Acting as gPRC client -func (cs *checkoutService) chargeCard(ctx context.Context, amount *pb.Money, paymentInfo *pb.CreditCardInfo) (string, error) { - paymentResp, err := pb.NewPaymentServiceClient(cs.paymentSvcConn).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 { - _, err := pb.NewEmailServiceClient(cs.emailSvcConn).SendOrderConfirmation(ctx, &pb.SendOrderConfirmationRequest{ - Email: email, - Order: order}) - return err -} - -// Acting as gPRC client -func (cs *checkoutService) shipOrder(ctx context.Context, address *pb.Address, items []*pb.CartItem) (string, error) { - resp, err := pb.NewShippingServiceClient(cs.shippingSvcConn).ShipOrder(ctx, &pb.ShipOrderRequest{ - Address: address, - Items: items}) - if err != nil { - return "", fmt.Errorf("shipment failed: %+v", err) - } - return resp.GetTrackingId(), nil -} - -// Helper function for gRPC connections: Dial and create client once, reuse. -func mustConnGRPC(ctx context.Context, conn **grpc.ClientConn, addr string) { - var err error - intercepterOpt := otelgrpc.WithTracerProvider(otel.GetTracerProvider()) - *conn, err = grpc.DialContext(ctx, addr, - grpc.WithInsecure(), - grpc.WithTimeout(time.Second*3), - grpc.WithStatsHandler(&ocgrpc.ClientHandler{}), // TODO: replace with OTel grpc metrics collector - // OpenTelemetry gRPC client channel interceptors pass trace contexts to the server. - grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor(intercepterOpt)), - grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor(intercepterOpt))) - if err != nil { - panic(fmt.Sprintf("Error %s grpc: failed to connect %s", err, addr)) - } -} diff --git a/src/checkoutservice/money/money.go b/src/checkoutservice/money/money.go deleted file mode 100644 index 5eb014964..000000000 --- a/src/checkoutservice/money/money.go +++ /dev/null @@ -1,132 +0,0 @@ -// 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/cloud-ops-sandbox/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 -} diff --git a/src/checkoutservice/money/money_test.go b/src/checkoutservice/money/money_test.go deleted file mode 100644 index f06810579..000000000 --- a/src/checkoutservice/money/money_test.go +++ /dev/null @@ -1,245 +0,0 @@ -// 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/cloud-ops-sandbox/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) - } - }) - } -} diff --git a/src/checkoutservice/tools.go b/src/checkoutservice/tools.go deleted file mode 100644 index 0600f7bb9..000000000 --- a/src/checkoutservice/tools.go +++ /dev/null @@ -1,22 +0,0 @@ -// 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. - -// +build tools - -package main - -import ( - _ "google.golang.org/grpc/cmd/protoc-gen-go-grpc" - _ "google.golang.org/protobuf/cmd/protoc-gen-go" -) diff --git a/src/currencyservice/.dockerignore b/src/currencyservice/.dockerignore deleted file mode 100644 index 4d92be150..000000000 --- a/src/currencyservice/.dockerignore +++ /dev/null @@ -1,2 +0,0 @@ -client.js -node_modules/ diff --git a/src/currencyservice/.gitignore b/src/currencyservice/.gitignore deleted file mode 100644 index c2658d7d1..000000000 --- a/src/currencyservice/.gitignore +++ /dev/null @@ -1 +0,0 @@ -node_modules/ diff --git a/src/currencyservice/Dockerfile b/src/currencyservice/Dockerfile deleted file mode 100644 index 4badc841b..000000000 --- a/src/currencyservice/Dockerfile +++ /dev/null @@ -1,46 +0,0 @@ -# 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:12-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.3.5 && \ - 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" ] diff --git a/src/currencyservice/client.js b/src/currencyservice/client.js deleted file mode 100644 index f381dc8d1..000000000 --- a/src/currencyservice/client.js +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - * 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}.${leftPad(m.nanos, 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)}`); - } -}); diff --git a/src/currencyservice/genproto.sh b/src/currencyservice/genproto.sh deleted file mode 100755 index a9609fd15..000000000 --- a/src/currencyservice/genproto.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/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. - -# protos are loaded dynamically for node, simply copies over the proto. -mkdir -p proto -cp -r ../../pb/* ./proto diff --git a/src/currencyservice/package-lock.json b/src/currencyservice/package-lock.json deleted file mode 100644 index c2c01f850..000000000 --- a/src/currencyservice/package-lock.json +++ /dev/null @@ -1,8701 +0,0 @@ -{ - "name": "grpc-currency-service", - "version": "0.1.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "grpc-currency-service", - "version": "0.1.0", - "license": "Apache-2.0", - "dependencies": { - "@google-cloud/debug-agent": "5.1.3", - "@google-cloud/opentelemetry-cloud-trace-exporter": "^0.10.0", - "@google-cloud/profiler": "4.1.2", - "@grpc/proto-loader": "0.6.2", - "@opentelemetry/api": "^1.0.0", - "@opentelemetry/instrumentation-grpc": "^0.23.0", - "@opentelemetry/node": "^0.23.0", - "@opentelemetry/tracing": "^0.22.0", - "ajv": "^5.0.0", - "async": "3.2.0", - "google-protobuf": "3.13.0", - "grpc": "1.24.10", - "left-pad": "1.3.0", - "pino": "5.17.0", - "request": "2.88.2", - "xml2js": "0.4.23" - }, - "devDependencies": { - "semistandard": "^15.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/@eslint/eslintrc": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz", - "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "lodash": "^4.17.19", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "node_modules/@eslint/eslintrc/node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/@google-cloud/common": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.6.0.tgz", - "integrity": "sha512-aHIFTqJZmeTNO9md8XxV+ywuvXF3xBm5WNmgWeeCK+XN5X+kGW0WEX94wGwj+/MdOnrVf4dL2RvSIt9J5yJG6Q==", - "dependencies": { - "@google-cloud/projectify": "^2.0.0", - "@google-cloud/promisify": "^2.0.0", - "arrify": "^2.0.1", - "duplexify": "^4.1.1", - "ent": "^2.2.0", - "extend": "^3.0.2", - "google-auth-library": "^7.0.2", - "retry-request": "^4.1.1", - "teeny-request": "^7.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@google-cloud/debug-agent": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/@google-cloud/debug-agent/-/debug-agent-5.1.3.tgz", - "integrity": "sha512-WbzeEz4MvPlM7DX2QBsPcWgF62u7LSQv/oMYPl0L+TddTebqjDKiVXwxpzWk61NIfcKiet3dyCbPIt3N5o8XPQ==", - "dependencies": { - "@google-cloud/common": "^3.0.0", - "acorn": "^8.0.0", - "coffeescript": "^2.0.0", - "console-log-level": "^1.4.0", - "extend": "^3.0.2", - "findit2": "^2.2.3", - "gcp-metadata": "^4.0.0", - "p-limit": "^3.0.1", - "semver": "^7.0.0", - "source-map": "^0.6.1", - "split": "^1.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@google-cloud/opentelemetry-cloud-trace-exporter": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@google-cloud/opentelemetry-cloud-trace-exporter/-/opentelemetry-cloud-trace-exporter-0.10.0.tgz", - "integrity": "sha512-nbfFiWvxh0Ks/+QonczBNoE+w6aTpQ/+V54Z8KfOOvziQV9nCm7++4ILEejXF6W9w8I3vxaIF5XBxRRARF8vEQ==", - "dependencies": { - "@google-cloud/opentelemetry-resource-util": "^0.10.0", - "@grpc/grpc-js": "^1.1.8", - "@grpc/proto-loader": "^0.6.0", - "google-auth-library": "^7.0.0", - "google-proto-files": "^2.1.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.0.0", - "@opentelemetry/core": "^0.22.0", - "@opentelemetry/resources": "^0.22.0", - "@opentelemetry/tracing": "^0.22.0" - } - }, - "node_modules/@google-cloud/opentelemetry-cloud-trace-exporter/node_modules/@google-cloud/opentelemetry-resource-util": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@google-cloud/opentelemetry-resource-util/-/opentelemetry-resource-util-0.10.0.tgz", - "integrity": "sha512-6o0vqrQVAFw0TyM/Hf7AgVHh2S4LHJxIxL3ITkPYA/00WlDlnwL+gg327olgqaG4hcEo0oluMvFnMMFAdS5VGA==", - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@opentelemetry/resources": "^0.22.0", - "@opentelemetry/semantic-conventions": "^0.22.0" - } - }, - "node_modules/@google-cloud/opentelemetry-cloud-trace-exporter/node_modules/@opentelemetry/semantic-conventions": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-0.22.0.tgz", - "integrity": "sha512-t4fKikazahwNKmwD+CE/icHyuZldWvNMupJhjxdk9T/KxHFx3zCGjHT3MKavwYP6abzgAAm5WwzD1oHlmj7dyg==", - "peer": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@google-cloud/profiler": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@google-cloud/profiler/-/profiler-4.1.2.tgz", - "integrity": "sha512-h/UOb6vTm9ozKjdgA2OxV86Yk1GFS0Mq+29Eeo2rdovI5zK+139Yt+eYAgDQNBJxrAPmj4ZZKHb7G6gPIGJJeQ==", - "dependencies": { - "@google-cloud/common": "^3.0.0", - "@types/console-log-level": "^1.4.0", - "@types/semver": "^7.0.0", - "console-log-level": "^1.4.0", - "delay": "^5.0.0", - "extend": "^3.0.2", - "gcp-metadata": "^4.0.0", - "parse-duration": "^1.0.0", - "pprof": "3.1.0", - "pretty-ms": "^7.0.0", - "protobufjs": "~6.11.0", - "semver": "^7.0.0", - "teeny-request": "^7.0.0" - }, - "engines": { - "node": ">=10.4.1" - } - }, - "node_modules/@google-cloud/projectify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.1.0.tgz", - "integrity": "sha512-qbpidP/fOvQNz3nyabaVnZqcED1NNzf7qfeOlgtAZd9knTwY+KtsGRkYpiQzcATABy4gnGP2lousM3S0nuWVzA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/@google-cloud/promisify": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.3.tgz", - "integrity": "sha512-d4VSA86eL/AFTe5xtyZX+ePUjE8dIFu2T8zmdeNBSa5/kNgXPCx/o/wbFNHAGLJdGnk1vddRuMESD9HbOC8irw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/@grpc/grpc-js": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.4.tgz", - "integrity": "sha512-AxtZcm0mArQhY9z8T3TynCYVEaSKxNCa9mVhVwBCUnsuUEe8Zn94bPYYKVQSLt+hJJ1y0ukr3mUvtWfcATL/IQ==", - "dependencies": { - "@types/node": ">=12.12.47" - }, - "engines": { - "node": "^8.13.0 || >=10.10.0" - } - }, - "node_modules/@grpc/proto-loader": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.2.tgz", - "integrity": "sha512-q2Qle60Ht2OQBCp9S5hv1JbI4uBBq6/mqSevFNK3ZEgRDBCAkWqZPUhD/K9gXOHrHKluliHiVq2L9sw1mVyAIg==", - "dependencies": { - "@types/long": "^4.0.1", - "lodash.camelcase": "^4.3.0", - "long": "^4.0.0", - "protobufjs": "^6.10.0", - "yargs": "^16.1.1" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz", - "integrity": "sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA==", - "dependencies": { - "detect-libc": "^1.0.3", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.1", - "nopt": "^5.0.0", - "npmlog": "^4.1.2", - "rimraf": "^3.0.2", - "semver": "^7.3.4", - "tar": "^6.1.0" - }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" - } - }, - "node_modules/@opentelemetry/api": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.1.tgz", - "integrity": "sha512-H5Djcc2txGAINgf3TNaq4yFofYSIK3722PM89S/3R8FuI/eqi1UscajlXk7EBkG9s2pxss/q6SHlpturaavXaw==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@opentelemetry/api-metrics": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-metrics/-/api-metrics-0.23.0.tgz", - "integrity": "sha512-MGfH9aMnVktRTagYHvhksrk42vPDjTIz5N6Cxu31t6dgJa6iUYR6MemnOdphyLk73DUaqmR5s2Fn6jg0Xd9gqA==", - "engines": { - "node": ">=8.0.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.0.1" - } - }, - "node_modules/@opentelemetry/context-async-hooks": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-0.23.0.tgz", - "integrity": "sha512-aM+sSnNe5GL66KaHx4QJFVOvK817LE32bhc29BW9KlamieqxfDnSelPoNPra85FWlxzLXPGowU7sW5rexSRAtA==", - "engines": { - "node": ">=8.1.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.0.1" - } - }, - "node_modules/@opentelemetry/core": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-0.22.0.tgz", - "integrity": "sha512-x6JxuQ4rY2x39GEXJSqMgyf8XZPNNiZrGcCMhZSrtypq/WXlsJuxMNnUAl2hj2rpSGGukhhWn5cMpCmMJJz1hw==", - "dependencies": { - "@opentelemetry/semantic-conventions": "0.22.0", - "semver": "^7.1.3" - }, - "engines": { - "node": ">=8.5.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.0.0" - } - }, - "node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-0.22.0.tgz", - "integrity": "sha512-t4fKikazahwNKmwD+CE/icHyuZldWvNMupJhjxdk9T/KxHFx3zCGjHT3MKavwYP6abzgAAm5WwzD1oHlmj7dyg==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@opentelemetry/instrumentation": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.23.0.tgz", - "integrity": "sha512-1f6js0lIIPAWwR2EKPsUSowP2KloX+tv21QjWWp+BfFUcql+V6lh1RoNaxJWqFbe+BiZH7m+fD7UvJ2bWRQxdQ==", - "dependencies": { - "@opentelemetry/api-metrics": "0.23.0", - "require-in-the-middle": "^5.0.3", - "semver": "^7.3.2", - "shimmer": "^1.2.1" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.0.1" - } - }, - "node_modules/@opentelemetry/instrumentation-grpc": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-grpc/-/instrumentation-grpc-0.23.0.tgz", - "integrity": "sha512-6KQ44TNXq7WH7U3EKFYRHPQ8TvhtEogcgGVM+Nipa57aD9EDvFkhIDYKKeVwfclzrE3dZ5QndnO2vElo0T0oWw==", - "dependencies": { - "@opentelemetry/api-metrics": "0.23.0", - "@opentelemetry/instrumentation": "0.23.0", - "@opentelemetry/semantic-conventions": "0.23.0" - }, - "engines": { - "node": ">=8.0.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.0.1" - } - }, - "node_modules/@opentelemetry/node": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/node/-/node-0.23.0.tgz", - "integrity": "sha512-StG3UQmcm/D6ZCoiAvNcFN1K9pm4zIf+uzS7L2HToOh83iwjvBYuMDwMPNTSH8eKM+2+OYOVtud4bn9wF5aLGA==", - "dependencies": { - "@opentelemetry/context-async-hooks": "0.23.0", - "@opentelemetry/core": "0.23.0", - "@opentelemetry/propagator-b3": "0.23.0", - "@opentelemetry/propagator-jaeger": "0.23.0", - "@opentelemetry/tracing": "0.23.0", - "semver": "^7.1.3" - }, - "engines": { - "node": ">=8.0.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.0.1" - } - }, - "node_modules/@opentelemetry/node/node_modules/@opentelemetry/core": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-0.23.0.tgz", - "integrity": "sha512-7COVsnGEW96ITjc0waWYo/R27sFqjPUg4SCoP8XL48zAGr9zjzeuJoQe/xVchs7op//qOeeEEeBxiBvXy2QS0Q==", - "dependencies": { - "@opentelemetry/semantic-conventions": "0.23.0", - "semver": "^7.1.3" - }, - "engines": { - "node": ">=8.5.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.0.1" - } - }, - "node_modules/@opentelemetry/node/node_modules/@opentelemetry/resources": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-0.23.0.tgz", - "integrity": "sha512-sAiaoQ0pOwjaaKySuwCUlvej/W9M5d+SxpcuBFUBUojqRlEAYDbx1FHClPnKtOysIb9rXJDQvM3xlH++7NQQzg==", - "dependencies": { - "@opentelemetry/core": "0.23.0", - "@opentelemetry/semantic-conventions": "0.23.0" - }, - "engines": { - "node": ">=8.0.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.0.1" - } - }, - "node_modules/@opentelemetry/node/node_modules/@opentelemetry/tracing": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/tracing/-/tracing-0.23.0.tgz", - "integrity": "sha512-3vNLS55bE0CG1RBDz7+wAAKpLjbl8fhQKqM4MvTy/LYHSolgyM5BNutSb/TcA9LtWvkdI0djgFXxeRig1OFqoQ==", - "dependencies": { - "@opentelemetry/core": "0.23.0", - "@opentelemetry/resources": "0.23.0", - "@opentelemetry/semantic-conventions": "0.23.0", - "lodash.merge": "^4.6.2" - }, - "engines": { - "node": ">=8.0.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.0.1" - } - }, - "node_modules/@opentelemetry/propagator-b3": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-0.23.0.tgz", - "integrity": "sha512-bXojPjqncbhZtsX1tmIMB/dVLXI8ByoLLTBSHd5z6vJQA66LYtJX89xlIVZfiwuWIePqUnBJTmGEK95bDem6uw==", - "dependencies": { - "@opentelemetry/core": "0.23.0" - }, - "engines": { - "node": ">=8.0.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.0.1" - } - }, - "node_modules/@opentelemetry/propagator-b3/node_modules/@opentelemetry/core": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-0.23.0.tgz", - "integrity": "sha512-7COVsnGEW96ITjc0waWYo/R27sFqjPUg4SCoP8XL48zAGr9zjzeuJoQe/xVchs7op//qOeeEEeBxiBvXy2QS0Q==", - "dependencies": { - "@opentelemetry/semantic-conventions": "0.23.0", - "semver": "^7.1.3" - }, - "engines": { - "node": ">=8.5.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.0.1" - } - }, - "node_modules/@opentelemetry/propagator-jaeger": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-0.23.0.tgz", - "integrity": "sha512-N94k3dwnA4KeTUp2BE2ytADp4XYU4EWreo1tVwBVDpowjXY9WkVsDsZD6QA/PUvJJQZCzexSS5ERnHGoVRcOmQ==", - "dependencies": { - "@opentelemetry/core": "0.23.0" - }, - "engines": { - "node": ">=8.5.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.0.1" - } - }, - "node_modules/@opentelemetry/propagator-jaeger/node_modules/@opentelemetry/core": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-0.23.0.tgz", - "integrity": "sha512-7COVsnGEW96ITjc0waWYo/R27sFqjPUg4SCoP8XL48zAGr9zjzeuJoQe/xVchs7op//qOeeEEeBxiBvXy2QS0Q==", - "dependencies": { - "@opentelemetry/semantic-conventions": "0.23.0", - "semver": "^7.1.3" - }, - "engines": { - "node": ">=8.5.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.0.1" - } - }, - "node_modules/@opentelemetry/resources": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-0.22.0.tgz", - "integrity": "sha512-LiX6/JyuD2eHi7Ewrq/PUP79azDqshd0r2oksNTJ+VwgbGfMlq79ykd4FhiEEk23fFbajGt+9ginadXoRk17dg==", - "dependencies": { - "@opentelemetry/core": "0.22.0", - "@opentelemetry/semantic-conventions": "0.22.0" - }, - "engines": { - "node": ">=8.0.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.0.0" - } - }, - "node_modules/@opentelemetry/resources/node_modules/@opentelemetry/semantic-conventions": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-0.22.0.tgz", - "integrity": "sha512-t4fKikazahwNKmwD+CE/icHyuZldWvNMupJhjxdk9T/KxHFx3zCGjHT3MKavwYP6abzgAAm5WwzD1oHlmj7dyg==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@opentelemetry/semantic-conventions": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-0.23.0.tgz", - "integrity": "sha512-Tzo+VGR1zlzLbjVI+7mlDJ2xuaUsue4scWvFlK+fzcUfn9siF4NWbxoC2X6Br2B/g4dsq1OAwAYsPVYIEoY2rQ==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@opentelemetry/tracing": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/tracing/-/tracing-0.22.0.tgz", - "integrity": "sha512-EFrKTFndiEdh/KnzwDgo/EcphG/5z/NyLck8oiUUY+YMP7hskXNYHjTWSAv9UxtYe1MzgLbjmAateTuMmFIVNw==", - "dependencies": { - "@opentelemetry/core": "0.22.0", - "@opentelemetry/resources": "0.22.0", - "@opentelemetry/semantic-conventions": "0.22.0", - "lodash.merge": "^4.6.2" - }, - "engines": { - "node": ">=8.0.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.0.0" - } - }, - "node_modules/@opentelemetry/tracing/node_modules/@opentelemetry/semantic-conventions": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-0.22.0.tgz", - "integrity": "sha512-t4fKikazahwNKmwD+CE/icHyuZldWvNMupJhjxdk9T/KxHFx3zCGjHT3MKavwYP6abzgAAm5WwzD1oHlmj7dyg==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" - }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/@types/bytebuffer": { - "version": "5.0.42", - "resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.42.tgz", - "integrity": "sha512-lEgKojWUAc/MG2t649oZS5AfYFP2xRNPoDuwDBlBMjHXd8MaGPgFgtCXUK7inZdBOygmVf10qxc1Us8GXC96aw==", - "dependencies": { - "@types/long": "*", - "@types/node": "*" - } - }, - "node_modules/@types/console-log-level": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@types/console-log-level/-/console-log-level-1.4.1.tgz", - "integrity": "sha512-Dm5OaenEl6wj6qn6EgLyN6kcdRPgov6BJehbid57kyjZuZpow/bghppdiyqTvxXiDIpxnuN58ZowimKW3qEPmA==" - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", - "dev": true - }, - "node_modules/@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" - }, - "node_modules/@types/node": { - "version": "15.12.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.5.tgz", - "integrity": "sha512-se3yX7UHv5Bscf8f1ERKvQOD6sTyycH3hdaoozvaLxgUiY5lIGEeH37AD0G0Qi9kPqihPn0HOfd2yaIEN9VwEg==" - }, - "node_modules/@types/semver": { - "version": "7.3.6", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.6.tgz", - "integrity": "sha512-0caWDWmpCp0uifxFh+FaqK3CuZ2SkRR/ZRxAV5+zNdC3QVUi6wyOJnefhPvtNt8NQWXB5OA93BUvZsXpWat2Xw==" - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dependencies": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, - "node_modules/are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "node_modules/are-we-there-yet/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/are-we-there-yet/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/are-we-there-yet/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/array-includes": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", - "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.5" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", - "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", - "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ascli": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz", - "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=", - "dependencies": { - "colour": "~0.7.1", - "optjs": "~3.2.2" - } - }, - "node_modules/asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/async": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", - "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "node_modules/atomic-sleep": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", - "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", - "engines": { - "node": "*" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "node_modules/bytebuffer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", - "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", - "dependencies": { - "long": "~3" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/bytebuffer/node_modules/long": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", - "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/chalk/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/coffeescript": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.5.1.tgz", - "integrity": "sha512-J2jRPX0eeFh5VKyVnoLrfVFgLZtnnmp96WQSLAS8OrLm2wtQLcnikYKe1gViJKDH7vucjuhHvBKKBP3rKcD1tQ==", - "bin": { - "cake": "bin/cake", - "coffee": "bin/coffee" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/colour": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz", - "integrity": "sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g=", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" - }, - "node_modules/console-log-level": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/console-log-level/-/console-log-level-1.4.1.tgz", - "integrity": "sha512-VZzbIORbP+PPcN/gg3DXClTLPLg5Slwd5fL2MIc+o1qZ4BXBvWyc6QxPk6T/Mkr6IVjRpoAGf32XxP3ZWMVRcQ==" - }, - "node_modules/contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/debug-log": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/debug-log/-/debug-log-1.0.1.tgz", - "integrity": "sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "node_modules/define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "dependencies": { - "object-keys": "^1.0.12" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/deglob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/deglob/-/deglob-4.0.1.tgz", - "integrity": "sha512-/g+RDZ7yf2HvoW+E5Cy+K94YhgcFgr6C8LuHZD1O5HoNPkf3KY6RfXJ0DBGlB/NkLi5gml+G9zqRzk9S0mHZCg==", - "dev": true, - "dependencies": { - "find-root": "^1.0.0", - "glob": "^7.0.5", - "ignore": "^5.0.0", - "pkg-config": "^1.1.0", - "run-parallel": "^1.1.2", - "uniq": "^1.0.1" - } - }, - "node_modules/deglob/node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/delay": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", - "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" - }, - "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/duplexify": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", - "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", - "dependencies": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=" - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-abstract": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", - "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.3", - "is-string": "^1.0.6", - "object-inspect": "^1.10.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/eslint": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.12.1.tgz", - "integrity": "sha512-HlMTEdr/LicJfN08LB3nM1rRYliDXOmfoO4vj39xN6BLpFzF00hbwBoqHk8UcJ2M/3nlARZWy/mslvGEuZFvsg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "@eslint/eslintrc": "^0.2.1", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.0", - "esquery": "^1.2.0", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash": "^4.17.19", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/eslint-config-semistandard": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/eslint-config-semistandard/-/eslint-config-semistandard-15.0.1.tgz", - "integrity": "sha512-sfV+qNBWKOmF0kZJll1VH5XqOAdTmLlhbOl9WKI11d2eMEe+Kicxnpm24PQWHOqAfk5pAWU2An0LjNCXKa4Usg==", - "dev": true - }, - "node_modules/eslint-config-standard": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-15.0.1.tgz", - "integrity": "sha512-UGorkix49kBium7Y124o2U9Qy7Lpa+nO0FsaqQSIPeno5hGNxZtSBJbqJX6gtpYfDFWCtqCAN9wyK+oDd9jT7Q==", - "dev": true - }, - "node_modules/eslint-config-standard-jsx": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-9.0.0.tgz", - "integrity": "sha512-e9ezaClB5YdTYqGUd3wReKC1si8XRn234tmME+3qebQ+KHtH92B6dr4LE6qPjK9AYe9XfwDK/xgQSwyCKQwv5Q==", - "dev": true - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", - "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", - "dev": true, - "dependencies": { - "debug": "^2.6.9", - "resolve": "^1.13.1" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/eslint-module-utils": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz", - "integrity": "sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "pkg-dir": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", - "dev": true, - "dependencies": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.22.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", - "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.1", - "array.prototype.flat": "^1.2.3", - "contains-path": "^0.1.0", - "debug": "^2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.4", - "eslint-module-utils": "^2.6.0", - "has": "^1.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.1", - "read-pkg-up": "^2.0.0", - "resolve": "^1.17.0", - "tsconfig-paths": "^3.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "dependencies": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", - "dev": true, - "dependencies": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/eslint-plugin-node/node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/eslint-plugin-node/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-promise": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz", - "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-plugin-react": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.21.5.tgz", - "integrity": "sha512-8MaEggC2et0wSF6bUeywF7qQ46ER81irOdWS4QWxnnlAEsnzeBevk1sWh7fhpCghPpXb+8Ks7hvaft6L/xsR6g==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.1", - "array.prototype.flatmap": "^1.2.3", - "doctrine": "^2.1.0", - "has": "^1.0.3", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "object.entries": "^1.1.2", - "object.fromentries": "^2.0.2", - "object.values": "^1.1.1", - "prop-types": "^15.7.2", - "resolve": "^1.18.1", - "string.prototype.matchall": "^4.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-plugin-react/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-standard": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.2.tgz", - "integrity": "sha512-nKptN8l7jksXkwFk++PhJB3cCDTcXOEyhISIN86Ue2feJ1LFyY3PrY3/xT2keXlJSY5bpmbiTG0f885/YKAvTA==", - "dev": true - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "node_modules/eslint/node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/eslint/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/eslint/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/espree/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "node_modules/fast-redact": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-2.1.0.tgz", - "integrity": "sha512-0LkHpTLyadJavq9sRzzyqIoMZemWli77K2/MGOkafrR64B9ItrvZ9aT+jluvNDsv0YEHjSNhlMBtbokuoqii4A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/fast-safe-stringify": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", - "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" - }, - "node_modules/fast-text-encoding": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", - "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==" - }, - "node_modules/file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, - "dependencies": { - "flat-cache": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "node_modules/find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "dev": true - }, - "node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/findit2": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz", - "integrity": "sha1-WKRmaX34piBc39vzlVNri9d3pfY=", - "engines": { - "node": ">=0.8.22" - } - }, - "node_modules/flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "dependencies": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/flatstr": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/flatstr/-/flatstr-1.0.12.tgz", - "integrity": "sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw==" - }, - "node_modules/flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "node_modules/gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dependencies": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "node_modules/gaxios": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.0.tgz", - "integrity": "sha512-pHplNbslpwCLMyII/lHPWFQbJWOX0B3R1hwBEOvzYi1GmdKZruuEHK4N9V6f7tf1EaPYyF80mui1+344p6SmLg==", - "dependencies": { - "abort-controller": "^3.0.0", - "extend": "^3.0.2", - "https-proxy-agent": "^5.0.0", - "is-stream": "^2.0.0", - "node-fetch": "^2.3.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/gcp-metadata": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.3.0.tgz", - "integrity": "sha512-L9XQUpvKJCM76YRSmcxrR4mFPzPGsgZUH+GgHMxAET8qc6+BhRJq63RLhWakgEO2KKVgeSDVfyiNjkGSADwNTA==", - "dependencies": { - "gaxios": "^4.0.0", - "json-bigint": "^1.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "node_modules/get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "dev": true, - "dependencies": { - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/google-auth-library": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.1.2.tgz", - "integrity": "sha512-FMipHgfe2u1LzWsf2n9zEB9KsJ8M3n8OYTHbHtlkzPCyo7IknXQR5X99nfvwUHGuX+iEpihUZxDuPm7+qBYeXg==", - "dependencies": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/google-p12-pem": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.0.tgz", - "integrity": "sha512-JUtEHXL4DY/N+xhlm7TC3qL797RPAtk0ZGXNs3/gWyiDHYoA/8Rjes0pztkda+sZv4ej1EoO2KhWgW5V9KTrSQ==", - "dependencies": { - "node-forge": "^0.10.0" - }, - "bin": { - "gp12-pem": "build/src/bin/gp12-pem.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/google-proto-files": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/google-proto-files/-/google-proto-files-2.4.0.tgz", - "integrity": "sha512-M5u56EsADOnplBUHTBzqBcCtPNPoGtBBXefjtA7mt3KDsOnlRM75fwrW2rsPS3Am2vrf9I0/NlI0E3nKWo/Ipg==", - "dependencies": { - "protobufjs": "^6.8.0", - "walkdir": "^0.4.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/google-protobuf": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.13.0.tgz", - "integrity": "sha512-ZIf3qfLFayVrPvAjeKKxO5FRF1/NwRxt6Dko+fWEMuHwHbZx8/fcaAao9b0wCM6kr8qeg2te8XTpyuvKuD9aKw==" - }, - "node_modules/graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", - "dev": true - }, - "node_modules/grpc": { - "version": "1.24.10", - "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.24.10.tgz", - "integrity": "sha512-mTR+P5IL3WO3oCgNwxKFE5ksXEJfCYP+dk0aIbjB494f7OnHTmssU5r9vznsSq3+cdLcxAzGFskOj5CaPwi8KA==", - "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.4", - "@types/bytebuffer": "^5.0.40", - "lodash.camelcase": "^4.3.0", - "lodash.clone": "^4.5.0", - "nan": "^2.13.2", - "protobufjs": "^5.0.3" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/grpc/node_modules/cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "node_modules/grpc/node_modules/protobufjs": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.3.tgz", - "integrity": "sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==", - "dependencies": { - "ascli": "~1", - "bytebuffer": "~5", - "glob": "^7.0.5", - "yargs": "^3.10.0" - }, - "bin": { - "pbjs": "bin/pbjs" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/grpc/node_modules/wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/grpc/node_modules/y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==" - }, - "node_modules/grpc/node_modules/yargs": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", - "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", - "dependencies": { - "camelcase": "^2.0.1", - "cliui": "^3.0.3", - "decamelize": "^1.1.1", - "os-locale": "^1.4.0", - "string-width": "^1.0.1", - "window-size": "^0.1.4", - "y18n": "^3.2.0" - } - }, - "node_modules/gtoken": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.3.0.tgz", - "integrity": "sha512-mCcISYiaRZrJpfqOs0QWa6lfEM/C1V9ASkzFmuz43XBb5s1Vynh+CZy1ECeeJXVGx2PRByjYzb4Y4/zr1byr0w==", - "dependencies": { - "gaxios": "^4.0.0", - "google-p12-pem": "^3.0.3", - "jws": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/har-validator/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "node_modules/har-validator/node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/har-validator/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" - }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "node_modules/is-bigint": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", - "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", - "dev": true - }, - "node_modules/is-boolean-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", - "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-core-module": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", - "dependencies": { - "has": "^1.0.3" - } - }, - "node_modules/is-date-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", - "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-number-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", - "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-regex": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", - "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-string": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", - "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "node_modules/json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "dependencies": { - "bignumber.js": "^9.0.0" - } - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "node_modules/json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "node_modules/json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "node_modules/jsx-ast-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", - "integrity": "sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.2", - "object.assign": "^4.1.2" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "dependencies": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dependencies": { - "invert-kv": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/left-pad": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", - "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==" - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/load-json-file/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" - }, - "node_modules/lodash.clone": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", - "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" - }, - "node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/mime-db": { - "version": "1.48.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", - "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.31", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", - "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", - "dependencies": { - "mime-db": "1.48.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "node_modules/minipass": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/module-details-from-path": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=" - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/nan": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node_modules/node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "engines": { - "node": "4.x || >=6.0.0" - } - }, - "node_modules/node-forge": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", - "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dependencies": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "engines": { - "node": "*" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", - "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", - "dev": true - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.entries": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.4.tgz", - "integrity": "sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz", - "integrity": "sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "has": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.values": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", - "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/optjs": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", - "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=" - }, - "node_modules/os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dependencies": { - "lcid": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-locate/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-duration": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-1.0.0.tgz", - "integrity": "sha512-X4kUkCTHU1N/kEbwK9FpUJ0UZQa90VzeczfS704frR30gljxDG0pSziws06XlK+CGRSo/1wtG1mFIdBFQTMQNw==" - }, - "node_modules/parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "dependencies": { - "error-ex": "^1.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/parse-ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", - "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "node_modules/path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "dependencies": { - "pify": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/path-type/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "node_modules/pify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", - "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/pino": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/pino/-/pino-5.17.0.tgz", - "integrity": "sha512-LqrqmRcJz8etUjyV0ddqB6OTUutCgQULPFg2b4dtijRHUsucaAdBgSUW58vY6RFSX+NT8963F+q0tM6lNwGShA==", - "dependencies": { - "fast-redact": "^2.0.0", - "fast-safe-stringify": "^2.0.7", - "flatstr": "^1.0.12", - "pino-std-serializers": "^2.4.2", - "quick-format-unescaped": "^3.0.3", - "sonic-boom": "^0.7.5" - }, - "bin": { - "pino": "bin.js" - } - }, - "node_modules/pino-std-serializers": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-2.5.0.tgz", - "integrity": "sha512-wXqbqSrIhE58TdrxxlfLwU9eDhrzppQDvGhBEr1gYbzzM4KKo3Y63gSjiDXRKLVS2UOXdPNR2v+KnQgNrs+xUg==" - }, - "node_modules/pkg-conf": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz", - "integrity": "sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ==", - "dev": true, - "dependencies": { - "find-up": "^3.0.0", - "load-json-file": "^5.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-conf/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-conf/node_modules/load-json-file": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", - "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.15", - "parse-json": "^4.0.0", - "pify": "^4.0.1", - "strip-bom": "^3.0.0", - "type-fest": "^0.3.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-conf/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-conf/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-conf/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-conf/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-conf/node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-conf/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-conf/node_modules/type-fest": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", - "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-config": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pkg-config/-/pkg-config-1.1.1.tgz", - "integrity": "sha1-VX7yLXPaPIg3EHdmxS6tq94pj+Q=", - "dev": true, - "dependencies": { - "debug-log": "^1.0.0", - "find-root": "^1.0.0", - "xtend": "^4.0.1" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "dependencies": { - "find-up": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pprof": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pprof/-/pprof-3.1.0.tgz", - "integrity": "sha512-nbYfVzZYQ/TPV9QZFPMb59FRZrIe4M4FTruH11+vd4gR5cGUG3dfoXpXdfki50eeVeqWQrXuWdUsrRIZi2SteQ==", - "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.0", - "bindings": "^1.2.1", - "delay": "^5.0.0", - "findit2": "^2.2.3", - "nan": "^2.14.0", - "p-limit": "^3.0.0", - "pify": "^5.0.0", - "protobufjs": "~6.10.0", - "source-map": "^0.7.3", - "split": "^1.0.1" - }, - "engines": { - "node": ">=10.4.1" - } - }, - "node_modules/pprof/node_modules/@types/node": { - "version": "13.13.52", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", - "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==" - }, - "node_modules/pprof/node_modules/protobufjs": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz", - "integrity": "sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==", - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": "^13.7.0", - "long": "^4.0.0" - }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" - } - }, - "node_modules/pprof/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/pretty-ms": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", - "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", - "dependencies": { - "parse-ms": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "dev": true, - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, - "node_modules/protobufjs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", - "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" - } - }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "node_modules/quick-format-unescaped": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-3.0.3.tgz", - "integrity": "sha512-dy1yjycmn9blucmJLXOfZDx1ikZJUi6E8bBZLnhPG5gBrVhHXx2xVyqqgKBubVNEXmx51dBACMHpoMQK/N/AXQ==" - }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - }, - "node_modules/read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "dependencies": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "dependencies": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", - "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-in-the-middle": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.1.0.tgz", - "integrity": "sha512-M2rLKVupQfJ5lf9OvqFGIT+9iVLnTmjgbOmpil12hiSQNn5zJTKGPoIisETNjfK+09vP3rpm1zJajmErpr2sEQ==", - "dependencies": { - "debug": "^4.1.1", - "module-details-from-path": "^1.0.3", - "resolve": "^1.12.0" - } - }, - "node_modules/resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dependencies": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/retry-request": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.2.0.tgz", - "integrity": "sha512-rIwHm2pipUX7MFTpscNr9CNfOsW3gzcosqUOvS7MbuURgdDeIzNVjA/sNgs4BTt0g3L748hB7Q/Yt6StRFHD4w==", - "dependencies": { - "debug": "^4.1.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "node_modules/semistandard": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/semistandard/-/semistandard-15.0.0.tgz", - "integrity": "sha512-qWMJubk+WeTHXtdoe4Kh81SqwcVPwOsJcDFu1QbXqO3vh60PwEJ1VrlhaHXNwP3fjfGdFPJBYXlA8x4QRNIbdw==", - "dev": true, - "dependencies": { - "eslint": "~7.12.1", - "eslint-config-semistandard": "15.0.1", - "eslint-config-standard": "15.0.1", - "eslint-config-standard-jsx": "9.0.0", - "eslint-plugin-import": "~2.22.1", - "eslint-plugin-node": "~11.1.0", - "eslint-plugin-promise": "~4.2.1", - "eslint-plugin-react": "~7.21.5", - "eslint-plugin-standard": "~4.0.2", - "standard-engine": "^13.0.0" - }, - "bin": { - "semistandard": "bin/cmd.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "node_modules/signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" - }, - "node_modules/slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/slice-ansi/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/slice-ansi/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/sonic-boom": { - "version": "0.7.7", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-0.7.7.tgz", - "integrity": "sha512-Ei5YOo5J64GKClHIL/5evJPgASXFVpfVYbJV9PILZQytTK6/LCwHvsZJW2Ig4p9FMC2OrBrMnXKgRN/OEoAWfg==", - "dependencies": { - "atomic-sleep": "^1.0.0", - "flatstr": "^1.0.12" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", - "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", - "dev": true - }, - "node_modules/split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "dependencies": { - "through": "2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "node_modules/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/standard-engine": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-13.0.0.tgz", - "integrity": "sha512-fQ8/0SQ84hRtxru3tsyhc8JDBDrUFzJc/lOxh5Of/wCEpMZ0J0j7XX5kymtgdZZEke0Lb1HxzvSYdnjmg05ewA==", - "dev": true, - "dependencies": { - "deglob": "^4.0.1", - "get-stdin": "^8.0.0", - "minimist": "^1.2.5", - "pkg-conf": "^3.1.0", - "xdg-basedir": "^4.0.0" - }, - "engines": { - "node": ">=8.10" - } - }, - "node_modules/stream-events": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", - "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", - "dependencies": { - "stubs": "^3.0.0" - } - }, - "node_modules/stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string.prototype.matchall": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz", - "integrity": "sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.2", - "get-intrinsic": "^1.1.1", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.3.1", - "side-channel": "^1.0.4" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/stubs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=" - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "dependencies": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "node_modules/table/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/table/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/table/node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/table/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/table/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/table/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tar": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", - "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/teeny-request": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.1.0.tgz", - "integrity": "sha512-hPfSc05a7Mf3syqVhSkrVMb844sMiP60MrfGMts3ft6V6UlSkEIGQzgwf0dy1KjdE3FV2lJ5s7QCBFcaoQLA6g==", - "dependencies": { - "http-proxy-agent": "^4.0.0", - "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.6.1", - "stream-events": "^1.0.5", - "uuid": "^8.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/tsconfig-paths": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", - "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "node_modules/uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", - "dev": true - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/walkdir": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", - "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, - "node_modules/window-size": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=", - "bin": { - "window-size": "cli.js" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "node_modules/write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "dependencies": { - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/write/node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "engines": { - "node": ">=10" - } - } - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.14.5" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", - "dev": true - }, - "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - } - } - }, - "@eslint/eslintrc": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz", - "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "lodash": "^4.17.19", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - } - } - }, - "@google-cloud/common": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.6.0.tgz", - "integrity": "sha512-aHIFTqJZmeTNO9md8XxV+ywuvXF3xBm5WNmgWeeCK+XN5X+kGW0WEX94wGwj+/MdOnrVf4dL2RvSIt9J5yJG6Q==", - "requires": { - "@google-cloud/projectify": "^2.0.0", - "@google-cloud/promisify": "^2.0.0", - "arrify": "^2.0.1", - "duplexify": "^4.1.1", - "ent": "^2.2.0", - "extend": "^3.0.2", - "google-auth-library": "^7.0.2", - "retry-request": "^4.1.1", - "teeny-request": "^7.0.0" - } - }, - "@google-cloud/debug-agent": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/@google-cloud/debug-agent/-/debug-agent-5.1.3.tgz", - "integrity": "sha512-WbzeEz4MvPlM7DX2QBsPcWgF62u7LSQv/oMYPl0L+TddTebqjDKiVXwxpzWk61NIfcKiet3dyCbPIt3N5o8XPQ==", - "requires": { - "@google-cloud/common": "^3.0.0", - "acorn": "^8.0.0", - "coffeescript": "^2.0.0", - "console-log-level": "^1.4.0", - "extend": "^3.0.2", - "findit2": "^2.2.3", - "gcp-metadata": "^4.0.0", - "p-limit": "^3.0.1", - "semver": "^7.0.0", - "source-map": "^0.6.1", - "split": "^1.0.0" - } - }, - "@google-cloud/opentelemetry-cloud-trace-exporter": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@google-cloud/opentelemetry-cloud-trace-exporter/-/opentelemetry-cloud-trace-exporter-0.10.0.tgz", - "integrity": "sha512-nbfFiWvxh0Ks/+QonczBNoE+w6aTpQ/+V54Z8KfOOvziQV9nCm7++4ILEejXF6W9w8I3vxaIF5XBxRRARF8vEQ==", - "requires": { - "@google-cloud/opentelemetry-resource-util": "^0.10.0", - "@grpc/grpc-js": "^1.1.8", - "@grpc/proto-loader": "^0.6.0", - "google-auth-library": "^7.0.0", - "google-proto-files": "^2.1.0" - }, - "dependencies": { - "@google-cloud/opentelemetry-resource-util": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@google-cloud/opentelemetry-resource-util/-/opentelemetry-resource-util-0.10.0.tgz", - "integrity": "sha512-6o0vqrQVAFw0TyM/Hf7AgVHh2S4LHJxIxL3ITkPYA/00WlDlnwL+gg327olgqaG4hcEo0oluMvFnMMFAdS5VGA==", - "requires": {} - }, - "@opentelemetry/semantic-conventions": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-0.22.0.tgz", - "integrity": "sha512-t4fKikazahwNKmwD+CE/icHyuZldWvNMupJhjxdk9T/KxHFx3zCGjHT3MKavwYP6abzgAAm5WwzD1oHlmj7dyg==", - "peer": true - } - } - }, - "@google-cloud/profiler": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@google-cloud/profiler/-/profiler-4.1.2.tgz", - "integrity": "sha512-h/UOb6vTm9ozKjdgA2OxV86Yk1GFS0Mq+29Eeo2rdovI5zK+139Yt+eYAgDQNBJxrAPmj4ZZKHb7G6gPIGJJeQ==", - "requires": { - "@google-cloud/common": "^3.0.0", - "@types/console-log-level": "^1.4.0", - "@types/semver": "^7.0.0", - "console-log-level": "^1.4.0", - "delay": "^5.0.0", - "extend": "^3.0.2", - "gcp-metadata": "^4.0.0", - "parse-duration": "^1.0.0", - "pprof": "3.1.0", - "pretty-ms": "^7.0.0", - "protobufjs": "~6.11.0", - "semver": "^7.0.0", - "teeny-request": "^7.0.0" - } - }, - "@google-cloud/projectify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.1.0.tgz", - "integrity": "sha512-qbpidP/fOvQNz3nyabaVnZqcED1NNzf7qfeOlgtAZd9knTwY+KtsGRkYpiQzcATABy4gnGP2lousM3S0nuWVzA==" - }, - "@google-cloud/promisify": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.3.tgz", - "integrity": "sha512-d4VSA86eL/AFTe5xtyZX+ePUjE8dIFu2T8zmdeNBSa5/kNgXPCx/o/wbFNHAGLJdGnk1vddRuMESD9HbOC8irw==" - }, - "@grpc/grpc-js": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.4.tgz", - "integrity": "sha512-AxtZcm0mArQhY9z8T3TynCYVEaSKxNCa9mVhVwBCUnsuUEe8Zn94bPYYKVQSLt+hJJ1y0ukr3mUvtWfcATL/IQ==", - "requires": { - "@types/node": ">=12.12.47" - } - }, - "@grpc/proto-loader": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.2.tgz", - "integrity": "sha512-q2Qle60Ht2OQBCp9S5hv1JbI4uBBq6/mqSevFNK3ZEgRDBCAkWqZPUhD/K9gXOHrHKluliHiVq2L9sw1mVyAIg==", - "requires": { - "@types/long": "^4.0.1", - "lodash.camelcase": "^4.3.0", - "long": "^4.0.0", - "protobufjs": "^6.10.0", - "yargs": "^16.1.1" - } - }, - "@mapbox/node-pre-gyp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz", - "integrity": "sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA==", - "requires": { - "detect-libc": "^1.0.3", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.1", - "nopt": "^5.0.0", - "npmlog": "^4.1.2", - "rimraf": "^3.0.2", - "semver": "^7.3.4", - "tar": "^6.1.0" - } - }, - "@opentelemetry/api": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.1.tgz", - "integrity": "sha512-H5Djcc2txGAINgf3TNaq4yFofYSIK3722PM89S/3R8FuI/eqi1UscajlXk7EBkG9s2pxss/q6SHlpturaavXaw==" - }, - "@opentelemetry/api-metrics": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-metrics/-/api-metrics-0.23.0.tgz", - "integrity": "sha512-MGfH9aMnVktRTagYHvhksrk42vPDjTIz5N6Cxu31t6dgJa6iUYR6MemnOdphyLk73DUaqmR5s2Fn6jg0Xd9gqA==", - "requires": {} - }, - "@opentelemetry/context-async-hooks": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-0.23.0.tgz", - "integrity": "sha512-aM+sSnNe5GL66KaHx4QJFVOvK817LE32bhc29BW9KlamieqxfDnSelPoNPra85FWlxzLXPGowU7sW5rexSRAtA==", - "requires": {} - }, - "@opentelemetry/core": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-0.22.0.tgz", - "integrity": "sha512-x6JxuQ4rY2x39GEXJSqMgyf8XZPNNiZrGcCMhZSrtypq/WXlsJuxMNnUAl2hj2rpSGGukhhWn5cMpCmMJJz1hw==", - "requires": { - "@opentelemetry/semantic-conventions": "0.22.0", - "semver": "^7.1.3" - }, - "dependencies": { - "@opentelemetry/semantic-conventions": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-0.22.0.tgz", - "integrity": "sha512-t4fKikazahwNKmwD+CE/icHyuZldWvNMupJhjxdk9T/KxHFx3zCGjHT3MKavwYP6abzgAAm5WwzD1oHlmj7dyg==" - } - } - }, - "@opentelemetry/instrumentation": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.23.0.tgz", - "integrity": "sha512-1f6js0lIIPAWwR2EKPsUSowP2KloX+tv21QjWWp+BfFUcql+V6lh1RoNaxJWqFbe+BiZH7m+fD7UvJ2bWRQxdQ==", - "requires": { - "@opentelemetry/api-metrics": "0.23.0", - "require-in-the-middle": "^5.0.3", - "semver": "^7.3.2", - "shimmer": "^1.2.1" - } - }, - "@opentelemetry/instrumentation-grpc": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-grpc/-/instrumentation-grpc-0.23.0.tgz", - "integrity": "sha512-6KQ44TNXq7WH7U3EKFYRHPQ8TvhtEogcgGVM+Nipa57aD9EDvFkhIDYKKeVwfclzrE3dZ5QndnO2vElo0T0oWw==", - "requires": { - "@opentelemetry/api-metrics": "0.23.0", - "@opentelemetry/instrumentation": "0.23.0", - "@opentelemetry/semantic-conventions": "0.23.0" - } - }, - "@opentelemetry/node": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/node/-/node-0.23.0.tgz", - "integrity": "sha512-StG3UQmcm/D6ZCoiAvNcFN1K9pm4zIf+uzS7L2HToOh83iwjvBYuMDwMPNTSH8eKM+2+OYOVtud4bn9wF5aLGA==", - "requires": { - "@opentelemetry/context-async-hooks": "0.23.0", - "@opentelemetry/core": "0.23.0", - "@opentelemetry/propagator-b3": "0.23.0", - "@opentelemetry/propagator-jaeger": "0.23.0", - "@opentelemetry/tracing": "0.23.0", - "semver": "^7.1.3" - }, - "dependencies": { - "@opentelemetry/core": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-0.23.0.tgz", - "integrity": "sha512-7COVsnGEW96ITjc0waWYo/R27sFqjPUg4SCoP8XL48zAGr9zjzeuJoQe/xVchs7op//qOeeEEeBxiBvXy2QS0Q==", - "requires": { - "@opentelemetry/semantic-conventions": "0.23.0", - "semver": "^7.1.3" - } - }, - "@opentelemetry/resources": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-0.23.0.tgz", - "integrity": "sha512-sAiaoQ0pOwjaaKySuwCUlvej/W9M5d+SxpcuBFUBUojqRlEAYDbx1FHClPnKtOysIb9rXJDQvM3xlH++7NQQzg==", - "requires": { - "@opentelemetry/core": "0.23.0", - "@opentelemetry/semantic-conventions": "0.23.0" - } - }, - "@opentelemetry/tracing": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/tracing/-/tracing-0.23.0.tgz", - "integrity": "sha512-3vNLS55bE0CG1RBDz7+wAAKpLjbl8fhQKqM4MvTy/LYHSolgyM5BNutSb/TcA9LtWvkdI0djgFXxeRig1OFqoQ==", - "requires": { - "@opentelemetry/core": "0.23.0", - "@opentelemetry/resources": "0.23.0", - "@opentelemetry/semantic-conventions": "0.23.0", - "lodash.merge": "^4.6.2" - } - } - } - }, - "@opentelemetry/propagator-b3": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-0.23.0.tgz", - "integrity": "sha512-bXojPjqncbhZtsX1tmIMB/dVLXI8ByoLLTBSHd5z6vJQA66LYtJX89xlIVZfiwuWIePqUnBJTmGEK95bDem6uw==", - "requires": { - "@opentelemetry/core": "0.23.0" - }, - "dependencies": { - "@opentelemetry/core": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-0.23.0.tgz", - "integrity": "sha512-7COVsnGEW96ITjc0waWYo/R27sFqjPUg4SCoP8XL48zAGr9zjzeuJoQe/xVchs7op//qOeeEEeBxiBvXy2QS0Q==", - "requires": { - "@opentelemetry/semantic-conventions": "0.23.0", - "semver": "^7.1.3" - } - } - } - }, - "@opentelemetry/propagator-jaeger": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-0.23.0.tgz", - "integrity": "sha512-N94k3dwnA4KeTUp2BE2ytADp4XYU4EWreo1tVwBVDpowjXY9WkVsDsZD6QA/PUvJJQZCzexSS5ERnHGoVRcOmQ==", - "requires": { - "@opentelemetry/core": "0.23.0" - }, - "dependencies": { - "@opentelemetry/core": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-0.23.0.tgz", - "integrity": "sha512-7COVsnGEW96ITjc0waWYo/R27sFqjPUg4SCoP8XL48zAGr9zjzeuJoQe/xVchs7op//qOeeEEeBxiBvXy2QS0Q==", - "requires": { - "@opentelemetry/semantic-conventions": "0.23.0", - "semver": "^7.1.3" - } - } - } - }, - "@opentelemetry/resources": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-0.22.0.tgz", - "integrity": "sha512-LiX6/JyuD2eHi7Ewrq/PUP79azDqshd0r2oksNTJ+VwgbGfMlq79ykd4FhiEEk23fFbajGt+9ginadXoRk17dg==", - "requires": { - "@opentelemetry/core": "0.22.0", - "@opentelemetry/semantic-conventions": "0.22.0" - }, - "dependencies": { - "@opentelemetry/semantic-conventions": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-0.22.0.tgz", - "integrity": "sha512-t4fKikazahwNKmwD+CE/icHyuZldWvNMupJhjxdk9T/KxHFx3zCGjHT3MKavwYP6abzgAAm5WwzD1oHlmj7dyg==" - } - } - }, - "@opentelemetry/semantic-conventions": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-0.23.0.tgz", - "integrity": "sha512-Tzo+VGR1zlzLbjVI+7mlDJ2xuaUsue4scWvFlK+fzcUfn9siF4NWbxoC2X6Br2B/g4dsq1OAwAYsPVYIEoY2rQ==" - }, - "@opentelemetry/tracing": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/tracing/-/tracing-0.22.0.tgz", - "integrity": "sha512-EFrKTFndiEdh/KnzwDgo/EcphG/5z/NyLck8oiUUY+YMP7hskXNYHjTWSAv9UxtYe1MzgLbjmAateTuMmFIVNw==", - "requires": { - "@opentelemetry/core": "0.22.0", - "@opentelemetry/resources": "0.22.0", - "@opentelemetry/semantic-conventions": "0.22.0", - "lodash.merge": "^4.6.2" - }, - "dependencies": { - "@opentelemetry/semantic-conventions": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-0.22.0.tgz", - "integrity": "sha512-t4fKikazahwNKmwD+CE/icHyuZldWvNMupJhjxdk9T/KxHFx3zCGjHT3MKavwYP6abzgAAm5WwzD1oHlmj7dyg==" - } - } - }, - "@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" - }, - "@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" - }, - "@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", - "requires": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" - }, - "@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" - }, - "@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" - }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" - }, - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" - }, - "@types/bytebuffer": { - "version": "5.0.42", - "resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.42.tgz", - "integrity": "sha512-lEgKojWUAc/MG2t649oZS5AfYFP2xRNPoDuwDBlBMjHXd8MaGPgFgtCXUK7inZdBOygmVf10qxc1Us8GXC96aw==", - "requires": { - "@types/long": "*", - "@types/node": "*" - } - }, - "@types/console-log-level": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@types/console-log-level/-/console-log-level-1.4.2.tgz", - "integrity": "sha512-TnhDAntcJthcCMrR3OAKAUjgHyQgoms1yaBJepGv+BtXi8PLf8aX2L/NMCfofRTpVqW0bLklpGTsuqmUSCR2Uw==" - }, - "@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" - }, - "@types/node": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.0.1.tgz", - "integrity": "sha512-hBOx4SUlEPKwRi6PrXuTGw1z6lz0fjsibcWCM378YxsSu/6+C30L6CR49zIBKHiwNWCYIcOLjg4OHKZaFeLAug==" - }, - "@types/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-4g1jrL98mdOIwSOUh6LTlB0Cs9I0dQPwINUhBg7C6pN4HLr8GS8xsksJxilW6S6dQHVi2K/o+lQuQcg7LroCnw==" - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==" - }, - "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "requires": { - "debug": "4" - } - }, - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-includes": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", - "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.5" - } - }, - "array.prototype.flat": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", - "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - } - }, - "array.prototype.flatmap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", - "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "function-bind": "^1.1.1" - } - }, - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==" - }, - "ascli": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz", - "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=", - "requires": { - "colour": "~0.7.1", - "optjs": "~3.2.2" - } - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true - }, - "async": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", - "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "atomic-sleep": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", - "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==" - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "bytebuffer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", - "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", - "requires": { - "long": "~3" - }, - "dependencies": { - "long": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", - "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=" - } - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, - "coffeescript": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.5.1.tgz", - "integrity": "sha512-J2jRPX0eeFh5VKyVnoLrfVFgLZtnnmp96WQSLAS8OrLm2wtQLcnikYKe1gViJKDH7vucjuhHvBKKBP3rKcD1tQ==" - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "colour": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz", - "integrity": "sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g=" - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" - }, - "console-log-level": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/console-log-level/-/console-log-level-1.4.1.tgz", - "integrity": "sha512-VZzbIORbP+PPcN/gg3DXClTLPLg5Slwd5fL2MIc+o1qZ4BXBvWyc6QxPk6T/Mkr6IVjRpoAGf32XxP3ZWMVRcQ==" - }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "requires": { - "ms": "2.1.2" - } - }, - "debug-log": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/debug-log/-/debug-log-1.0.1.tgz", - "integrity": "sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8=", - "dev": true - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "deglob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/deglob/-/deglob-4.0.1.tgz", - "integrity": "sha512-/g+RDZ7yf2HvoW+E5Cy+K94YhgcFgr6C8LuHZD1O5HoNPkf3KY6RfXJ0DBGlB/NkLi5gml+G9zqRzk9S0mHZCg==", - "dev": true, - "requires": { - "find-root": "^1.0.0", - "glob": "^7.0.5", - "ignore": "^5.0.0", - "pkg-config": "^1.1.0", - "run-parallel": "^1.1.2", - "uniq": "^1.0.1" - }, - "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - } - } - }, - "delay": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", - "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==" - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "duplexify": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", - "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", - "requires": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "requires": { - "once": "^1.4.0" - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=" - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", - "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.3", - "is-string": "^1.0.6", - "object-inspect": "^1.10.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.12.1.tgz", - "integrity": "sha512-HlMTEdr/LicJfN08LB3nM1rRYliDXOmfoO4vj39xN6BLpFzF00hbwBoqHk8UcJ2M/3nlARZWy/mslvGEuZFvsg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@eslint/eslintrc": "^0.2.1", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.0", - "esquery": "^1.2.0", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash": "^4.17.19", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, - "eslint-config-semistandard": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/eslint-config-semistandard/-/eslint-config-semistandard-15.0.1.tgz", - "integrity": "sha512-sfV+qNBWKOmF0kZJll1VH5XqOAdTmLlhbOl9WKI11d2eMEe+Kicxnpm24PQWHOqAfk5pAWU2An0LjNCXKa4Usg==", - "dev": true - }, - "eslint-config-standard": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-15.0.1.tgz", - "integrity": "sha512-UGorkix49kBium7Y124o2U9Qy7Lpa+nO0FsaqQSIPeno5hGNxZtSBJbqJX6gtpYfDFWCtqCAN9wyK+oDd9jT7Q==", - "dev": true - }, - "eslint-config-standard-jsx": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-9.0.0.tgz", - "integrity": "sha512-e9ezaClB5YdTYqGUd3wReKC1si8XRn234tmME+3qebQ+KHtH92B6dr4LE6qPjK9AYe9XfwDK/xgQSwyCKQwv5Q==", - "dev": true - }, - "eslint-import-resolver-node": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", - "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", - "dev": true, - "requires": { - "debug": "^2.6.9", - "resolve": "^1.13.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-module-utils": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz", - "integrity": "sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "pkg-dir": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", - "dev": true, - "requires": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" - } - }, - "eslint-plugin-import": { - "version": "2.22.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", - "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==", - "dev": true, - "requires": { - "array-includes": "^3.1.1", - "array.prototype.flat": "^1.2.3", - "contains-path": "^0.1.0", - "debug": "^2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.4", - "eslint-module-utils": "^2.6.0", - "has": "^1.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.1", - "read-pkg-up": "^2.0.0", - "resolve": "^1.17.0", - "tsconfig-paths": "^3.9.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", - "dev": true, - "requires": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" - }, - "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "eslint-plugin-promise": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz", - "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==", - "dev": true - }, - "eslint-plugin-react": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.21.5.tgz", - "integrity": "sha512-8MaEggC2et0wSF6bUeywF7qQ46ER81irOdWS4QWxnnlAEsnzeBevk1sWh7fhpCghPpXb+8Ks7hvaft6L/xsR6g==", - "dev": true, - "requires": { - "array-includes": "^3.1.1", - "array.prototype.flatmap": "^1.2.3", - "doctrine": "^2.1.0", - "has": "^1.0.3", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "object.entries": "^1.1.2", - "object.fromentries": "^2.0.2", - "object.values": "^1.1.1", - "prop-types": "^15.7.2", - "resolve": "^1.18.1", - "string.prototype.matchall": "^4.0.2" - }, - "dependencies": { - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - } - } - }, - "eslint-plugin-standard": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.2.tgz", - "integrity": "sha512-nKptN8l7jksXkwFk++PhJB3cCDTcXOEyhISIN86Ue2feJ1LFyY3PrY3/xT2keXlJSY5bpmbiTG0f885/YKAvTA==", - "dev": true - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fast-redact": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-2.1.0.tgz", - "integrity": "sha512-0LkHpTLyadJavq9sRzzyqIoMZemWli77K2/MGOkafrR64B9ItrvZ9aT+jluvNDsv0YEHjSNhlMBtbokuoqii4A==" - }, - "fast-safe-stringify": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", - "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" - }, - "fast-text-encoding": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", - "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==" - }, - "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, - "requires": { - "flat-cache": "^2.0.1" - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "dev": true - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "findit2": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz", - "integrity": "sha1-WKRmaX34piBc39vzlVNri9d3pfY=" - }, - "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "dependencies": { - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "flatstr": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/flatstr/-/flatstr-1.0.12.tgz", - "integrity": "sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw==" - }, - "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "requires": { - "minipass": "^3.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "gaxios": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.0.tgz", - "integrity": "sha512-pHplNbslpwCLMyII/lHPWFQbJWOX0B3R1hwBEOvzYi1GmdKZruuEHK4N9V6f7tf1EaPYyF80mui1+344p6SmLg==", - "requires": { - "abort-controller": "^3.0.0", - "extend": "^3.0.2", - "https-proxy-agent": "^5.0.0", - "is-stream": "^2.0.0", - "node-fetch": "^2.3.0" - } - }, - "gcp-metadata": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.3.0.tgz", - "integrity": "sha512-L9XQUpvKJCM76YRSmcxrR4mFPzPGsgZUH+GgHMxAET8qc6+BhRJq63RLhWakgEO2KKVgeSDVfyiNjkGSADwNTA==", - "requires": { - "gaxios": "^4.0.0", - "json-bigint": "^1.0.0" - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "dev": true, - "requires": { - "type-fest": "^0.8.1" - } - }, - "google-auth-library": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.3.0.tgz", - "integrity": "sha512-MPeeMlnsYnoiiVFMwX3hgaS684aiXrSqKoDP+xL4Ejg4Z0qLvIeg4XsaChemyFI8ZUO7ApwDAzNtgmhWSDNh5w==", - "requires": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - } - }, - "google-p12-pem": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.0.tgz", - "integrity": "sha512-JUtEHXL4DY/N+xhlm7TC3qL797RPAtk0ZGXNs3/gWyiDHYoA/8Rjes0pztkda+sZv4ej1EoO2KhWgW5V9KTrSQ==", - "requires": { - "node-forge": "^0.10.0" - } - }, - "google-proto-files": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/google-proto-files/-/google-proto-files-2.4.0.tgz", - "integrity": "sha512-M5u56EsADOnplBUHTBzqBcCtPNPoGtBBXefjtA7mt3KDsOnlRM75fwrW2rsPS3Am2vrf9I0/NlI0E3nKWo/Ipg==", - "requires": { - "protobufjs": "^6.8.0", - "walkdir": "^0.4.0" - } - }, - "google-protobuf": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.13.0.tgz", - "integrity": "sha512-ZIf3qfLFayVrPvAjeKKxO5FRF1/NwRxt6Dko+fWEMuHwHbZx8/fcaAao9b0wCM6kr8qeg2te8XTpyuvKuD9aKw==" - }, - "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", - "dev": true - }, - "grpc": { - "version": "1.24.10", - "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.24.10.tgz", - "integrity": "sha512-mTR+P5IL3WO3oCgNwxKFE5ksXEJfCYP+dk0aIbjB494f7OnHTmssU5r9vznsSq3+cdLcxAzGFskOj5CaPwi8KA==", - "requires": { - "@mapbox/node-pre-gyp": "^1.0.4", - "@types/bytebuffer": "^5.0.40", - "lodash.camelcase": "^4.3.0", - "lodash.clone": "^4.5.0", - "nan": "^2.13.2", - "protobufjs": "^5.0.3" - }, - "dependencies": { - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "protobufjs": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.3.tgz", - "integrity": "sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==", - "requires": { - "ascli": "~1", - "bytebuffer": "~5", - "glob": "^7.0.5", - "yargs": "^3.10.0" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==" - }, - "yargs": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", - "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", - "requires": { - "camelcase": "^2.0.1", - "cliui": "^3.0.3", - "decamelize": "^1.1.1", - "os-locale": "^1.4.0", - "string-width": "^1.0.1", - "window-size": "^0.1.4", - "y18n": "^3.2.0" - } - } - } - }, - "gtoken": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.3.0.tgz", - "integrity": "sha512-mCcISYiaRZrJpfqOs0QWa6lfEM/C1V9ASkzFmuz43XBb5s1Vynh+CZy1ECeeJXVGx2PRByjYzb4Y4/zr1byr0w==", - "requires": { - "gaxios": "^4.0.0", - "google-p12-pem": "^3.0.3", - "jws": "^4.0.0" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - } - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-bigint": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", - "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", - "dev": true - }, - "is-boolean-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", - "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", - "dev": true - }, - "is-core-module": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", - "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "dev": true - }, - "is-number-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", - "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", - "dev": true - }, - "is-regex": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", - "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.2" - } - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" - }, - "is-string": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", - "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", - "dev": true - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "requires": { - "bignumber.js": "^9.0.0" - } - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jsx-ast-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", - "integrity": "sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==", - "dev": true, - "requires": { - "array-includes": "^3.1.2", - "object.assign": "^4.1.2" - } - }, - "jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "requires": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "requires": { - "invert-kv": "^1.0.0" - } - }, - "left-pad": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", - "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==" - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" - }, - "lodash.clone": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", - "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=" - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "mime-db": { - "version": "1.48.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", - "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" - }, - "mime-types": { - "version": "2.1.31", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", - "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", - "requires": { - "mime-db": "1.48.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "minipass": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", - "requires": { - "yallist": "^4.0.0" - } - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - }, - "module-details-from-path": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nan": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" - }, - "node-forge": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", - "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" - }, - "nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-inspect": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", - "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.entries": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.4.tgz", - "integrity": "sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.2" - } - }, - "object.fromentries": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz", - "integrity": "sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "has": "^1.0.3" - } - }, - "object.values": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", - "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.2" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "optjs": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", - "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=" - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "requires": { - "lcid": "^1.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - }, - "dependencies": { - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - } - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-duration": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-1.0.0.tgz", - "integrity": "sha512-X4kUkCTHU1N/kEbwK9FpUJ0UZQa90VzeczfS704frR30gljxDG0pSziws06XlK+CGRSo/1wtG1mFIdBFQTMQNw==" - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "parse-ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", - "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==" - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "pify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", - "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==" - }, - "pino": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/pino/-/pino-5.17.0.tgz", - "integrity": "sha512-LqrqmRcJz8etUjyV0ddqB6OTUutCgQULPFg2b4dtijRHUsucaAdBgSUW58vY6RFSX+NT8963F+q0tM6lNwGShA==", - "requires": { - "fast-redact": "^2.0.0", - "fast-safe-stringify": "^2.0.7", - "flatstr": "^1.0.12", - "pino-std-serializers": "^2.4.2", - "quick-format-unescaped": "^3.0.3", - "sonic-boom": "^0.7.5" - } - }, - "pino-std-serializers": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-2.5.0.tgz", - "integrity": "sha512-wXqbqSrIhE58TdrxxlfLwU9eDhrzppQDvGhBEr1gYbzzM4KKo3Y63gSjiDXRKLVS2UOXdPNR2v+KnQgNrs+xUg==" - }, - "pkg-conf": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz", - "integrity": "sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ==", - "dev": true, - "requires": { - "find-up": "^3.0.0", - "load-json-file": "^5.2.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "load-json-file": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", - "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.15", - "parse-json": "^4.0.0", - "pify": "^4.0.1", - "strip-bom": "^3.0.0", - "type-fest": "^0.3.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "type-fest": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", - "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", - "dev": true - } - } - }, - "pkg-config": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pkg-config/-/pkg-config-1.1.1.tgz", - "integrity": "sha1-VX7yLXPaPIg3EHdmxS6tq94pj+Q=", - "dev": true, - "requires": { - "debug-log": "^1.0.0", - "find-root": "^1.0.0", - "xtend": "^4.0.1" - } - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - }, - "pprof": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pprof/-/pprof-3.1.0.tgz", - "integrity": "sha512-nbYfVzZYQ/TPV9QZFPMb59FRZrIe4M4FTruH11+vd4gR5cGUG3dfoXpXdfki50eeVeqWQrXuWdUsrRIZi2SteQ==", - "requires": { - "@mapbox/node-pre-gyp": "^1.0.0", - "bindings": "^1.2.1", - "delay": "^5.0.0", - "findit2": "^2.2.3", - "nan": "^2.14.0", - "p-limit": "^3.0.0", - "pify": "^5.0.0", - "protobufjs": "~6.10.0", - "source-map": "^0.7.3", - "split": "^1.0.1" - }, - "dependencies": { - "@types/node": { - "version": "13.13.52", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", - "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==" - }, - "protobufjs": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz", - "integrity": "sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==", - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": "^13.7.0", - "long": "^4.0.0" - } - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" - } - } - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "pretty-ms": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", - "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", - "requires": { - "parse-ms": "^2.1.0" - } - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "dev": true, - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, - "protobufjs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", - "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - } - }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "quick-format-unescaped": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-3.0.3.tgz", - "integrity": "sha512-dy1yjycmn9blucmJLXOfZDx1ikZJUi6E8bBZLnhPG5gBrVhHXx2xVyqqgKBubVNEXmx51dBACMHpoMQK/N/AXQ==" - }, - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "regexp.prototype.flags": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", - "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-in-the-middle": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.1.0.tgz", - "integrity": "sha512-M2rLKVupQfJ5lf9OvqFGIT+9iVLnTmjgbOmpil12hiSQNn5zJTKGPoIisETNjfK+09vP3rpm1zJajmErpr2sEQ==", - "requires": { - "debug": "^4.1.1", - "module-details-from-path": "^1.0.3", - "resolve": "^1.12.0" - } - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "retry-request": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.2.1.tgz", - "integrity": "sha512-afiCoZZ7D/AR2mf+9ajr75dwGFgWmPEshv3h+oKtf9P1AsHfHvcVXumdbAEq2qNy4UXFEXsEX5HpyGj4axvoaA==", - "requires": { - "debug": "^4.1.1" - } - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { - "glob": "^7.1.3" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "semistandard": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/semistandard/-/semistandard-15.0.0.tgz", - "integrity": "sha512-qWMJubk+WeTHXtdoe4Kh81SqwcVPwOsJcDFu1QbXqO3vh60PwEJ1VrlhaHXNwP3fjfGdFPJBYXlA8x4QRNIbdw==", - "dev": true, - "requires": { - "eslint": "~7.12.1", - "eslint-config-semistandard": "15.0.1", - "eslint-config-standard": "15.0.1", - "eslint-config-standard-jsx": "9.0.0", - "eslint-plugin-import": "~2.22.1", - "eslint-plugin-node": "~11.1.0", - "eslint-plugin-promise": "~4.2.1", - "eslint-plugin-react": "~7.21.5", - "eslint-plugin-standard": "~4.0.2", - "standard-engine": "^13.0.0" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" - }, - "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - } - } - }, - "sonic-boom": { - "version": "0.7.7", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-0.7.7.tgz", - "integrity": "sha512-Ei5YOo5J64GKClHIL/5evJPgASXFVpfVYbJV9PILZQytTK6/LCwHvsZJW2Ig4p9FMC2OrBrMnXKgRN/OEoAWfg==", - "requires": { - "atomic-sleep": "^1.0.0", - "flatstr": "^1.0.12" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", - "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", - "dev": true - }, - "split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "requires": { - "through": "2" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "standard-engine": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-13.0.0.tgz", - "integrity": "sha512-fQ8/0SQ84hRtxru3tsyhc8JDBDrUFzJc/lOxh5Of/wCEpMZ0J0j7XX5kymtgdZZEke0Lb1HxzvSYdnjmg05ewA==", - "dev": true, - "requires": { - "deglob": "^4.0.1", - "get-stdin": "^8.0.0", - "minimist": "^1.2.5", - "pkg-conf": "^3.1.0", - "xdg-basedir": "^4.0.0" - } - }, - "stream-events": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", - "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", - "requires": { - "stubs": "^3.0.0" - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string.prototype.matchall": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz", - "integrity": "sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.2", - "get-intrinsic": "^1.1.1", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.3.1", - "side-channel": "^1.0.4" - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "stubs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "tar": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", - "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - } - }, - "teeny-request": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.1.1.tgz", - "integrity": "sha512-iwY6rkW5DDGq8hE2YgNQlKbptYpY5Nn2xecjQiNjOXWbKzPGUfmeUBCSQbbr306d7Z7U2N0TPl+/SwYRfua1Dg==", - "requires": { - "http-proxy-agent": "^4.0.0", - "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.6.1", - "stream-events": "^1.0.5", - "uuid": "^8.0.0" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "tsconfig-paths": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz", - "integrity": "sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q==", - "dev": true, - "requires": { - "json5": "^2.2.0", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", - "dev": true - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "walkdir": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", - "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "window-size": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=" - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - }, - "dependencies": { - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - } - } - }, - "xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "dev": true - }, - "xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - } - }, - "xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" - } - } -} diff --git a/src/currencyservice/package.json b/src/currencyservice/package.json deleted file mode 100644 index b67b3e8c5..000000000 --- a/src/currencyservice/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "grpc-currency-service", - "version": "0.1.0", - "description": "A gRPC currency conversion microservice", - "repository": "https://github.com/GoogleCloudPlatform/microservices-demo", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "lint": "semistandard *.js" - }, - "license": "Apache-2.0", - "dependencies": { - "@google-cloud/debug-agent": "5.1.3", - "@google-cloud/opentelemetry-cloud-trace-exporter": "^0.10.0", - "@google-cloud/profiler": "4.1.2", - "@grpc/proto-loader": "0.6.2", - "@opentelemetry/api": "^1.0.0", - "@opentelemetry/instrumentation-grpc": "^0.23.0", - "@opentelemetry/node": "^0.23.0", - "@opentelemetry/tracing": "^0.22.0", - "ajv": "^5.0.0", - "async": "3.2.0", - "google-protobuf": "3.13.0", - "grpc": "1.24.10", - "left-pad": "1.3.0", - "pino": "5.17.0", - "request": "2.88.2", - "xml2js": "0.4.23" - }, - "devDependencies": { - "semistandard": "^15.0.0" - } -} diff --git a/src/currencyservice/proto/demo.proto b/src/currencyservice/proto/demo.proto deleted file mode 100644 index e5981af58..000000000 --- a/src/currencyservice/proto/demo.proto +++ /dev/null @@ -1,260 +0,0 @@ -// 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 "vintage" or "gardening" 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; -} diff --git a/src/currencyservice/proto/grpc/health/v1/health.proto b/src/currencyservice/proto/grpc/health/v1/health.proto deleted file mode 100644 index 4b4677b8a..000000000 --- a/src/currencyservice/proto/grpc/health/v1/health.proto +++ /dev/null @@ -1,43 +0,0 @@ -// 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); -} diff --git a/src/currencyservice/server.js b/src/currencyservice/server.js deleted file mode 100644 index cd61c8101..000000000 --- a/src/currencyservice/server.js +++ /dev/null @@ -1,223 +0,0 @@ -/* - * 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. - */ - -require('@google-cloud/profiler').start({ - serviceContext: { - service: 'currencyservice', - } -}); -require('@google-cloud/debug-agent').start({ - serviceContext: { - service: 'currencyservice', - } -}); - -const opentelemetry = require('@opentelemetry/api'); -const {NodeTracerProvider} = require('@opentelemetry/node'); -const {BatchSpanProcessor} = require('@opentelemetry/tracing'); -const {TraceExporter} = require('@google-cloud/opentelemetry-cloud-trace-exporter'); -const { registerInstrumentations } = require('@opentelemetry/instrumentation'); -const { GrpcInstrumentation } = require('@opentelemetry/instrumentation-grpc'); - -// OpenTelemetry tracing with exporter to Google Cloud Trace -const provider = new NodeTracerProvider(); -provider.register(); - -registerInstrumentations({ - instrumentations: [new GrpcInstrumentation()] -}); - -// Enable OpenTelemetry exporters to export traces to Google Cloud Trace. -// Exporters use Application Default Credentials (ADCs) to authenticate. -// See https://developers.google.com/identity/protocols/application-default-credentials -// for more details. When your application is running on GCP, -// you don't need to provide auth credentials or a project id. -const exporter = new TraceExporter(); -provider.addSpanProcessor(new BatchSpanProcessor(exporter)); -const tracer = opentelemetry.trace.getTracer('currency'); - -const path = require('path'); -const grpc = require('grpc'); -const request = require('request'); -const xml2js = require('xml2js'); -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 = 7000; -const DATA_URL = 'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml'; - -const shopProto = _loadProto(MAIN_PROTO_PATH).hipstershop; -const healthProto = _loadProto(HEALTH_PROTO_PATH).grpc.health.v1; - -const logger = pino({ - name: 'currencyservice-server', - messageKey: 'message', - levelKey: '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 an XML webpage - * Uses public data from European Central Bank - */ -let _data; -function _getCurrencyData (callback) { - if (!_data) { - logger.info('Fetching currency data...'); - request(DATA_URL, (err, res) => { - if (err) { - throw new Error(`Error getting data: ${err}`); - } - - const body = res.body.split('\n').slice(7, -2).join('\n'); - xml2js.parseString(body, (err, resJs) => { - if (err) { - throw new Error(`Error parsing HTML: ${err}`); - } - - const array = resJs['Cube']['Cube'].map(x => x['$']); - const results = array.reduce((acc, x) => { - acc[x['currency']] = x['rate']; - return acc; - }, { 'EUR': '1.0' }); - _data = results; - callback(_data); - }); - }); - } else { - 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) { - // Extract the span context received from the gRPC client. - // Create a child span and add an event. - const currentSpan = opentelemetry.trace.getSpan(opentelemetry.context.active()) - const span = tracer.startSpan('currencyservice:GetSupportedCurrencies()', { - parent: currentSpan, - kind: 1, // server - }); - span.addEvent('Get Supported Currencies'); - logger.info('Getting supported currencies...'); - _getCurrencyData((data) => { - callback(null, {currency_codes: Object.keys(data)}); - span.end(); - }); -} - -/** - * Converts between currencies - */ -function convert (call, callback) { - // Extract the span context received from the gRPC client. - // Create a child span and add an event. - const currentSpan = opentelemetry.trace.getSpan(opentelemetry.context.active()) - const span = tracer.startSpan('currencyservice:Convert()', { - parent: currentSpan, - kind: 1, // server - }); - logger.info('received conversion request'); - 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`); - span.addEvent(`Convert Currency from ${request.from.currency_code} to ${request.to_code}`); - callback(null, result); - span.end(); - }); - } 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.bind(`0.0.0.0:${PORT}`, grpc.ServerCredentials.createInsecure()); - server.start(); -} - -main(); -// Flush all traces and shut down the Cloud Trace exporter. -exporter.shutdown(); diff --git a/src/emailservice/Dockerfile b/src/emailservice/Dockerfile deleted file mode 100644 index 4eca38827..000000000 --- a/src/emailservice/Dockerfile +++ /dev/null @@ -1,52 +0,0 @@ -# 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++ \ - && 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.3.5 && \ - 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.9/ /usr/local/lib/python3.9/ - -# Add the application -COPY . . - -EXPOSE 8080 -ENTRYPOINT [ "python", "email_server.py" ] diff --git a/src/emailservice/demo_pb2.py b/src/emailservice/demo_pb2.py deleted file mode 100644 index d72a5e707..000000000 --- a/src/emailservice/demo_pb2.py +++ /dev/null @@ -1,1766 +0,0 @@ -#!/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) diff --git a/src/emailservice/demo_pb2_grpc.py b/src/emailservice/demo_pb2_grpc.py deleted file mode 100644 index 7b567b13a..000000000 --- a/src/emailservice/demo_pb2_grpc.py +++ /dev/null @@ -1,491 +0,0 @@ -#!/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,)) diff --git a/src/emailservice/email_client.py b/src/emailservice/email_client.py deleted file mode 100644 index 9f194f90c..000000000 --- a/src/emailservice/email_client.py +++ /dev/null @@ -1,58 +0,0 @@ -#!/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 -from opentelemetry import propagate, trace -from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter -from opentelemetry.instrumentation.grpc import client_interceptor -from opentelemetry.propagators.cloud_trace_propagator import CloudTraceFormatPropagator -from opentelemetry.sdk.trace import TracerProvider -from opentelemetry.sdk.trace.export import SimpleSpanProcessor - -import demo_pb2 -import demo_pb2_grpc -from logger import get_json_logger - -logger = get_json_logger("emailservice-client") - - -try: - trace.set_tracer_provider(TracerProvider()) - trace.get_tracer_provider().add_span_processor( - SimpleSpanProcessor(CloudTraceSpanExporter()) - ) - propagate.set_global_textmap(CloudTraceFormatPropagator()) - tracer_interceptor = client_interceptor(trace.get_tracer_provider()) -except Exception as e: - raise Exception("{}".format(e)) - - -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. response: {}".format(response)) - 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.") diff --git a/src/emailservice/email_server.py b/src/emailservice/email_server.py deleted file mode 100644 index 95bcd8e24..000000000 --- a/src/emailservice/email_server.py +++ /dev/null @@ -1,250 +0,0 @@ -#!/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 base64 -import os -import time -import traceback -from concurrent import futures - -import googlecloudprofiler -import grpc -from google.api_core.exceptions import GoogleAPICallError -from grpc_health.v1 import health_pb2, health_pb2_grpc -from jinja2 import Environment, FileSystemLoader, TemplateError, select_autoescape -from opentelemetry import propagate, trace -from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter -from opentelemetry.instrumentation.grpc import server_interceptor -from opentelemetry.propagators.cloud_trace_propagator import CloudTraceFormatPropagator -from opentelemetry.sdk.trace import TracerProvider -from opentelemetry.sdk.trace.export import SimpleSpanProcessor - -import demo_pb2 -import demo_pb2_grpc -from logger import get_json_logger - -logger = get_json_logger("emailservice-server") - -try: - import googleclouddebugger - - googleclouddebugger.enable(module="emailserver", version="1.0.0") -except ImportError: - logger.error("could not enable debugger") - logger.error(traceback.print_exc()) - -# 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") - - @staticmethod - def send_email(client, email_address, content): - # TODO(yoshifumi): replace tentative project_id, region and sender_id - # with the actual values when DummyEmailService is removed. - project_id = "dummy-project-id" - region = "dummy-region" - sender_id = "dummy-sender" - from_address = "0.0.0.0:6000" - - 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 - ) - ) - if os.getenv("ENCODE_EMAIL", "false").lower() == "true": - try: - encoded_email = self.EncodeEmail(request.email) - request.email = encoded_email - except Exception: - logger.error("Err: Could not encode email") - context.set_code(grpc.StatusCode.INTERNAL) - return demo_pb2.Empty() - - def EncodeEmail(self, email): - """ - Encodes the email address to base64 encoding - Input: - email - (string) the email address - Output: - string - the encoded email as base64 - """ - byte_rep = email.encode("ascii") - b64_bytes = base64.b64encode(email) - return b64_bytes.decode("ascii") - - -class HealthCheck: - def Check(self, request, context): - return health_pb2.HealthCheckResponse( - status=health_pb2.HealthCheckResponse.SERVING - ) - - -def start(dummy_mode): - # Create gRPC server channel to receive requests from checkout (client). - interceptor = server_interceptor(trace.get_tracer_provider()) - server = grpc.server( - futures.ThreadPoolExecutor(max_workers=10), interceptors=(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 init_cloud_profiler(): - 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" - ) - - -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.") - init_cloud_profiler() - except KeyError: - logger.info("Profiler disabled.") - - # OpenTelemetry Tracing - # TracerProvider provides global state and access to tracers. - trace.set_tracer_provider(TracerProvider()) - - # Export traces to Google Cloud Trace - # When running on GCP, the exporter handles authentication - # using automatically default application credentials. - # When running locally, credentials may need to be set explicitly. - trace.get_tracer_provider().add_span_processor( - SimpleSpanProcessor(CloudTraceSpanExporter()) - ) - propagate.set_global_textmap(CloudTraceFormatPropagator()) - - start(dummy_mode=True) diff --git a/src/emailservice/genproto.sh b/src/emailservice/genproto.sh deleted file mode 100755 index 3e7e01e89..000000000 --- a/src/emailservice/genproto.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/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. - -#!/bin/bash -e - -python -m grpc_tools.protoc -I../../pb --python_out=. --grpc_python_out=. ../../pb/demo.proto diff --git a/src/emailservice/logger.py b/src/emailservice/logger.py deleted file mode 100644 index 0a8262be7..000000000 --- a/src/emailservice/logger.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/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 get_json_logger(name): - logger = logging.getLogger(name) - handler = logging.StreamHandler(sys.stdout) - formatter = CustomJsonFormatter("%(timestamp)s %(severity)s %(name)s %(message)s") - handler.setFormatter(formatter) - logger.addHandler(handler) - logger.setLevel(logging.INFO) - logger.propagate = False - return logger diff --git a/src/emailservice/requirements.in b/src/emailservice/requirements.in deleted file mode 100644 index 1f0398060..000000000 --- a/src/emailservice/requirements.in +++ /dev/null @@ -1,17 +0,0 @@ -google-api-core==1.26.3 -google-python-cloud-debugger==2.17 -grpcio-health-checking==1.30.0 -grpcio==1.36.1 -jinja2==2.11.3 -opentelemetry-api==1.0 -opentelemetry-sdk==1.0 -opentelemetry-exporter-gcp-trace==1.0.0 -opentelemetry-propagator-gcp==1.0.0 -opentelemetry-instrumentation-grpc==0.19b0 -opentelemetry-instrumentation==0.19b0 -python-json-logger==0.1.11 -google-cloud-profiler==1.1.2 -google-cloud-trace==0.24.0 -requests==2.25.1 -httplib2==0.19.0 -urllib3==1.26.5 diff --git a/src/emailservice/requirements.txt b/src/emailservice/requirements.txt deleted file mode 100644 index 0fe9e0b38..000000000 --- a/src/emailservice/requirements.txt +++ /dev/null @@ -1,47 +0,0 @@ -# -# This file is autogenerated by pip-compile -# To update, run: -# -# pip-compile -# -cachetools==4.2.2 # via google-auth -certifi==2020.12.5 # via requests -chardet==3.0.4 # via requests -google-api-core[grpc]==1.26.3 # via -r requirements.in, google-api-python-client, google-cloud-core, google-cloud-trace, google-python-cloud-debugger -google-api-python-client==1.12.8 # via google-cloud-profiler, google-python-cloud-debugger -google-auth-httplib2==0.0.4 # via google-api-python-client, google-cloud-profiler, google-python-cloud-debugger -google-auth==1.24.0 # via google-api-core, google-api-python-client, google-auth-httplib2, google-cloud-profiler, google-python-cloud-debugger -google-cloud-core==1.4.4 # via google-cloud-trace -google-cloud-profiler==1.1.2 # via -r requirements.in -google-cloud-trace==0.24.0 # via -r requirements.in, opentelemetry-exporter-gcp-trace -google-python-cloud-debugger==2.17 # via -r requirements.in -googleapis-common-protos==1.52.0 # via google-api-core -grpcio-health-checking==1.30.0 # via -r requirements.in -grpcio==1.36.1 # via -r requirements.in, google-api-core, grpcio-health-checking, opentelemetry-instrumentation-grpc -httplib2==0.19.0 # via -r requirements.in, google-api-python-client, google-auth-httplib2 -idna==2.10 # via requests -jinja2==2.11.3 # via -r requirements.in -markupsafe==1.1.1 # via jinja2 -opentelemetry-api==1.0.0 # via -r requirements.in, opentelemetry-exporter-gcp-trace, opentelemetry-instrumentation, opentelemetry-instrumentation-grpc, opentelemetry-propagator-gcp, opentelemetry-sdk -opentelemetry-exporter-gcp-trace==1.0.0 # via -r requirements.in -opentelemetry-instrumentation-grpc==0.19b0 # via -r requirements.in -opentelemetry-instrumentation==0.19b0 # via -r requirements.in, opentelemetry-instrumentation-grpc -opentelemetry-propagator-gcp==1.0.0 # via -r requirements.in -opentelemetry-sdk==1.0.0 # via -r requirements.in, opentelemetry-exporter-gcp-trace, opentelemetry-instrumentation-grpc -packaging==20.9 # via google-api-core -protobuf==3.13.0 # via google-api-core, google-cloud-profiler, googleapis-common-protos, grpcio-health-checking -pyasn1-modules==0.2.8 # via google-auth -pyasn1==0.4.8 # via pyasn1-modules, rsa -pyparsing==2.4.7 # via httplib2, packaging -python-json-logger==0.1.11 # via -r requirements.in -pytz==2018.9 # via google-api-core -pyyaml==5.4.1 # via google-python-cloud-debugger -requests==2.25.1 # via -r requirements.in, google-api-core, google-cloud-profiler -rsa==4.7 # via google-auth -six==1.15.0 # via google-api-core, google-api-python-client, google-auth, google-auth-httplib2, google-cloud-core, google-python-cloud-debugger, grpcio, protobuf -uritemplate==3.0.1 # via google-api-python-client -urllib3==1.26.5 # via -r requirements.in, requests -wrapt==1.12.1 # via opentelemetry-instrumentation, opentelemetry-instrumentation-grpc - -# The following packages are considered to be unsafe in a requirements file: -# setuptools diff --git a/src/emailservice/templates/confirmation.html b/src/emailservice/templates/confirmation.html deleted file mode 100644 index 4b1c7c82d..000000000 --- a/src/emailservice/templates/confirmation.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - 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.QuantityPrice
#{{ item.item.product_id }}{{ item.item.quantity }}{{ item.cost.units }}.{{ "%02d" | format(item.cost.nanos // 10000000) }} {{ item.cost.currency_code }}
- - diff --git a/src/frontend/.dockerignore b/src/frontend/.dockerignore deleted file mode 100644 index 48b8bf907..000000000 --- a/src/frontend/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -vendor/ diff --git a/src/frontend/.gitkeep b/src/frontend/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/frontend/Dockerfile b/src/frontend/Dockerfile deleted file mode 100644 index 772e5b8ac..000000000 --- a/src/frontend/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -# 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.15-alpine as builder -RUN apk add --no-cache ca-certificates git && \ - wget -qO/go/bin/dep https://github.com/golang/dep/releases/download/v0.5.0/dep-linux-amd64 && \ - chmod +x /go/bin/dep - -ENV PROJECT github.com/GoogleCloudPlatform/microservices-demo/src/frontend -WORKDIR /go/src/$PROJECT - -# restore dependencies -COPY Gopkg.* ./ -RUN dep ensure --vendor-only -v -COPY . . -RUN go install . - -FROM alpine as release -RUN apk add --no-cache ca-certificates \ - busybox-extras net-tools bind-tools -WORKDIR /frontend -COPY --from=builder /go/bin/frontend /frontend/server -COPY ./templates ./templates -COPY ./static ./static -EXPOSE 8080 -ENTRYPOINT ["/frontend/server"] diff --git a/src/frontend/Gopkg.lock b/src/frontend/Gopkg.lock deleted file mode 100644 index 06b2ab179..000000000 --- a/src/frontend/Gopkg.lock +++ /dev/null @@ -1,421 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - digest = "1:cd61c288406d5d80572967f908a23a1f0ffbf460e926269672e955f4a88b79bc" - name = "cloud.google.com/go" - packages = [ - "compute/metadata", - "internal/version", - "monitoring/apiv3", - "profiler", - "trace/apiv2", - ] - pruneopts = "UT" - revision = "457ea5c15ccf3b87db582c450e80101989da35f7" - version = "v0.40.0" - -[[projects]] - digest = "1:4b96dcd8534bc6450a922bd16a76360ba3381f0d1daf40abbaec91c053fbfeb5" - name = "contrib.go.opencensus.io/exporter/stackdriver" - packages = ["."] - pruneopts = "UT" - revision = "37aa2801fbf0205003e15636096ebf0373510288" - version = "v0.5.0" - -[[projects]] - digest = "1:34624033bc188a4e41a68c1ba6ca9b2650e8c5f2136c28045b18c9c503a749d1" - name = "github.com/DataDog/sketches-go" - packages = ["ddsketch"] - pruneopts = "UT" - revision = "43f19ad77ff73bc865c41f7e391ef4b23b82810a" - version = "v0.0.1" - -[[projects]] - branch = "master" - digest = "1:6cbe7676244a1429f4c22601f799d377a70449469ef636f91d992d719b559ff3" - name = "github.com/GoogleCloudPlatform/microservices-demo" - packages = [ - "src/frontend/genproto", - "src/frontend/money", - ] - pruneopts = "UT" - revision = "d944092100696aa4a5974ef5c2e710547a824622" - -[[projects]] - digest = "1:9fe8532210bb4a51753c8b783bb6ff4bf03da370b2440a05f5686b3b440ce930" - name = "github.com/GoogleCloudPlatform/opentelemetry-operations-go" - packages = ["exporter/trace"] - pruneopts = "UT" - revision = "a1393affee9a13ed21974ae1d791da1b3189f4a0" - version = "v0.2.1" - -[[projects]] - digest = "1:72856926f8208767b837bf51e3373f49139f61889b67dc7fd3c2a0fd711e3f7a" - name = "github.com/golang/protobuf" - packages = [ - "proto", - "protoc-gen-go/descriptor", - "ptypes", - "ptypes/any", - "ptypes/duration", - "ptypes/empty", - "ptypes/struct", - "ptypes/timestamp", - "ptypes/wrappers", - ] - pruneopts = "UT" - revision = "aa810b61a9c79d51363740d207bb46cf8e620ed5" - version = "v1.2.0" - -[[projects]] - branch = "master" - digest = "1:089d56c0adb79140365b5c86815ce97233986da6f3a525c6b706773e4b83876f" - name = "github.com/google/pprof" - packages = ["profile"] - pruneopts = "UT" - revision = "3ea8567a2e5752420fc544d2e2ad249721768934" - -[[projects]] - digest = "1:236d7e1bdb50d8f68559af37dbcf9d142d56b431c9b2176d41e2a009b664cda8" - name = "github.com/google/uuid" - packages = ["."] - pruneopts = "UT" - revision = "9b3b1e0f5f99ae461456d768e7d301a7acdaa2d8" - version = "v1.1.0" - -[[projects]] - digest = "1:856bd1e35f6da8ce5671a5df09d0e89bf01e9b74b3dabb6d097d39b3813801e1" - name = "github.com/googleapis/gax-go" - packages = ["v2"] - pruneopts = "UT" - revision = "c8a15bac9b9fe955bd9f900272f9a306465d28cf" - version = "v2.0.3" - -[[projects]] - digest = "1:c79fb010be38a59d657c48c6ba1d003a8aa651fa56b579d959d74573b7dff8e1" - name = "github.com/gorilla/context" - packages = ["."] - pruneopts = "UT" - revision = "08b5f424b9271eedf6f9f0ce86cb9396ed337a42" - version = "v1.1.1" - -[[projects]] - digest = "1:e73f5b0152105f18bc131fba127d9949305c8693f8a762588a82a48f61756f5f" - name = "github.com/gorilla/mux" - packages = ["."] - pruneopts = "UT" - revision = "e3702bed27f0d39777b0b37b664b6280e8ef8fbf" - version = "v1.6.2" - -[[projects]] - digest = "1:0a69a1c0db3591fcefb47f115b224592c8dfa4368b7ba9fae509d5e16cdc95c8" - name = "github.com/konsorten/go-windows-terminal-sequences" - packages = ["."] - pruneopts = "UT" - revision = "5c8c8bd35d3832f5d134ae1e1e375b69a4d25242" - version = "v1.0.1" - -[[projects]] - digest = "1:40e195917a951a8bf867cd05de2a46aaf1806c50cf92eebf4c16f78cd196f747" - name = "github.com/pkg/errors" - packages = ["."] - pruneopts = "UT" - revision = "645ef00459ed84a119197bfb8d8205042c6df63d" - version = "v0.8.0" - -[[projects]] - digest = "1:69b1cc331fca23d702bd72f860c6a647afd0aa9fcbc1d0659b1365e26546dd70" - name = "github.com/sirupsen/logrus" - packages = ["."] - pruneopts = "UT" - revision = "bcd833dfe83d3cebad139e4a29ed79cb2318bf95" - version = "v1.2.0" - -[[projects]] - digest = "1:1bb914cfb78f68f488a91cd7872d3d06a5f83c5bbacf0296dbef44e120b00a91" - name = "go.opencensus.io" - packages = [ - ".", - "internal", - "internal/tagencoding", - "plugin/ocgrpc", - "plugin/ochttp", - "plugin/ochttp/propagation/b3", - "stats", - "stats/internal", - "stats/view", - "tag", - "trace", - "trace/internal", - "trace/propagation", - "trace/tracestate", - ] - pruneopts = "UT" - revision = "b11f239c032624b045c4c2bfd3d1287b4012ce89" - version = "v0.16.0" - -[[projects]] - digest = "1:2f2ba64eb51ae09d5f683c176a5114f3a6d7e8fd9bb3b196c1fbd7cc0ddc2512" - name = "go.opentelemetry.io/otel" - packages = [ - "api/correlation", - "api/global", - "api/global/internal", - "api/internal", - "api/kv", - "api/kv/value", - "api/label", - "api/metric", - "api/metric/registry", - "api/oterror", - "api/propagation", - "api/standard", - "api/trace", - "api/unit", - "exporters/metric/stdout", - "instrumentation/grpctrace", - "instrumentation/othttp", - "internal/metric", - "internal/trace/parent", - "sdk", - "sdk/export/metric", - "sdk/export/metric/aggregation", - "sdk/export/trace", - "sdk/instrumentation", - "sdk/internal", - "sdk/metric", - "sdk/metric/aggregator", - "sdk/metric/aggregator/array", - "sdk/metric/aggregator/ddsketch", - "sdk/metric/aggregator/histogram", - "sdk/metric/aggregator/minmaxsumcount", - "sdk/metric/aggregator/sum", - "sdk/metric/controller/push", - "sdk/metric/controller/time", - "sdk/metric/processor/basic", - "sdk/metric/selector/simple", - "sdk/resource", - "sdk/trace", - "sdk/trace/internal", - ] - pruneopts = "UT" - revision = "58e50e249fe4c57f64e421e300b5d2316ae96811" - version = "v0.9.0" - -[[projects]] - branch = "master" - digest = "1:38f553aff0273ad6f367cb0a0f8b6eecbaef8dc6cb8b50e57b6a81c1d5b1e332" - name = "golang.org/x/crypto" - packages = ["ssh/terminal"] - pruneopts = "UT" - revision = "ff983b9c42bc9fbf91556e191cc8efb585c16908" - -[[projects]] - branch = "master" - digest = "1:8ecb828bb550a8c6b7d75b8261a42c369461311616ebe5451966d067f5f993bf" - name = "golang.org/x/net" - packages = [ - "context", - "context/ctxhttp", - "http/httpguts", - "http2", - "http2/hpack", - "idna", - "internal/timeseries", - "trace", - ] - pruneopts = "UT" - revision = "927f97764cc334a6575f4b7a1584a147864d5723" - -[[projects]] - branch = "master" - digest = "1:23443edff0740e348959763085df98400dcfd85528d7771bb0ce9f5f2754ff4a" - name = "golang.org/x/oauth2" - packages = [ - ".", - "google", - "internal", - "jws", - "jwt", - ] - pruneopts = "UT" - revision = "d668ce993890a79bda886613ee587a69dd5da7a6" - -[[projects]] - branch = "master" - digest = "1:75515eedc0dc2cb0b40372008b616fa2841d831c63eedd403285ff286c593295" - name = "golang.org/x/sync" - packages = ["semaphore"] - pruneopts = "UT" - revision = "37e7f081c4d4c64e13b10787722085407fe5d15f" - -[[projects]] - branch = "master" - digest = "1:191cccd950a4aeadb60306062f2bdc2f924d750d0156ec6c691b17211bfd7349" - name = "golang.org/x/sys" - packages = [ - "unix", - "windows", - ] - pruneopts = "UT" - revision = "82a175fd1598e8a172e58ebdf5ed262bb29129e5" - -[[projects]] - digest = "1:a2ab62866c75542dd18d2b069fec854577a20211d7c0ea6ae746072a1dccdd18" - name = "golang.org/x/text" - packages = [ - "collate", - "collate/build", - "internal/colltab", - "internal/gen", - "internal/tag", - "internal/triegen", - "internal/ucd", - "language", - "secure/bidirule", - "transform", - "unicode/bidi", - "unicode/cldr", - "unicode/norm", - "unicode/rangetable", - ] - pruneopts = "UT" - revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0" - version = "v0.3.0" - -[[projects]] - branch = "master" - digest = "1:2e81813e8e072aa700e101369890e55539729d817d32dbc3fab228d6b40c4d83" - name = "google.golang.org/api" - packages = [ - "googleapi/transport", - "internal", - "iterator", - "option", - "support/bundler", - "transport", - "transport/grpc", - "transport/http", - "transport/http/internal/propagation", - ] - pruneopts = "UT" - revision = "19e022d8cf43ce81f046bae8cc18c5397cc7732f" - -[[projects]] - digest = "1:c4eaa5f79d36f76ef4bd0c4f96e36bc1b7b5a359528d1267f0cb7a5d58b7b5bb" - name = "google.golang.org/appengine" - packages = [ - ".", - "internal", - "internal/app_identity", - "internal/base", - "internal/datastore", - "internal/log", - "internal/modules", - "internal/remote_api", - "internal/socket", - "internal/urlfetch", - "socket", - "urlfetch", - ] - pruneopts = "UT" - revision = "e9657d882bb81064595ca3b56cbe2546bbabf7b1" - version = "v1.4.0" - -[[projects]] - branch = "master" - digest = "1:3552e7267a98c605e6cbfe6b03c34589265ab72e6078b95fb2e10e0cb44f5cc8" - name = "google.golang.org/genproto" - packages = [ - "googleapis/api/annotations", - "googleapis/api/distribution", - "googleapis/api/label", - "googleapis/api/metric", - "googleapis/api/monitoredres", - "googleapis/devtools/cloudprofiler/v2", - "googleapis/devtools/cloudtrace/v2", - "googleapis/monitoring/v3", - "googleapis/rpc/errdetails", - "googleapis/rpc/status", - "protobuf/field_mask", - ] - pruneopts = "UT" - revision = "bd9b4fb69e2ffd37621a6caa54dcbead29b546f2" - -[[projects]] - digest = "1:3fc54ad826c0183f803bb97e0927dfc05fcb7b7a6ddabed646ee8184d861fa9b" - name = "google.golang.org/grpc" - packages = [ - ".", - "balancer", - "balancer/base", - "balancer/roundrobin", - "binarylog/grpc_binarylog_v1", - "codes", - "connectivity", - "credentials", - "credentials/internal", - "credentials/oauth", - "encoding", - "encoding/proto", - "grpclog", - "internal", - "internal/backoff", - "internal/binarylog", - "internal/channelz", - "internal/envconfig", - "internal/grpcrand", - "internal/grpcsync", - "internal/syscall", - "internal/transport", - "keepalive", - "metadata", - "naming", - "peer", - "resolver", - "resolver/dns", - "resolver/passthrough", - "stats", - "status", - "tap", - ] - pruneopts = "UT" - revision = "df014850f6dee74ba2fc94874043a9f3f75fbfd8" - version = "v1.17.0" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - input-imports = [ - "cloud.google.com/go/profiler", - "contrib.go.opencensus.io/exporter/stackdriver", - "github.com/GoogleCloudPlatform/microservices-demo/src/frontend/genproto", - "github.com/GoogleCloudPlatform/microservices-demo/src/frontend/money", - "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace", - "github.com/golang/protobuf/proto", - "github.com/google/uuid", - "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", - "go.opentelemetry.io/otel/api/global", - "go.opentelemetry.io/otel/api/kv", - "go.opentelemetry.io/otel/api/metric", - "go.opentelemetry.io/otel/api/standard", - "go.opentelemetry.io/otel/api/trace", - "go.opentelemetry.io/otel/exporters/metric/stdout", - "go.opentelemetry.io/otel/instrumentation/grpctrace", - "go.opentelemetry.io/otel/instrumentation/othttp", - "go.opentelemetry.io/otel/sdk/metric/controller/push", - "go.opentelemetry.io/otel/sdk/resource", - "go.opentelemetry.io/otel/sdk/trace", - "golang.org/x/net/context", - "google.golang.org/grpc", - ] - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/src/frontend/Gopkg.toml b/src/frontend/Gopkg.toml deleted file mode 100644 index 74588b388..000000000 --- a/src/frontend/Gopkg.toml +++ /dev/null @@ -1,78 +0,0 @@ -# Gopkg.toml example -# -# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" -# -# [prune] -# non-go = false -# go-tests = true -# unused-packages = true - - -[[constraint]] - name = "cloud.google.com/go" - version = "0.40.0" - -[[constraint]] - name = "contrib.go.opencensus.io/exporter/stackdriver" - version = "0.5.0" - -[[constraint]] - name = "github.com/golang/protobuf" - version = "1.2.0" - -[[constraint]] - name = "github.com/google/uuid" - version = "1.0.0" - -[[constraint]] - name = "github.com/gorilla/mux" - version = "1.6.2" - -[[constraint]] - name = "github.com/pkg/errors" - version = "0.8.0" - -[[constraint]] - name = "github.com/sirupsen/logrus" - version = "1.0.6" - -[[constraint]] - name = "go.opencensus.io" - version = "0.16.0" - -[[constraint]] - name = "go.opentelemetry.io/otel" - version = "^0.9.0" - -[[constraint]] - name = "github.com/GoogleCloudPlatform/opentelemetry-operations-go" - version = ">=0.2.0" - -[[constraint]] - branch = "master" - name = "golang.org/x/net" - -[[constraint]] - name = "google.golang.org/grpc" - version = "1.15.0" - -[prune] - go-tests = true - unused-packages = true diff --git a/src/frontend/README.md b/src/frontend/README.md deleted file mode 100644 index 4e8f72591..000000000 --- a/src/frontend/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# frontend - -Run the following command to restore dependencies to `vendor/` directory: - - dep ensure --vendor-only diff --git a/src/frontend/genproto.sh b/src/frontend/genproto.sh deleted file mode 100755 index b17eebcce..000000000 --- a/src/frontend/genproto.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/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. - -#!/bin/bash -e - -PATH=$PATH:$(go env GOPATH)/bin -protodir=../../pb - -protoc --go_out=genproto --go-grpc-out=genproto -I $protodir $protodir/demo.proto diff --git a/src/frontend/genproto/demo.pb.go b/src/frontend/genproto/demo.pb.go deleted file mode 100644 index 838624d01..000000000 --- a/src/frontend/genproto/demo.pb.go +++ /dev/null @@ -1,2478 +0,0 @@ -// 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 "vintage" or "gardening" 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, -} diff --git a/src/frontend/handlers.go b/src/frontend/handlers.go deleted file mode 100644 index abd622ebc..000000000 --- a/src/frontend/handlers.go +++ /dev/null @@ -1,463 +0,0 @@ -// 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/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" -) - -var ( - templates = template.Must(template.New(""). - Funcs(template.FuncMap{ - "renderMoney": renderMoney, - }).ParseGlob("templates/*.html")) -) - -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 - } - ratings, err := fe.getAllRatings(r.Context()) - if err != nil { - log.WithField("error", err).Error("Cannot retrieve product ratings") - ratings = map[string]float64{} - } - - 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 - Rating float64 - } - 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 - } - rating, found := ratings[p.Id] - if !found { - log.WithField("product", p.Id).Error("Product rating is missing") - rating = 0.0 - } - ps[i] = productView{p, price, rating} - } - - // Feature: convert currency for product to all currencies - if strings.ToLower(os.Getenv("CONVERT_CURRENCIES")) == "true" { - for i := 0; i < 10*len(currencies); i++ { - fe.convertAllCurrencies(r, products, currencies) - } - } - - if err := templates.ExecuteTemplate(w, "home", map[string]interface{}{ - "session_id": sessionID(r), - "request_id": r.Context().Value(ctxKeyRequestID{}), - "user_currency": currentCurrency(r), - "currencies": currencies, - "products": ps, - "cart_size": len(cart), - "banner_color": os.Getenv("BANNER_COLOR"), // illustrates canary deployments - "ad": fe.chooseAd(r.Context(), []string{}, log), - }); err != nil { - log.Error(err) - } -} - -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 - } - - rating, _, err := fe.getRating(r.Context(), id) - if err != nil { - log.WithField("product", id).Error("Product rating is missing") - rating = 0.0 - } - - product := struct { - Item *pb.Product - Price *pb.Money - Rating float64 - }{p, price, rating} - - 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), - "currencies": currencies, - "product": product, - "recommendations": recommendations, - "cart_size": len(cart), - }); 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": len(cart), - "shipping_cost": shippingCost, - "total_cost": totalPrice, - "items": items, - "expiration_years": []int{year, year + 1, year + 2, year + 3, year + 4}, - }); 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() { - totalPaid = money.Must(money.Sum(totalPaid, *v.GetCost())) - } - - if err := templates.ExecuteTemplate(w, "order", map[string]interface{}{ - "session_id": sessionID(r), - "request_id": r.Context().Value(ctxKeyRequestID{}), - "user_currency": currentCurrency(r), - "order": order.GetOrder(), - "total_paid": &totalPaid, - "recommendations": recommendations, - }); err != nil { - log.Println(err) - } -} - -// postNewRatingHandler posts new rating vote for product. -// It ignores the error responses on the vote request since it is not critical. -func (fe *frontendServer) submitRatingHandler(w http.ResponseWriter, r *http.Request) { - log := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger) - productID := mux.Vars(r)["id"] - if productID == "" { - renderHTTPError(log, r, w, errors.New("product id not specified"), http.StatusBadRequest) - return - } - rating, _ := strconv.ParseInt(r.FormValue("rating"), 10, 32) - log.WithField("product", productID).WithField("rating", rating).Debug("vote new rating") - - err := fe.postNewRating(r.Context(), productID, int32(rating)) - if err != nil { - log.WithField("error", err).Warn("failed to post new rating") - } - w.WriteHeader(http.StatusOK) -} - -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))] -} - -// Converts a product's currency to every other currency -// The error is logged as a warning since it is not critical. -func (fe *frontendServer) convertCurrenciesForProduct(r *http.Request, product *pb.Product, currencies []string) { - log := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger) - for _, c := range currencies { - _, err := fe.convertCurrency(r.Context(), product.GetPriceUsd(), c) - if err != nil { - log.WithField("error", err).Warn("Failed converting currencies for products.") - return - } - } -} - -// Converts the currency for all products into every other currency -func (fe *frontendServer) convertAllCurrencies(r *http.Request, products []*pb.Product, currencies []string) { - for _, p := range products { - fe.convertCurrenciesForProduct(r, p, currencies) - } -} - -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) - 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)}) -} - -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 -} - -func renderMoney(money pb.Money) string { - return fmt.Sprintf("%s %d.%02d", money.GetCurrencyCode(), money.GetUnits(), money.GetNanos()/10000000) -} diff --git a/src/frontend/main.go b/src/frontend/main.go deleted file mode 100644 index 1a11312a4..000000000 --- a/src/frontend/main.go +++ /dev/null @@ -1,314 +0,0 @@ -// 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/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" - - // OTel Metric - "go.opentelemetry.io/otel/api/metric" - metricstdout "go.opentelemetry.io/otel/exporters/metric/stdout" - "go.opentelemetry.io/otel/instrumentation/othttp" - "go.opentelemetry.io/otel/sdk/metric/controller/push" - - // OTel Trace - // OTel -> GCP Trace direct exporter for go - texporter "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace" - "go.opentelemetry.io/otel/api/global" - "go.opentelemetry.io/otel/api/standard" - "go.opentelemetry.io/otel/instrumentation/grpctrace" - "go.opentelemetry.io/otel/sdk/resource" - sdktrace "go.opentelemetry.io/otel/sdk/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} - // Custom Metrics for User Dashboard - // TODO: use automatic metrics collection when Views API available in OpenTelemetry - // TODO: remove these after automatically collected - http_request_count metric.Int64Counter - http_response_errors metric.Int64Counter - http_request_latency metric.Int64ValueRecorder -) - -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 - - ratingSvcAddr string -} - -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 - - controller := initMetricsExporter(log) - defer controller.Stop() - - go initProfiling(log, "frontend", "1.0.0") - go initTelemetry(log) - - // TODO: register views when OpenTelemetry Views API is available - meter := controller.Provider().Meter("hipstershop/frontend") - // TODO: use automatic default metrics collection and remove custom metrics - http_request_count = metric.Must(meter).NewInt64Counter("http_request_count") - http_response_errors = metric.Must(meter).NewInt64Counter("http_response_errors") - http_request_latency = metric.Must(meter).NewInt64ValueRecorder("http_request_latency") - tracer := global.TraceProvider().Tracer("hipstershop/frontend") - ctx, span := tracer.Start(ctx, "root") - defer span.End() - - 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") - mustMapEnv(&svc.ratingSvcAddr, "RATING_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.HandleFunc("/product/{id}/rating", svc.submitRatingHandler).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 = othttp.NewHandler(r, "frontend", // OpenTelemetry HTTP wrapper - othttp.WithMessageEvents(othttp.ReadEvents, othttp.WriteEvents)) // Uses global meter and tracer - 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)) -} - -// Initialize OpenTelemetry Metrics exporter -func initMetricsExporter(log logrus.FieldLogger) *push.Controller { - // TODO: export to Cloud Monitoring instead of stdout - pusher, err := metricstdout.InstallNewPipeline(metricstdout.Config{ - PrettyPrint: false, - }) - if err != nil { - log.Panicf("failed to initialize metric stdout exporter %v", err) - } - return pusher -} - -// TODO: remove this after full conversion to OpenTelemetry -func initOpenCensus(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("failed to initialize stackdriver exporter: %+v", err) - } else { - // Register the views to collect server stats. - 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") - } - 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") -} - -// Initialize Telemetry collection (Tracing, Metrics/Stats) with OpenCensus and OpenTelemetry -func initTelemetry(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. - // TODO: Remove OpenCensus after full conversion to OpenTelemetry - trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()}) - initOpenCensus(log) - - // When running on GCP, authentication is handled automatically - // using default credentials. This environment variable check - // is to help debug projects running locally. It's possible for this - // warning to be printed while the exporter works normally. See - // https://developers.google.com/identity/protocols/application-default-credentials - // for more details. - // Initialize exporter OTel Trace -> Google Cloud Trace - projectID := os.Getenv("GOOGLE_CLOUD_PROJECT") - if len(projectID) == 0 { - log.Warn("GOOGLE_CLOUD_PROJECT not set") - } - // Initialize exporter OTel Trace -> GCP Trace - exporter, err := texporter.NewExporter(texporter.WithProjectID(projectID)) - if err != nil { - log.Fatalf("failed to initialize exporter: %v", err) - } - - // Create trace provider with the exporter. - tp, err := sdktrace.NewProvider(sdktrace.WithConfig( - // This is a demo app with low QPS. AlwaysSample() is used here - // to make sure traces are available for observation and analysis. - // It should not be used in production environments. - sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}), - sdktrace.WithSyncer(exporter), - // TODO: replace with predefined constant for GKE or autodetection when available - sdktrace.WithResource(resource.New(standard.ServiceNameKey.String("GKE")))) - if err != nil { - log.Fatal("failed to initialize trace provider: %v", err) - } - global.SetTraceProvider(tp) -} - -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 - *conn, err = grpc.DialContext(ctx, addr, - grpc.WithInsecure(), - grpc.WithTimeout(time.Second*3), - grpc.WithStatsHandler(&ocgrpc.ClientHandler{}), // TODO: replace with OT equivalent when available. - // OpenTelemetry gRPC client channel interceptors pass trace contexts to the server. - grpc.WithUnaryInterceptor(grpctrace.UnaryClientInterceptor(global.TraceProvider().Tracer("frontend"))), - grpc.WithStreamInterceptor(grpctrace.StreamClientInterceptor(global.TraceProvider().Tracer("frontend")))) - if err != nil { - panic(errors.Wrapf(err, "grpc: failed to connect %s", addr)) - } -} diff --git a/src/frontend/middleware.go b/src/frontend/middleware.go deleted file mode 100644 index fa8c644cd..000000000 --- a/src/frontend/middleware.go +++ /dev/null @@ -1,118 +0,0 @@ -// 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" - - "go.opentelemetry.io/otel/api/trace" - "go.opentelemetry.io/otel/api/kv" -) - -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()) - trace.SpanFromContext(ctx).SetAttributes(kv.String("name", r.URL.Path)) - - // TODO: remove when default metrics through Views API are available in OpenTelemetry - http_request_count.Add(ctx, 1) - - 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") - // TODO: remove when default metrics through Views API are available in OpenTelemetry - http_request_latency.Record(ctx, int64(time.Since(start) / time.Millisecond)) - if rr.status != http.StatusOK { - // TODO: remove when default metrics through Views API are available in OpenTelemetry - http_response_errors.Add(ctx, 1) - } - }() - - 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) - } -} diff --git a/src/frontend/money/money.go b/src/frontend/money/money.go deleted file mode 100644 index f1bcc2fe5..000000000 --- a/src/frontend/money/money.go +++ /dev/null @@ -1,132 +0,0 @@ -// 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 -} diff --git a/src/frontend/money/money_test.go b/src/frontend/money/money_test.go deleted file mode 100644 index 643e38ffe..000000000 --- a/src/frontend/money/money_test.go +++ /dev/null @@ -1,245 +0,0 @@ -// 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) - } - }) - } -} diff --git a/src/frontend/rest.go b/src/frontend/rest.go deleted file mode 100644 index 7defd5212..000000000 --- a/src/frontend/rest.go +++ /dev/null @@ -1,166 +0,0 @@ -// 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 -// -// 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. - -package main - -import ( - "bytes" - "context" - "encoding/json" - "io" - "io/ioutil" - "net/http" - "net/url" - "path" - "time" - - "github.com/pkg/errors" -) - -// ErrorResponse describes error response for API call -type ErrorResponse struct { - Error string `json:"error"` -} - -// AllRatingsResponse describes response for GET /ratings -type AllRatingsResponse struct { - Ratings []struct { - ID string `json:"id"` - Rating float64 `json:"rating"` - } `json:"ratings"` -} - -// RatingResponse describes response for GET /rating/ -type RatingResponse struct { - ID string `json:"id"` - Rating float64 `json:"rating"` - Votes int `json:"votes"` -} - -// RatingRequest describes request for POST /rating -type RatingRequest struct { - ID string `json:"id"` - Rating int32 `json:"rating"` -} - -func buildURL(host, resource, id string) (string, error) { - uri, err := url.ParseRequestURI(host) - if err != nil { - return "", errors.Errorf("%q is invalid URL", host) - } - uri.Path = path.Join(uri.Path, resource, id) - return uri.String(), nil -} - -// sendRestRequest abstracts sending GET and POST requests with a timeout, parsing response and error handling. -// It parses the returned Json into response. Any response with code that is not 200 or 4xx results in error. -func sendRestRequest(ctx context.Context, method, url string, payload io.Reader, response interface{}) error { - ctx, cancel := context.WithTimeout(ctx, time.Millisecond*500) - defer cancel() - - req, err := http.NewRequestWithContext(ctx, method, url, payload) - if err != nil { - return errors.Wrapf(err, "failed to create %s request to %s", method, url) - } - if payload != nil { - req.Header.Set("Content-type", "application/json") - } - result, err := http.DefaultClient.Do(req) - if result != nil { - defer result.Body.Close() - } - if err != nil { - return errors.Wrapf(err, "failed to send %s request to %s", method, url) - } - - body, err := ioutil.ReadAll(result.Body) - if err != nil { - return errors.Wrap(err, "failed to read response") - } - - if result.StatusCode >= 400 { - errData := new(ErrorResponse) - err := json.Unmarshal(body, errData) - if err != nil { - return errors.Wrap(err, "json unmarshal failed for : "+string(body)) - } - return errors.Errorf("status: %d, message: %s", result.StatusCode, errData.Error) - } else if result.StatusCode == 200 { - err := json.Unmarshal(body, response) - if err != nil { - return errors.Wrap(err, "json unmarshal failed for : "+string(body)) - } - return nil - } else { - return errors.Errorf("unhandled response code %q", result.StatusCode) - } -} - -// getAllRatings sends GET /ratings request to rating service. -// It returns a map of product ids to ratings. -func (fe *frontendServer) getAllRatings(ctx context.Context) (map[string]float64, error) { - result := make(map[string]float64) - - url, err := buildURL(fe.ratingSvcAddr, "ratings", "") - if err != nil { - return result, err - } - - data := new(AllRatingsResponse) - err = sendRestRequest(ctx, "GET", url, nil, data) - if err != nil { - return result, errors.Wrapf(err, "getAllRatings failed") - } - - for _, r := range data.Ratings { - result[r.ID] = r.Rating - } - return result, nil -} - -// getRating sends GET /rating/ request to rating service where is a product id. -// It returns the rating of the product and the current number of votes. -func (fe *frontendServer) getRating(ctx context.Context, id string) (float64, int, error) { - url, err := buildURL(fe.ratingSvcAddr, "rating", id) - if err != nil { - return 0, 0, err - } - - data := new(RatingResponse) - err = sendRestRequest(ctx, "GET", url, nil, data) - if err != nil { - return 0, 0, errors.Wrapf(err, "getRating for %q failed", id) - } - return data.Rating, data.Votes, nil -} - -// postNewRating sends POST /rating request to rating service to submit a new rating of the product. -// It returns no data because the rating is not updated immediately. -func (fe *frontendServer) postNewRating(ctx context.Context, id string, rating int32) error { - url, err := buildURL(fe.ratingSvcAddr, "rating", "") - if err != nil { - return err - } - - request, err := json.Marshal(RatingRequest{ID: id, Rating: rating}) - if err != nil { - return errors.Wrap(err, "failed serialize request data") - } - data := new(struct{}) - err = sendRestRequest(ctx, "POST", url, bytes.NewBuffer(request), data) - if err != nil { - return errors.Wrapf(err, "post rating %d for %q failed", rating, id) - } - return nil -} diff --git a/src/frontend/rpc.go b/src/frontend/rpc.go deleted file mode 100644 index a1dd31384..000000000 --- a/src/frontend/rpc.go +++ /dev/null @@ -1,127 +0,0 @@ -// 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") -} diff --git a/src/frontend/static/css/styles.css b/src/frontend/static/css/styles.css deleted file mode 100644 index d13c4ee14..000000000 --- a/src/frontend/static/css/styles.css +++ /dev/null @@ -1,31 +0,0 @@ -/** - * 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 - * - * 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. - */ -.rating-5starts { - --percent: calc(var(--rating) / 5 * 100%); - display: inline-block; - font-size: 30px; - font-family: "Comic Sans MS"; - line-height: 1; -} -.rating-5starts::before { - content: '★★★★★'; - letter-spacing: 3px; - background: linear-gradient(90deg, #fc0 var(--percent), #fff var(--percent)); - background-clip: text; - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; -} - diff --git a/src/frontend/static/img/products/air-plant.jpg b/src/frontend/static/img/products/air-plant.jpg deleted file mode 100644 index ac05101dc..000000000 Binary files a/src/frontend/static/img/products/air-plant.jpg and /dev/null differ diff --git a/src/frontend/static/img/products/barista-kit.jpg b/src/frontend/static/img/products/barista-kit.jpg deleted file mode 100644 index cebcfd607..000000000 Binary files a/src/frontend/static/img/products/barista-kit.jpg and /dev/null differ diff --git a/src/frontend/static/img/products/camera-lens.jpg b/src/frontend/static/img/products/camera-lens.jpg deleted file mode 100644 index 63746b1bb..000000000 Binary files a/src/frontend/static/img/products/camera-lens.jpg and /dev/null differ diff --git a/src/frontend/static/img/products/camp-mug.jpg b/src/frontend/static/img/products/camp-mug.jpg deleted file mode 100644 index bb95b110a..000000000 Binary files a/src/frontend/static/img/products/camp-mug.jpg and /dev/null differ diff --git a/src/frontend/static/img/products/city-bike.jpg b/src/frontend/static/img/products/city-bike.jpg deleted file mode 100644 index 74102eba6..000000000 Binary files a/src/frontend/static/img/products/city-bike.jpg and /dev/null differ diff --git a/src/frontend/static/img/products/credits.txt b/src/frontend/static/img/products/credits.txt deleted file mode 100644 index bb488c4c5..000000000 --- a/src/frontend/static/img/products/credits.txt +++ /dev/null @@ -1,9 +0,0 @@ -film-camera.jpg,CC0 Public Domain,https://pxhere.com/en/photo/829555 -camera-lens.jpg,CC0 Public Domain,https://pxhere.com/en/photo/670041 -air-plant.jpg,,https://unsplash.com/photos/uUwEAW5jFLE -camp-mug.jpg,,https://unsplash.com/photos/h9VhRlMfVkg -record-player.jpg,,https://unsplash.com/photos/pEEHFSX1vak -city-bike.jpg,,https://unsplash.com/photos/Lpe9u9etwMU -typewriter.jpg,,https://unsplash.com/photos/mk7D-4UCfmg -barista-kit.jpg,,https://unsplash.com/photos/ZiRyGGIpRCw -terrarium.jpg,,https://unsplash.com/photos/E9QYLj0724Y diff --git a/src/frontend/static/img/products/film-camera.jpg b/src/frontend/static/img/products/film-camera.jpg deleted file mode 100644 index 9d78c3f44..000000000 Binary files a/src/frontend/static/img/products/film-camera.jpg and /dev/null differ diff --git a/src/frontend/static/img/products/record-player.jpg b/src/frontend/static/img/products/record-player.jpg deleted file mode 100644 index e17508817..000000000 Binary files a/src/frontend/static/img/products/record-player.jpg and /dev/null differ diff --git a/src/frontend/static/img/products/terrarium.jpg b/src/frontend/static/img/products/terrarium.jpg deleted file mode 100644 index 84ee200c0..000000000 Binary files a/src/frontend/static/img/products/terrarium.jpg and /dev/null differ diff --git a/src/frontend/static/img/products/typewriter.jpg b/src/frontend/static/img/products/typewriter.jpg deleted file mode 100644 index 127527b2e..000000000 Binary files a/src/frontend/static/img/products/typewriter.jpg and /dev/null differ diff --git a/src/frontend/templates/ad.html b/src/frontend/templates/ad.html deleted file mode 100644 index fe2af19f8..000000000 --- a/src/frontend/templates/ad.html +++ /dev/null @@ -1,26 +0,0 @@ - - -{{ define "text_ad" }} -
- -
-{{ end }} \ No newline at end of file diff --git a/src/frontend/templates/cart.html b/src/frontend/templates/cart.html deleted file mode 100644 index 8d1eccb8a..000000000 --- a/src/frontend/templates/cart.html +++ /dev/null @@ -1,173 +0,0 @@ - - -{{ define "cart" }} - {{ template "header" . }} - -
-
-
- {{ if eq (len $.items) 0 }} -

Your shopping cart is empty!

-

Items you add to your shopping cart will appear here.

- Browse Products → - {{ else }} - -
-
-

{{ len $.items }} item - {{- if gt (len $.items) 1}}s{{end}} - in your Shopping Cart

-
-
-
- - Browse more products → -
- -
-
-
- - {{ range $.items }} -
-
- -
-
- {{.Item.Name}}
- SKU: #{{.Item.Id}} -
-
- Qty: {{.Quantity}}
- - {{ renderMoney .Price}} - -
-
- {{ end }} -
-
-

Shipping Cost: {{ renderMoney .shipping_cost }}

- Total Cost: {{ renderMoney .total_cost }} -
-
- -
-
-
-

Checkout

-
-
-
- - -
-
- - -
-
- - -
- -
-
-
- - -
-
- - -
-
- - -
-
-
-
- - -
-
- - -
-
- - -
-
- - -
-
-
- -
-
-
-
- {{ end }} - - {{ if $.recommendations}} -
- {{ template "recommendations" $.recommendations }} - {{ end }} - -
-
-
- - {{ template "footer" . }} -{{ end }} diff --git a/src/frontend/templates/error.html b/src/frontend/templates/error.html deleted file mode 100644 index 373632085..000000000 --- a/src/frontend/templates/error.html +++ /dev/null @@ -1,36 +0,0 @@ - - -{{ define "error" }} - {{ template "header" . }} - -
-
-
-

Uh, oh!

-

Something has failed. Below are some details for debugging.

- -

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

-
-                    {{- .error -}}
-                
-
-
-
- - {{ template "footer" . }} -{{ end }} diff --git a/src/frontend/templates/footer.html b/src/frontend/templates/footer.html deleted file mode 100644 index 5c445bdbe..000000000 --- a/src/frontend/templates/footer.html +++ /dev/null @@ -1,41 +0,0 @@ - - -{{ define "footer" }} -
-
-

- © 2020 Google Inc - - (Source Code) - -

-

- - This website is hosted for demo purposes only. It is not an - actual shop. This is not an official Google project. - -

- - {{ if $.session_id }}session-id: {{ $.session_id }}
{{end}} - {{ if $.request_id }}request-id: {{ $.request_id }}
{{end}} -
-
-
- - - -{{ end }} diff --git a/src/frontend/templates/header.html b/src/frontend/templates/header.html deleted file mode 100644 index 278374465..000000000 --- a/src/frontend/templates/header.html +++ /dev/null @@ -1,52 +0,0 @@ - - -{{ define "header" }} - - - - - - - - Hipster Shop - - - - -
- -
- - - {{end}} \ No newline at end of file diff --git a/src/frontend/templates/home.html b/src/frontend/templates/home.html deleted file mode 100644 index 6c142aa61..000000000 --- a/src/frontend/templates/home.html +++ /dev/null @@ -1,80 +0,0 @@ - - -{{ define "home" }} - -{{ template "header" . }} -
-
-
-

- One-stop for Hipster Fashion & Style Online -

-

- Tired of mainstream fashion ideas, popular trends and - societal norms? This line of lifestyle products will help - you catch up with the hipster trend and express your - personal style. Start shopping hip and vintage items now! -

-
-
- -
-
-
- {{ range $.products }} -
-
- - - -
-
-
-
- {{ .Item.Name }} -
-
-
-
-
-
-
- - - {{ renderMoney .Price }} - - -
-
-
-
- {{ end }} -
-
- {{ with $.ad }}{{ template "text_ad" . }}{{ end}} -
-
-
-
- -{{ template "footer" . }} - -{{ end }} \ No newline at end of file diff --git a/src/frontend/templates/order.html b/src/frontend/templates/order.html deleted file mode 100644 index 70a744117..000000000 --- a/src/frontend/templates/order.html +++ /dev/null @@ -1,53 +0,0 @@ - - -{{ define "order" }} - {{ template "header" . }} - -
-
-
-
-
-

- Your order is complete! -

-

- Order Confirmation ID: {{.order.OrderId}} -
- Shipping Tracking ID: {{.order.ShippingTrackingId}} -

-

- Shipping Cost: {{renderMoney .order.ShippingCost}} -
- Total Paid: {{renderMoney .total_paid}} -

- Browse other products → -
-
-
- - {{ if $.recommendations }} -
- {{ template "recommendations" $.recommendations }} -
- {{ end }} -
-
-
- - {{ template "footer" . }} -{{ end }} diff --git a/src/frontend/templates/product.html b/src/frontend/templates/product.html deleted file mode 100644 index 5aa773408..000000000 --- a/src/frontend/templates/product.html +++ /dev/null @@ -1,114 +0,0 @@ - - -{{ define "product" }} -{{ template "header" . }} - -
-
-
-
-
- -
-
-
-
-

{{$.product.Item.Name}}

-
-
-
-
-
-

- {{ renderMoney $.product.Price}} -

-
-

-

Product Description:
- {{$.product.Item.Description}} -

-
-
- - -
-
-
-
- -
-
- -
- - -
-
-
-
- - {{ if $.recommendations}} -
- {{ template "recommendations" $.recommendations }} - {{ end }} - - {{ with $.ad }}{{ template "text_ad" . }}{{ end}} -
-
-
-{{ template "footer" . }} - -{{ end }} \ No newline at end of file diff --git a/src/frontend/templates/recommendations.html b/src/frontend/templates/recommendations.html deleted file mode 100644 index 38fc8b960..000000000 --- a/src/frontend/templates/recommendations.html +++ /dev/null @@ -1,37 +0,0 @@ - - -{{ define "recommendations" }} -
Products you might like
-
- {{range . }} -
-
- - - -
- - {{ .Name }} - -
-
-
- {{ end }} -
-{{ end }} diff --git a/src/loadgenerator/Dockerfile b/src/loadgenerator/Dockerfile deleted file mode 100644 index a0c452b17..000000000 --- a/src/loadgenerator/Dockerfile +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2020 Google Inc. All rights reserved. -# -# 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 with a base Python 3.8 image -FROM python:3.8 - -WORKDIR /home - -# Install the required dependencies via pip -COPY requirements.txt . -RUN pip install -r requirements.txt - -# Copy tasks and runner script -COPY run.sh . -COPY *.py ./ -COPY locust_tasks ./locust_tasks - -# Expose the required Locust ports -# - Master Port: 5557 (client locust), 5558 (SRE Recipe locust) -# - Web UI Port: 8089 (client locust), 8090 (SRE Recipe locust) -EXPOSE 5557 5558 8089 8090 - -# Start Locust using LOCUS_OPTS environment variable -ENTRYPOINT ["./run.sh"] diff --git a/src/loadgenerator/README.md b/src/loadgenerator/README.md deleted file mode 100644 index ebd0bae20..000000000 --- a/src/loadgenerator/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# Load Generator - -The Load Generator is implemented in [Locust](https://github.com/locustio/locust) -in library mode. - -## Load Shapes ("Locust Tasks") - -The Locust tasks that specify how to generate loads and traffic pattern to a -target endpoint are implemented in `locust_tasks` package. You can learn more -about how they work [here](https://docs.locust.io/en/stable/writing-a-locustfile.html). - -All the load tasks can be imported with function helpers defined in the `locust_tasks/__init__.py`. - -## SRE Recipe Endpoint - -The `locust_tasks/sre_recipe_load_tasks.py` is a special file containing load tasks used by -SRE Recipes for simulating specific load when certain SRE Recipes are triggered. -You can read more about SRE Recipes in the root `sre-recipes` directory of this -project. - -Specifically, this load generator implementation exposes the client facing load -generator via the `80` port, and a new, independent, hidden load generator -backend at `81` port to be triggered only by SRE Recipes for separation of -concerns. - -The `81` port SRE Recipe Load Generation endpoints implemented so far include: - -- `GET /api/ping`: ping the api for health -- `POST /api/spawn/`: spawn a Locust load generating user - by `user_identifier` at `spawn_rate` users per second, for a total of - `user_count` users. An optional form parameter `stop_after` can be set to - automatically stop all load generating users after a certain number of seconds - has passed. -- `GET /api/user_count`: return the current number of users currently spawned - and are generating loads. -- `POST/api/stop`: stop all load generating users - -Additional endpoints exposed natively by Locust are still available. Please -refer to the [official Locust documentation](https://docs.locust.io/en/stable/index.html) -for details. - -### Extensions - -The SRE Recipe API endpoint for load generation is implemented in Flask. You can -add more request handlers in `sre_recipe_utils.py` with `init_sre_recipe_api` -function. It supports any request handlers supported by [Flask](https://flask.palletsprojects.com/en/1.1.x/quickstart/). diff --git a/src/loadgenerator/app.py b/src/loadgenerator/app.py deleted file mode 100644 index 773ad55ab..000000000 --- a/src/loadgenerator/app.py +++ /dev/null @@ -1,159 +0,0 @@ -# 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. - -# -*- coding: utf-8 -*- -""" -This module contains a Locust app running in library mode. -""" -import sys -import gevent -import traceback - -from locust import HttpUser -from locust import task -from locust.stats import stats_history -from locust.env import Environment - -from absl import app -from absl import flags -FLAGS = flags.FLAGS - -from init import initialize -from sre_recipe_utils import init_sre_recipe_api -from locust_tasks import get_user_classes -from locust_tasks import get_load_shape - -from logger import getJSONLogger -logger = getJSONLogger('locust-server') - -try: - import googleclouddebugger - googleclouddebugger.enable( - module='locust-server', - version='1.0.0' - ) -except ImportError: - logger.warning("Could not enable cloud debugger") - logger.warning(traceback.print_exc()) - pass - - -def setup_locust_environment(host_target, - user_classes, - shape_class, - headless, - web_host, - web_port, - is_master, - master_bind_host, - master_bind_port, - is_worker, - master_host, - master_port, - start_web_ui_now): - # Create a Locust Environment - env = Environment( - host=host_target, user_classes=user_classes, shape_class=shape_class) - - # Setup Locust Runner - if is_master: - if is_worker: - logger.error( - "Locust cannot be started as both a master and a worker") - sys.exit(-1) - env.create_master_runner(master_bind_host, master_bind_port) - logger.info("Created master locust runner") - elif is_worker: - env.create_worker_runner(master_host, master_port) - logger.info("Created worker locust runner") - else: - env.create_local_runner() - logger.info("Created local locust runner") - - # Start a greenlet that periodically saves runner's stats to its history - gevent.spawn(stats_history, env.runner) - - # Only start web UI if it is not headless and not in worker mode - if not headless and not is_worker: - env.create_web_ui(host=web_host, port=web_port, - delayed_start=(not start_web_ui_now)) - - return env - - -def main(argv): - logger.info("Initialing locust in library mode") - - # Setup User Facing Locust Environment - logger.info( - f"Setting up user facing Locust server with {FLAGS.task} tasks") - - env = setup_locust_environment( - host_target=FLAGS.host, - user_classes=get_user_classes(FLAGS.task), - shape_class=get_load_shape(FLAGS.task), - headless=FLAGS.headless, - web_host=FLAGS.web_host, - web_port=FLAGS.web_port, - is_master=FLAGS.master, - master_bind_host=FLAGS.master_bind_host, - master_bind_port=FLAGS.master_bind_port, - is_worker=FLAGS.worker, - master_host=FLAGS.master_host, - master_port=FLAGS.master_port, - start_web_ui_now=True) - - if env.web_ui is not None: - user_facing_web_address = f"http://{FLAGS.web_host}:{FLAGS.web_port}" - logger.info( - f"User facing Locust listening on {user_facing_web_address}") - - # Setup SRE Recipe Facing Locust Environment - logger.info("Setting up SRE Recipe facing Locust server") - env_sre_recipe = setup_locust_environment( - host_target=FLAGS.host, - user_classes=[], - shape_class=None, - # we always need a flask app for SRE Recipe in order to have a functional API - headless=False, - web_host=FLAGS.web_host_sre_recipe, - web_port=FLAGS.web_port_sre_recipe, - is_master=FLAGS.master_sre_recipe, - master_bind_host=FLAGS.master_bind_host_sre_recipe, - master_bind_port=FLAGS.master_bind_port_sre_recipe, - is_worker=FLAGS.worker_sre_recipe, - master_host=FLAGS.master_host_sre_recipe, - master_port=FLAGS.master_port_sre_recipe, - # delay staring the web UI, so we can inject new request handlers - start_web_ui_now=False) - - if env_sre_recipe.web_ui is not None: - init_sre_recipe_api(env_sre_recipe) - - env_sre_recipe.web_ui.start() - - sre_recipe_web_address = ( - f"http://{FLAGS.web_host_sre_recipe}:{FLAGS.web_port_sre_recipe}" - ) - logger.info( - f"SRE Recipe facing Locust listening on {sre_recipe_web_address}") - - # wait for the web app to shutdown - env.runner.greenlet.join() - env_sre_recipe.runner.greenlet.join() - - -if __name__ == '__main__': - initialize() - app.run(main) diff --git a/src/loadgenerator/init.py b/src/loadgenerator/init.py deleted file mode 100644 index 28013b5d9..000000000 --- a/src/loadgenerator/init.py +++ /dev/null @@ -1,101 +0,0 @@ -# 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. - -# -*- coding: utf-8 -*- -""" -This module contains code for initialization logics such as defining command -line flags and arguments. -""" - -from absl import flags - - -def define_user_locust_flags(): - """Flags for user facing Locust server""" - flags.DEFINE_enum('task', 'basic', ['basic', 'step'], - 'The default locust tasks, user types, and load shapes to' - 'spawn for user-facing Locust. It needs to be implemented' - 'in the "locust_tasks" folder. Defaults to basic.') - flags.DEFINE_boolean( - 'headless', False, 'Start user facing Locust without web interface') - flags.DEFINE_string('web_host', "0.0.0.0", - 'Hostname/IP for user facing locust web UI. ' - 'Defaults to 0.0.0.0') - flags.DEFINE_integer('web_port', 8089, - 'Port number that the user facing locust web UI ' - 'will listen to. Defaults to 8089') - - # Redefine command line flags for running locust in distributed mode: - # https://docs.locust.io/en/stable/running-locust-distributed.html - flags.DEFINE_boolean( - 'master', False, 'Running user facing locust as a master runner') - flags.DEFINE_string('master_bind_host', "*", - 'What network interface that the master node will bind ' - 'to for user facing locust server. ' - 'Defaults to *: all available interfaces.') - flags.DEFINE_integer('master_bind_port', 5557, - 'Port number that the master node will listen to for ' - 'user facing locust server. Defaults to 5557.') - - flags.DEFINE_boolean( - 'worker', False, 'Running user facing locust as a worker runner') - flags.DEFINE_string('master_host', "127.0.0.1", - 'Hostname of the master node for user facing locust.' - 'Defaults to 127.0.0.1') - flags.DEFINE_integer('master_port', 5557, - 'Port number of the master for user facing locust.' - 'Defaults to 5557.') - - -def define_sre_recipe_locust_flags(): - """Flags for SRE Recipe facing Locust server""" - flags.DEFINE_string('web_host_sre_recipe', "0.0.0.0", - 'Hostname/IP for SRE Recipe facing locust web UI. ' - 'Defaults to 0.0.0.0') - flags.DEFINE_integer('web_port_sre_recipe', 8090, - 'Port number that the SRE Recipe facing locust web UI ' - 'will listen to. Defaults to 8090') - - # Redefine command line flags for running locust in distributed mode: - # https://docs.locust.io/en/stable/running-locust-distributed.html - flags.DEFINE_boolean( - 'master_sre_recipe', False, - 'Running SRE Recipe facing locust as a master runner') - flags.DEFINE_string('master_bind_host_sre_recipe', "*", - 'What network interface that the master node will bind ' - 'to for SRE Recipe facing locust server. ' - 'Defaults to *: all available interfaces.') - flags.DEFINE_integer('master_bind_port_sre_recipe', 5558, - 'Port number that the master node will listen to for ' - 'SRE Recipe facing locust server. Defaults to 5558.') - - flags.DEFINE_boolean( - 'worker_sre_recipe', False, - 'Running SRE Recipe facing locust as a worker runner') - flags.DEFINE_string('master_host_sre_recipe', "127.0.0.1", - 'Hostname of the master for SRE Recipe facing locust.' - 'Defaults to 127.0.0.1') - flags.DEFINE_integer('master_port_sre_recipe', 5558, - 'Port of the master for SRE Recipe facing locust.' - 'Defaults to 5558.') - - -def initialize(): - """Initialize flags supported by our Locust instance in library mode""" - flags.DEFINE_string('host', None, - 'Base URL of the target system to send load to') - flags.mark_flag_as_required("host") - - define_user_locust_flags() - define_sre_recipe_locust_flags() diff --git a/src/loadgenerator/locust_tasks/__init__.py b/src/loadgenerator/locust_tasks/__init__.py deleted file mode 100644 index 9e63f0ede..000000000 --- a/src/loadgenerator/locust_tasks/__init__.py +++ /dev/null @@ -1,55 +0,0 @@ -# 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 . import basic_locustfile as basic_locust_tasks -from . import step_locustfile as step_locust_tasks -from . import sre_recipe_load_tasks - -USER_FACING_LOCUST_USER_CLASSES = { - "basic": [ - basic_locust_tasks.PurchasingUser, - basic_locust_tasks.WishlistUser, - basic_locust_tasks.BrowsingUser, - ], - "step": [ - step_locust_tasks.PurchasingUser, - step_locust_tasks.WishlistUser, - step_locust_tasks.BrowsingUser, - ] -} - -SRE_RECIPE_USER_CLASSES = { - x.sre_recipe_user_identifier: x - for x in [ - sre_recipe_load_tasks.BasicHomePageViewingUser, - sre_recipe_load_tasks.BasicPurchasingUser, - ] -} - -USER_FACING_LOCUST_LOAD_SHAPE = { - "basic": None, # use default locust shape class - "step": step_locust_tasks.StepLoadShape() -} - - -def get_user_classes(task_type): - return USER_FACING_LOCUST_USER_CLASSES.get(task_type, []) - - -def get_sre_recipe_user_class(user_identifier): - return SRE_RECIPE_USER_CLASSES.get(user_identifier, None) - - -def get_load_shape(task_type): - return USER_FACING_LOCUST_LOAD_SHAPE.get(task_type, None) diff --git a/src/loadgenerator/locust_tasks/basic_locustfile.py b/src/loadgenerator/locust_tasks/basic_locustfile.py deleted file mode 100644 index d0d1d1e1d..000000000 --- a/src/loadgenerator/locust_tasks/basic_locustfile.py +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/env python - -# Copyright 2020 Google Inc. All rights reserved. -# -# 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 task, HttpUser, TaskSet - -products = [ - '0PUK6V6EV0', - '1YMWWN1N4O', - '2ZYFJ3GM2N', - '66VCHSJNUP', - '6E92ZMYYFZ', - '9SIQT8TOJO', - 'L9ECAV7KIM', - 'LS4PSXUNUM', - 'OLJCESPC7Z'] - -currencies = [ - 'EUR', - 'USD', - 'JPY', - 'GBP', - 'TRY', - 'CAD'] - -# Define specific frontend actions. - -@task -def index(l): - l.client.get("/") - -@task -def setCurrency(l): - l.client.post("/setCurrency", - {'currency_code': random.choice(currencies)}) - -@task -def browseProduct(l): - l.client.get("/product/" + random.choice(products)) - -@task -def viewCart(l): - l.client.get("/cart") - -@task -def emptyCart(l): - l.client.post("/cart/empty") - -@task -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])}) - -@task -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', - }) - -# LocustIO TaskSet classes defining detailed user behaviors. - -class PurchasingBehavior(TaskSet): - - def on_start(self): - index(self) - - tasks = {index: 1, - setCurrency: 1, - browseProduct: 2, - addToCart: 2, - viewCart: 1, - checkout: 1} - -class WishlistBehavior(TaskSet): - - def on_start(self): - index(self) - - tasks = {index: 1, - setCurrency: 1, - browseProduct: 5, - addToCart: 10, - viewCart: 5, - emptyCart: 2} - -class BrowsingBehavior(TaskSet): - - def on_start(self): - index(self) - - tasks = {index: 5, - setCurrency: 1, - browseProduct: 10} - -# LocustIO Locust classes defining general user scenarios. - -class PurchasingUser(HttpUser): - ''' - User that browses products, adds to cart, and purchases via checkout. - ''' - tasks = [PurchasingBehavior] - min_wait = 1000 - max_wait = 10000 - -class WishlistUser(HttpUser): - ''' - User that browses products, adds to cart, empties cart, but never purchases. - ''' - tasks = [WishlistBehavior] - min_wait = 1000 - max_wait = 10000 - -class BrowsingUser(HttpUser): - ''' - User that only browses products. - ''' - tasks = [BrowsingBehavior] - min_wait = 1000 - max_wait = 10000 diff --git a/src/loadgenerator/locust_tasks/sre_recipe_load_tasks.py b/src/loadgenerator/locust_tasks/sre_recipe_load_tasks.py deleted file mode 100644 index e28733927..000000000 --- a/src/loadgenerator/locust_tasks/sre_recipe_load_tasks.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python - -# Copyright 2021 Google Inc. All rights reserved. -# -# 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 task, between, HttpUser - - -PRODUCTS = [ - '0PUK6V6EV0', # Vintage Record Player - '1YMWWN1N4O', # Home Barista Kit - '2ZYFJ3GM2N', # Film Camera - '66VCHSJNUP', # Vintage Camera Lens - '6E92ZMYYFZ', # Air Plant - '9SIQT8TOJO', # City Bike - 'L9ECAV7KIM', # Terrarium - 'LS4PSXUNUM', # Metal Camping Mug - 'OLJCESPC7Z', # Vintage Typewriter -] - - -class BasicHomePageViewingUser(HttpUser): - """ - A user that simply visits the home page. - This load pattern is useful for SRE Recipes that want to expose - potential bugs or high page load latency in the frontend. - """ - sre_recipe_user_identifier = "BasicHomePageViewingUser" - - # wait between 1 and 10 seconds after each task - wait_time = between(1, 10) - - @task - def visit_home_page(self): - self.client.get("/") - - -class BasicPurchasingUser(HttpUser): - """ - A user behavior flow that generates loads to simulate the minimal set - of behaviors needed for checkout. This load pattern is useful for SRE - Recipes that want to expose potential bugs in cart and checkout services. - """ - # User Identifier for use by SRE Recipes - sre_recipe_user_identifier = "BasicPurchasingUser" - - # wait between 1 and 10 seconds after each task - wait_time = between(1, 10) - - @task - def buy_random_product_and_checkout(self): - # visit home page - self.client.get("/") - - # add a random product with a random quality to shopping cart - self.client.post("/cart", { - 'product_id': random.choice(PRODUCTS), - 'quantity': random.randint(1, 10) - }) - - # check out - self.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': '1111-1111-1111-1111', - 'credit_card_expiration_month': '1', - 'credit_card_expiration_year': '2039', - 'credit_card_cvv': '672', - }) diff --git a/src/loadgenerator/locust_tasks/step_locustfile.py b/src/loadgenerator/locust_tasks/step_locustfile.py deleted file mode 100644 index 14cd18df7..000000000 --- a/src/loadgenerator/locust_tasks/step_locustfile.py +++ /dev/null @@ -1,170 +0,0 @@ -#!/usr/bin/env python - -# Copyright 2020 Google Inc. All rights reserved. -# -# 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 math -import random -from locust import task, HttpUser, TaskSet, LoadTestShape - -products = [ - '0PUK6V6EV0', - '1YMWWN1N4O', - '2ZYFJ3GM2N', - '66VCHSJNUP', - '6E92ZMYYFZ', - '9SIQT8TOJO', - 'L9ECAV7KIM', - 'LS4PSXUNUM', - 'OLJCESPC7Z'] - -currencies = [ - 'EUR', - 'USD', - 'JPY', - 'GBP', - 'TRY', - 'CAD'] - -# Define specific frontend actions. - -@task -def index(l): - l.client.get("/") - -@task -def setCurrency(l): - l.client.post("/setCurrency", - {'currency_code': random.choice(currencies)}) - -@task -def browseProduct(l): - l.client.get("/product/" + random.choice(products)) - -@task -def viewCart(l): - l.client.get("/cart") - -@task -def emptyCart(l): - l.client.post("/cart/empty") - -@task -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])}) - -@task -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', - }) - -# LocustIO TaskSet classes defining detailed user behaviors. - -class PurchasingBehavior(TaskSet): - - def on_start(self): - index(self) - - tasks = {index: 1, - setCurrency: 1, - browseProduct: 2, - addToCart: 2, - viewCart: 1, - checkout: 1} - -class WishlistBehavior(TaskSet): - - def on_start(self): - index(self) - - tasks = {index: 1, - setCurrency: 1, - browseProduct: 5, - addToCart: 10, - viewCart: 5, - emptyCart: 2} - -class BrowsingBehavior(TaskSet): - - def on_start(self): - index(self) - - tasks = {index: 5, - setCurrency: 1, - browseProduct: 10} - -# LocustIO Locust classes defining general user scenarios. - -class PurchasingUser(HttpUser): - ''' - User that browses products, adds to cart, and purchases via checkout. - ''' - tasks = [PurchasingBehavior] - min_wait = 1000 - max_wait = 10000 - -class WishlistUser(HttpUser): - ''' - User that browses products, adds to cart, empties cart, but never purchases. - ''' - tasks = [WishlistBehavior] - min_wait = 1000 - max_wait = 10000 - -class BrowsingUser(HttpUser): - ''' - User that only browses products. - ''' - tasks = [BrowsingBehavior] - min_wait = 1000 - max_wait = 10000 - -class StepLoadShape(LoadTestShape): - """ - A step load shape - Keyword arguments: - step_time -- Time between steps - step_load -- User increase amount at each step - spawn_rate -- Users to stop/start per second at every step - time_limit -- Time limit in seconds - """ - - step_time = 30 - step_load = 10 - spawn_rate = 10 - time_limit = 300 # 5 minutes = 100 locusts total - - def tick(self): - run_time = self.get_run_time() - - if run_time > self.time_limit: - return None - - current_step = math.floor(run_time / self.step_time) + 1 - return (current_step * self.step_load, self.spawn_rate) diff --git a/src/loadgenerator/logger.py b/src/loadgenerator/logger.py deleted file mode 100644 index da682fa5e..000000000 --- a/src/loadgenerator/logger.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/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) - return logger diff --git a/src/loadgenerator/requirements.in b/src/loadgenerator/requirements.in deleted file mode 100644 index e9ab1c171..000000000 --- a/src/loadgenerator/requirements.in +++ /dev/null @@ -1,3 +0,0 @@ -absl-py==0.12.0 -locust==1.5.1 -python-json-logger==0.1.11 \ No newline at end of file diff --git a/src/loadgenerator/requirements.txt b/src/loadgenerator/requirements.txt deleted file mode 100644 index 93cbfc303..000000000 --- a/src/loadgenerator/requirements.txt +++ /dev/null @@ -1,67 +0,0 @@ -# -# This file is autogenerated by pip-compile -# To update, run: -# -# pip-compile --output-file=requirements.txt requirements.in -# -absl-py==0.12.0 - # via -r requirements.in -certifi==2020.12.5 - # via - # geventhttpclient - # requests -chardet==3.0.4 - # via requests -click==7.1.2 - # via flask -configargparse==1.2.3 - # via locust -flask-basicauth==0.2.0 - # via locust -flask==1.1.4 - # via - # flask-basicauth - # locust -gevent==20.12.1 - # via - # geventhttpclient - # locust -geventhttpclient==1.4.4 - # via locust -greenlet==0.4.17 - # via gevent -idna==2.10 - # via requests -itsdangerous==1.1.0 - # via flask -jinja2==2.11.3 - # via flask -locust==1.5.1 - # via -r requirements.in -markupsafe==1.1.1 - # via jinja2 -msgpack==1.0.0 - # via locust -psutil==5.7.2 - # via locust -python-json-logger==0.1.11 - # via -r requirements.in -pyzmq==19.0.2 - # via locust -requests==2.25.1 - # via locust -six==1.15.0 - # via geventhttpclient -urllib3==1.26.5 - # via requests -werkzeug==1.0.1 - # via - # flask - # locust -zope.event==4.5.0 - # via gevent -zope.interface==5.1.0 - # via gevent - -# The following packages are considered to be unsafe in a requirements file: -# setuptools diff --git a/src/loadgenerator/run.sh b/src/loadgenerator/run.sh deleted file mode 100755 index 0866ef371..000000000 --- a/src/loadgenerator/run.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash - -# Copyright 2020 Google Inc. All rights reserved. -# -# 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. - -# ensure the working dir is the script's folder -SCRIPT_DIR=$(realpath $(dirname "$0")) -cd $SCRIPT_DIR - -LOCUST_MODE=${LOCUST_MODE:-standalone} -LOCUST_TASK=${LOCUST_TASK:-basic} -LOCUS_OPTS="--task=$LOCUST_TASK --host=$TARGET_HOST" - -if [[ "$LOCUST_MODE" = "master" ]]; then - LOCUS_OPTS="$LOCUS_OPTS --master --master_sre_recipe" -elif [[ "$LOCUST_MODE" = "worker" ]]; then - LOCUS_OPTS="$LOCUS_OPTS --worker --master_host=$LOCUST_MASTER" - LOCUS_OPTS="$LOCUS_OPTS --worker_sre_recipe --master_host_sre_recipe=$LOCUST_MASTER" -fi - -echo "python3 app.py $LOCUS_OPTS" - -python3 app.py $LOCUS_OPTS diff --git a/src/loadgenerator/sre_recipe_utils.py b/src/loadgenerator/sre_recipe_utils.py deleted file mode 100644 index 9a212a769..000000000 --- a/src/loadgenerator/sre_recipe_utils.py +++ /dev/null @@ -1,154 +0,0 @@ -# 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. - -# -*- coding: utf-8 -*- -""" -This module contains code for intergrating SRE Recipes with LoadGen -""" - -import time -import gevent -from flask import request -from flask import jsonify -from flask import make_response -from functools import wraps -from locust.env import Environment -from locust_tasks import get_sre_recipe_user_class - - -def return_as_json_response(fn): - """ - Python helper decorator for returning status code and JSON responses from - a Flask request handler. - """ - @wraps(fn) - def wrapper(*args, **kwargs): - try: - body = fn(*args, **kwargs) - resp = make_response(jsonify(body), 200) - resp.headers["Content-Type"] = 'application/json' - return resp - except LookupError as e: - resp = make_response(jsonify({"err": str(e)}), 404) - resp.headers["Content-Type"] = 'application/json' - return resp - except ValueError as e: - resp = make_response(jsonify({"err": str(e)}), 400) - resp.headers["Content-Type"] = 'application/json' - return resp - except Exception as e: - resp = make_response(jsonify({"err": str(e)}), 500) - resp.headers["Content-Type"] = 'application/json' - return resp - - return wrapper - - -def init_sre_recipe_api(env): - """ - Attach custom Flask request handlers to a locust environment's flask app - """ - if env and env.web_ui: - @env.web_ui.app.route("/api/ping") - @return_as_json_response - def ping(): - return {"msg": "pong"} - - @env.web_ui.app.route("/api/user_count") - @return_as_json_response - def user_count(): - """ - Return the number of total users spawend for load generation. - - Response: - - user_count: int - """ - return {"user_count": env.runner.user_count} - - @env.web_ui.app.route("/api/spawn/", methods=['POST']) - @return_as_json_response - def spawn_by_user_identifier(user_identifier=None): - """ - Spawn a number of users with the SRE Recipe user identifer. - - Form Paramters: - - user_count: Required. The total number of users to spawn - - spawn_rate: Required. The spawn rate for the users. - - stop_after: Optional. If specified, run the load generation only - for the given number of seconds. - - Response: - On success, returns status code 200 and an acknowledgement 'msg' - On error, returns status code 400 for invalid arguments, and 404 - if load pattern for 'user_identifier' is not found, as well as an - 'err' message. - """ - # Required Query Parameters - user_count = request.form.get("user_count", default=None, type=int) - spawn_rate = request.form.get("spawn_rate", default=None, type=int) - # The function returns None, if user_identifier is not found - user_class = get_sre_recipe_user_class(user_identifier) - - - if user_count is None: - raise ValueError(f"Must specify a valid, non-empty, integer value for query parameter 'user_count': {request.form.get('user_count', default=None)}") - elif spawn_rate is None: - raise ValueError(f"Must specify a valid, non-empty, integer value for query parameter 'spawn_rate': {request.form.get('spawn_rate', default=None)}") - elif user_count <= 0: - raise ValueError(f"Query parameter 'user_count' must be positive: {user_count}") - elif spawn_rate <= 0: - raise ValueError(f"Query parameter 'spawn_rate' must be positive: {spawn_rate}") - elif user_class is None: - raise LookupError(f"Cannot find SRE Recipe Load for: {user_identifier}") - - # Optional Query Parameters - stop_after = request.form.get("stop_after", default=None, type=int) - if stop_after is not None and stop_after <= 0: - raise ValueError(f"Query parameter 'stop_after' must be positive: {stop_after}") - elif stop_after is None and "stop_after" in request.form: - raise ValueError(f"stop_after must be valid integer value: {request.form['stop_after']}") - - # We currently only support running one SRE Recipe load each time - # for implementation simplicity. - if env.runner.user_count > 0: - env.runner.quit() # stop existing load generating users, if any - env.user_classes = [user_class] # replace with the new users - - def spawn_when_all_users_stopped(): - # Wait at most 10 seconds until all existing users are stopped, then - # start generating new load with the new user types - tries = 0 - while tries < 10: - if env.runner.user_count == 0: - env.runner.start(user_count, spawn_rate) - break - tries += 1 - time.sleep(1) - # Start anyway. - if tries == 10: - env.runner.start(user_count, spawn_rate) - # Stop later if applicable - if stop_after: - gevent.spawn_later(stop_after, - lambda: env.runner.quit()) - - gevent.spawn(spawn_when_all_users_stopped); - return {"msg": f"Spawn Request Received: spawning {user_count} users at {spawn_rate} users/second"} - - @env.web_ui.app.route("/api/stop", methods=['POST']) - @return_as_json_response - def stop_all(): - """Stop all currently running users""" - env.runner.quit() - return {"msg": "All users stopped"} diff --git a/src/paymentservice/.dockerignore b/src/paymentservice/.dockerignore deleted file mode 100644 index 3c3629e64..000000000 --- a/src/paymentservice/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/src/paymentservice/.gitignore b/src/paymentservice/.gitignore deleted file mode 100644 index fd4f2b066..000000000 --- a/src/paymentservice/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -.DS_Store diff --git a/src/paymentservice/Dockerfile b/src/paymentservice/Dockerfile deleted file mode 100644 index 1d45be452..000000000 --- a/src/paymentservice/Dockerfile +++ /dev/null @@ -1,45 +0,0 @@ -# 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:12-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.3.5 && \ - 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" ] diff --git a/src/paymentservice/Gopkg.lock b/src/paymentservice/Gopkg.lock deleted file mode 100644 index bef2d0092..000000000 --- a/src/paymentservice/Gopkg.lock +++ /dev/null @@ -1,9 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "ab4fef131ee828e96ba67d31a7d690bd5f2f42040c6766b1b12fe856f87e0ff7" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/src/paymentservice/Gopkg.toml b/src/paymentservice/Gopkg.toml deleted file mode 100644 index d7072c225..000000000 --- a/src/paymentservice/Gopkg.toml +++ /dev/null @@ -1,30 +0,0 @@ -# Gopkg.toml example -# -# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" -# -# [prune] -# non-go = false -# go-tests = true -# unused-packages = true - - -[prune] - go-tests = true - unused-packages = true diff --git a/src/paymentservice/charge.js b/src/paymentservice/charge.js deleted file mode 100644 index ce9674a6c..000000000 --- a/src/paymentservice/charge.js +++ /dev/null @@ -1,83 +0,0 @@ -// 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() }; -}; diff --git a/src/paymentservice/genproto.sh b/src/paymentservice/genproto.sh deleted file mode 100755 index a9609fd15..000000000 --- a/src/paymentservice/genproto.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/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. - -# protos are loaded dynamically for node, simply copies over the proto. -mkdir -p proto -cp -r ../../pb/* ./proto diff --git a/src/paymentservice/index.js b/src/paymentservice/index.js deleted file mode 100644 index 0d33ca852..000000000 --- a/src/paymentservice/index.js +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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'; - -require('@google-cloud/profiler').start({ - serviceContext: { - service: 'paymentservice', - } -}); -require('@google-cloud/debug-agent').start({ - serviceContext: { - service: 'paymentservice', - } -}); - -const path = require('path'); -const tracer = require('./tracer')(); -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(); diff --git a/src/paymentservice/package-lock.json b/src/paymentservice/package-lock.json deleted file mode 100644 index f0d481ef2..000000000 --- a/src/paymentservice/package-lock.json +++ /dev/null @@ -1,3391 +0,0 @@ -{ - "name": "paymentservice", - "version": "0.0.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.14.5" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", - "dev": true - }, - "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - } - } - }, - "@eslint/eslintrc": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz", - "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "lodash": "^4.17.19", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - } - }, - "@google-cloud/common": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.6.0.tgz", - "integrity": "sha512-aHIFTqJZmeTNO9md8XxV+ywuvXF3xBm5WNmgWeeCK+XN5X+kGW0WEX94wGwj+/MdOnrVf4dL2RvSIt9J5yJG6Q==", - "requires": { - "@google-cloud/projectify": "^2.0.0", - "@google-cloud/promisify": "^2.0.0", - "arrify": "^2.0.1", - "duplexify": "^4.1.1", - "ent": "^2.2.0", - "extend": "^3.0.2", - "google-auth-library": "^7.0.2", - "retry-request": "^4.1.1", - "teeny-request": "^7.0.0" - } - }, - "@google-cloud/debug-agent": { - "version": "5.2.6", - "resolved": "https://registry.npmjs.org/@google-cloud/debug-agent/-/debug-agent-5.2.6.tgz", - "integrity": "sha512-I7wnOUOJwf94CwFWXcoWcWC5Olv+YlxzklXPpqZcyDBrZumhmdglVVdx8UGqA4uzfypft+tIh+dhAIeX89Tu+Q==", - "requires": { - "@google-cloud/common": "^3.0.0", - "acorn": "^8.0.0", - "coffeescript": "^2.0.0", - "console-log-level": "^1.4.0", - "extend": "^3.0.2", - "findit2": "^2.2.3", - "gcp-metadata": "^4.0.0", - "p-limit": "^3.0.1", - "semver": "^7.0.0", - "source-map": "^0.7.3", - "split": "^1.0.0" - } - }, - "@google-cloud/opentelemetry-cloud-trace-exporter": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@google-cloud/opentelemetry-cloud-trace-exporter/-/opentelemetry-cloud-trace-exporter-0.9.0.tgz", - "integrity": "sha512-4tFC7dgLQIxeq/9jTqMLmoWJBn/72Hn5Eth60HJTsMNd/0oDV7+hdki2z0WS/0cc+bPthCpoppHCrWw1DYpTbw==", - "requires": { - "@grpc/grpc-js": "^1.1.8", - "@grpc/proto-loader": "^0.5.5", - "google-auth-library": "^7.0.0", - "google-proto-files": "^2.1.0" - }, - "dependencies": { - "@grpc/proto-loader": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.5.6.tgz", - "integrity": "sha512-DT14xgw3PSzPxwS13auTEwxhMMOoz33DPUKNtmYK/QYbBSpLXJy78FGGs5yVoxVobEqPm4iW9MOIoz0A3bLTRQ==", - "requires": { - "lodash.camelcase": "^4.3.0", - "protobufjs": "^6.8.6" - } - } - } - }, - "@google-cloud/profiler": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@google-cloud/profiler/-/profiler-4.1.2.tgz", - "integrity": "sha512-h/UOb6vTm9ozKjdgA2OxV86Yk1GFS0Mq+29Eeo2rdovI5zK+139Yt+eYAgDQNBJxrAPmj4ZZKHb7G6gPIGJJeQ==", - "requires": { - "@google-cloud/common": "^3.0.0", - "@types/console-log-level": "^1.4.0", - "@types/semver": "^7.0.0", - "console-log-level": "^1.4.0", - "delay": "^5.0.0", - "extend": "^3.0.2", - "gcp-metadata": "^4.0.0", - "parse-duration": "^1.0.0", - "pprof": "3.1.0", - "pretty-ms": "^7.0.0", - "protobufjs": "~6.11.0", - "semver": "^7.0.0", - "teeny-request": "^7.0.0" - } - }, - "@google-cloud/projectify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.1.0.tgz", - "integrity": "sha512-qbpidP/fOvQNz3nyabaVnZqcED1NNzf7qfeOlgtAZd9knTwY+KtsGRkYpiQzcATABy4gnGP2lousM3S0nuWVzA==" - }, - "@google-cloud/promisify": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.3.tgz", - "integrity": "sha512-d4VSA86eL/AFTe5xtyZX+ePUjE8dIFu2T8zmdeNBSa5/kNgXPCx/o/wbFNHAGLJdGnk1vddRuMESD9HbOC8irw==" - }, - "@grpc/grpc-js": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.4.tgz", - "integrity": "sha512-AxtZcm0mArQhY9z8T3TynCYVEaSKxNCa9mVhVwBCUnsuUEe8Zn94bPYYKVQSLt+hJJ1y0ukr3mUvtWfcATL/IQ==", - "requires": { - "@types/node": ">=12.12.47" - } - }, - "@grpc/proto-loader": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.4.tgz", - "integrity": "sha512-7xvDvW/vJEcmLUltCUGOgWRPM8Oofv0eCFSVMuKqaqWJaXSzmB+m9hiyqe34QofAl4WAzIKUZZlinIF9FOHyTQ==", - "requires": { - "@types/long": "^4.0.1", - "lodash.camelcase": "^4.3.0", - "long": "^4.0.0", - "protobufjs": "^6.10.0", - "yargs": "^16.1.1" - } - }, - "@mapbox/node-pre-gyp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz", - "integrity": "sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA==", - "requires": { - "detect-libc": "^1.0.3", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.1", - "nopt": "^5.0.0", - "npmlog": "^4.1.2", - "rimraf": "^3.0.2", - "semver": "^7.3.4", - "tar": "^6.1.0" - } - }, - "@opentelemetry/api": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-0.11.0.tgz", - "integrity": "sha512-K+1ADLMxduhsXoZ0GRfi9Pw162FvzBQLDQlHru1lg86rpIU+4XqdJkSGo6y3Kg+GmOWq1HNHOA/ydw/rzHQkRg==", - "requires": { - "@opentelemetry/context-base": "^0.11.0" - } - }, - "@opentelemetry/context-async-hooks": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-0.11.0.tgz", - "integrity": "sha512-4z0X9EfvoLNA6R5yi+2taUyaSCUiyi/ht1qBYZMgpWvWwARgc5hcgGkZo7bekPk1zWfE9NFIhW6ySOXOP9CXyQ==", - "requires": { - "@opentelemetry/context-base": "^0.11.0" - } - }, - "@opentelemetry/context-base": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/context-base/-/context-base-0.11.0.tgz", - "integrity": "sha512-ESRk+572bftles7CVlugAj5Azrz61VO0MO0TS2pE9MLVL/zGmWuUBQryART6/nsrFqo+v9HPt37GPNcECTZR1w==" - }, - "@opentelemetry/core": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-0.11.0.tgz", - "integrity": "sha512-ZEKjBXeDGBqzouz0uJmrbEKNExEsQOhsZ3tJDCLcz5dUNoVw642oIn2LYWdQK2YdIfZbEmltiF65/csGsaBtFA==", - "requires": { - "@opentelemetry/api": "^0.11.0", - "@opentelemetry/context-base": "^0.11.0", - "semver": "^7.1.3" - } - }, - "@opentelemetry/node": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/node/-/node-0.11.0.tgz", - "integrity": "sha512-1SrZNbF7aBShySvsmWL+3bir6fVugjSnCyXsKMwclinhZIHd2cUfgjKdi42OCcA5G4Pp8TpO7/8ue8qI5yKX8w==", - "requires": { - "@opentelemetry/api": "^0.11.0", - "@opentelemetry/context-async-hooks": "^0.11.0", - "@opentelemetry/core": "^0.11.0", - "@opentelemetry/tracing": "^0.11.0", - "require-in-the-middle": "^5.0.0", - "semver": "^7.1.3" - } - }, - "@opentelemetry/plugin-grpc": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/plugin-grpc/-/plugin-grpc-0.11.0.tgz", - "integrity": "sha512-9MmLROXWJrpNWhnizpIZZj9GzAoH4MSTcroZxcIcFM5H1lKpyBmnEXqwpkuZ2q4WM7YvCPRrMUqRwg+znK7q2g==", - "requires": { - "@opentelemetry/api": "^0.11.0", - "@opentelemetry/core": "^0.11.0", - "@opentelemetry/semantic-conventions": "^0.11.0", - "shimmer": "^1.2.1" - } - }, - "@opentelemetry/resources": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-0.11.0.tgz", - "integrity": "sha512-o7DwV1TcezqBtS5YW2AWBcn01nVpPptIbTr966PLlVBcS//w8LkjeOShiSZxQ0lmV4b2en0FiSouSDoXk/5qIQ==", - "requires": { - "@opentelemetry/api": "^0.11.0", - "@opentelemetry/core": "^0.11.0" - } - }, - "@opentelemetry/semantic-conventions": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-0.11.0.tgz", - "integrity": "sha512-xsthnI/J+Cx0YVDGgUzvrH0ZTtfNtl866M454NarYwDrc0JvC24sYw+XS5PJyk2KDzAHtb0vlrumUc1OAut/Fw==" - }, - "@opentelemetry/tracing": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/tracing/-/tracing-0.11.0.tgz", - "integrity": "sha512-QweFmxzl32BcyzwdWCNjVXZT1WeENNS/RWETq/ohqu+fAsTcMyGcr6cOq/yDdFmtBy+bm5WVVdeByEjNS+c4/w==", - "requires": { - "@opentelemetry/api": "^0.11.0", - "@opentelemetry/context-base": "^0.11.0", - "@opentelemetry/core": "^0.11.0", - "@opentelemetry/resources": "^0.11.0", - "@opentelemetry/semantic-conventions": "^0.11.0" - } - }, - "@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" - }, - "@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" - }, - "@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", - "requires": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" - }, - "@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" - }, - "@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" - }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" - }, - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" - }, - "@types/bytebuffer": { - "version": "5.0.42", - "resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.42.tgz", - "integrity": "sha512-lEgKojWUAc/MG2t649oZS5AfYFP2xRNPoDuwDBlBMjHXd8MaGPgFgtCXUK7inZdBOygmVf10qxc1Us8GXC96aw==", - "requires": { - "@types/long": "*", - "@types/node": "*" - } - }, - "@types/console-log-level": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@types/console-log-level/-/console-log-level-1.4.2.tgz", - "integrity": "sha512-TnhDAntcJthcCMrR3OAKAUjgHyQgoms1yaBJepGv+BtXi8PLf8aX2L/NMCfofRTpVqW0bLklpGTsuqmUSCR2Uw==" - }, - "@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" - }, - "@types/node": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.0.1.tgz", - "integrity": "sha512-hBOx4SUlEPKwRi6PrXuTGw1z6lz0fjsibcWCM378YxsSu/6+C30L6CR49zIBKHiwNWCYIcOLjg4OHKZaFeLAug==" - }, - "@types/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-4g1jrL98mdOIwSOUh6LTlB0Cs9I0dQPwINUhBg7C6pN4HLr8GS8xsksJxilW6S6dQHVi2K/o+lQuQcg7LroCnw==" - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==" - }, - "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "requires": { - "debug": "4" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-includes": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", - "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.5" - } - }, - "array.prototype.flat": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", - "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - } - }, - "array.prototype.flatmap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", - "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "function-bind": "^1.1.1" - } - }, - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==" - }, - "ascli": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz", - "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=", - "requires": { - "colour": "~0.7.1", - "optjs": "~3.2.2" - } - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true - }, - "atomic-sleep": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", - "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==" - }, - "axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", - "requires": { - "follow-redirects": "^1.10.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==" - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "bytebuffer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", - "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", - "requires": { - "long": "~3" - }, - "dependencies": { - "long": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", - "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=" - } - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, - "coffeescript": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.5.1.tgz", - "integrity": "sha512-J2jRPX0eeFh5VKyVnoLrfVFgLZtnnmp96WQSLAS8OrLm2wtQLcnikYKe1gViJKDH7vucjuhHvBKKBP3rKcD1tQ==" - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "colour": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz", - "integrity": "sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g=" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" - }, - "console-log-level": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/console-log-level/-/console-log-level-1.4.1.tgz", - "integrity": "sha512-VZzbIORbP+PPcN/gg3DXClTLPLg5Slwd5fL2MIc+o1qZ4BXBvWyc6QxPk6T/Mkr6IVjRpoAGf32XxP3ZWMVRcQ==" - }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "requires": { - "ms": "2.1.2" - } - }, - "debug-log": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/debug-log/-/debug-log-1.0.1.tgz", - "integrity": "sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8=", - "dev": true - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "deglob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/deglob/-/deglob-4.0.1.tgz", - "integrity": "sha512-/g+RDZ7yf2HvoW+E5Cy+K94YhgcFgr6C8LuHZD1O5HoNPkf3KY6RfXJ0DBGlB/NkLi5gml+G9zqRzk9S0mHZCg==", - "dev": true, - "requires": { - "find-root": "^1.0.0", - "glob": "^7.0.5", - "ignore": "^5.0.0", - "pkg-config": "^1.1.0", - "run-parallel": "^1.1.2", - "uniq": "^1.0.1" - }, - "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - } - } - }, - "delay": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", - "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==" - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "duplexify": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", - "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", - "requires": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "requires": { - "once": "^1.4.0" - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=" - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", - "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.3", - "is-string": "^1.0.6", - "object-inspect": "^1.10.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.12.1.tgz", - "integrity": "sha512-HlMTEdr/LicJfN08LB3nM1rRYliDXOmfoO4vj39xN6BLpFzF00hbwBoqHk8UcJ2M/3nlARZWy/mslvGEuZFvsg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@eslint/eslintrc": "^0.2.1", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.0", - "esquery": "^1.2.0", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash": "^4.17.19", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, - "eslint-config-semistandard": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/eslint-config-semistandard/-/eslint-config-semistandard-15.0.1.tgz", - "integrity": "sha512-sfV+qNBWKOmF0kZJll1VH5XqOAdTmLlhbOl9WKI11d2eMEe+Kicxnpm24PQWHOqAfk5pAWU2An0LjNCXKa4Usg==", - "dev": true - }, - "eslint-config-standard": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-15.0.1.tgz", - "integrity": "sha512-UGorkix49kBium7Y124o2U9Qy7Lpa+nO0FsaqQSIPeno5hGNxZtSBJbqJX6gtpYfDFWCtqCAN9wyK+oDd9jT7Q==", - "dev": true - }, - "eslint-config-standard-jsx": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-9.0.0.tgz", - "integrity": "sha512-e9ezaClB5YdTYqGUd3wReKC1si8XRn234tmME+3qebQ+KHtH92B6dr4LE6qPjK9AYe9XfwDK/xgQSwyCKQwv5Q==", - "dev": true - }, - "eslint-import-resolver-node": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", - "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", - "dev": true, - "requires": { - "debug": "^2.6.9", - "resolve": "^1.13.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-module-utils": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz", - "integrity": "sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "pkg-dir": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", - "dev": true, - "requires": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" - } - }, - "eslint-plugin-import": { - "version": "2.22.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", - "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==", - "dev": true, - "requires": { - "array-includes": "^3.1.1", - "array.prototype.flat": "^1.2.3", - "contains-path": "^0.1.0", - "debug": "^2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.4", - "eslint-module-utils": "^2.6.0", - "has": "^1.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.1", - "read-pkg-up": "^2.0.0", - "resolve": "^1.17.0", - "tsconfig-paths": "^3.9.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", - "dev": true, - "requires": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" - }, - "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "eslint-plugin-promise": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz", - "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==", - "dev": true - }, - "eslint-plugin-react": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.21.5.tgz", - "integrity": "sha512-8MaEggC2et0wSF6bUeywF7qQ46ER81irOdWS4QWxnnlAEsnzeBevk1sWh7fhpCghPpXb+8Ks7hvaft6L/xsR6g==", - "dev": true, - "requires": { - "array-includes": "^3.1.1", - "array.prototype.flatmap": "^1.2.3", - "doctrine": "^2.1.0", - "has": "^1.0.3", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "object.entries": "^1.1.2", - "object.fromentries": "^2.0.2", - "object.values": "^1.1.1", - "prop-types": "^15.7.2", - "resolve": "^1.18.1", - "string.prototype.matchall": "^4.0.2" - }, - "dependencies": { - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - } - } - }, - "eslint-plugin-standard": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.2.tgz", - "integrity": "sha512-nKptN8l7jksXkwFk++PhJB3cCDTcXOEyhISIN86Ue2feJ1LFyY3PrY3/xT2keXlJSY5bpmbiTG0f885/YKAvTA==", - "dev": true - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fast-redact": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-2.1.0.tgz", - "integrity": "sha512-0LkHpTLyadJavq9sRzzyqIoMZemWli77K2/MGOkafrR64B9ItrvZ9aT+jluvNDsv0YEHjSNhlMBtbokuoqii4A==" - }, - "fast-safe-stringify": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", - "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" - }, - "fast-text-encoding": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", - "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==" - }, - "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, - "requires": { - "flat-cache": "^2.0.1" - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "dev": true - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "findit2": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz", - "integrity": "sha1-WKRmaX34piBc39vzlVNri9d3pfY=" - }, - "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "dependencies": { - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "flatstr": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/flatstr/-/flatstr-1.0.12.tgz", - "integrity": "sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw==" - }, - "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "follow-redirects": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", - "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==" - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "requires": { - "minipass": "^3.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "gaxios": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.0.tgz", - "integrity": "sha512-pHplNbslpwCLMyII/lHPWFQbJWOX0B3R1hwBEOvzYi1GmdKZruuEHK4N9V6f7tf1EaPYyF80mui1+344p6SmLg==", - "requires": { - "abort-controller": "^3.0.0", - "extend": "^3.0.2", - "https-proxy-agent": "^5.0.0", - "is-stream": "^2.0.0", - "node-fetch": "^2.3.0" - } - }, - "gcp-metadata": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.3.0.tgz", - "integrity": "sha512-L9XQUpvKJCM76YRSmcxrR4mFPzPGsgZUH+GgHMxAET8qc6+BhRJq63RLhWakgEO2KKVgeSDVfyiNjkGSADwNTA==", - "requires": { - "gaxios": "^4.0.0", - "json-bigint": "^1.0.0" - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", - "dev": true - }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "dev": true, - "requires": { - "type-fest": "^0.8.1" - } - }, - "google-auth-library": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.3.0.tgz", - "integrity": "sha512-MPeeMlnsYnoiiVFMwX3hgaS684aiXrSqKoDP+xL4Ejg4Z0qLvIeg4XsaChemyFI8ZUO7ApwDAzNtgmhWSDNh5w==", - "requires": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - } - }, - "google-p12-pem": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.0.tgz", - "integrity": "sha512-JUtEHXL4DY/N+xhlm7TC3qL797RPAtk0ZGXNs3/gWyiDHYoA/8Rjes0pztkda+sZv4ej1EoO2KhWgW5V9KTrSQ==", - "requires": { - "node-forge": "^0.10.0" - } - }, - "google-proto-files": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/google-proto-files/-/google-proto-files-2.4.0.tgz", - "integrity": "sha512-M5u56EsADOnplBUHTBzqBcCtPNPoGtBBXefjtA7mt3KDsOnlRM75fwrW2rsPS3Am2vrf9I0/NlI0E3nKWo/Ipg==", - "requires": { - "protobufjs": "^6.8.0", - "walkdir": "^0.4.0" - } - }, - "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", - "dev": true - }, - "grpc": { - "version": "1.24.10", - "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.24.10.tgz", - "integrity": "sha512-mTR+P5IL3WO3oCgNwxKFE5ksXEJfCYP+dk0aIbjB494f7OnHTmssU5r9vznsSq3+cdLcxAzGFskOj5CaPwi8KA==", - "requires": { - "@mapbox/node-pre-gyp": "^1.0.4", - "@types/bytebuffer": "^5.0.40", - "lodash.camelcase": "^4.3.0", - "lodash.clone": "^4.5.0", - "nan": "^2.13.2", - "protobufjs": "^5.0.3" - }, - "dependencies": { - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "protobufjs": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.3.tgz", - "integrity": "sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==", - "requires": { - "ascli": "~1", - "bytebuffer": "~5", - "glob": "^7.0.5", - "yargs": "^3.10.0" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==" - }, - "yargs": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", - "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", - "requires": { - "camelcase": "^2.0.1", - "cliui": "^3.0.3", - "decamelize": "^1.1.1", - "os-locale": "^1.4.0", - "string-width": "^1.0.1", - "window-size": "^0.1.4", - "y18n": "^3.2.0" - } - } - } - }, - "gtoken": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.3.0.tgz", - "integrity": "sha512-mCcISYiaRZrJpfqOs0QWa6lfEM/C1V9ASkzFmuz43XBb5s1Vynh+CZy1ECeeJXVGx2PRByjYzb4Y4/zr1byr0w==", - "requires": { - "gaxios": "^4.0.0", - "google-p12-pem": "^3.0.3", - "jws": "^4.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - } - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-bigint": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", - "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", - "dev": true - }, - "is-boolean-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", - "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", - "dev": true - }, - "is-core-module": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", - "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "dev": true - }, - "is-number-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", - "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", - "dev": true - }, - "is-regex": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", - "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.2" - } - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" - }, - "is-string": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", - "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", - "dev": true - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "requires": { - "bignumber.js": "^9.0.0" - } - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "jsx-ast-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", - "integrity": "sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==", - "dev": true, - "requires": { - "array-includes": "^3.1.2", - "object.assign": "^4.1.2" - } - }, - "jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "requires": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "requires": { - "invert-kv": "^1.0.0" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" - }, - "lodash.clone": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", - "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=" - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "minipass": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", - "requires": { - "yallist": "^4.0.0" - } - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - }, - "module-details-from-path": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nan": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" - }, - "node-forge": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", - "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" - }, - "nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-inspect": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", - "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.entries": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.4.tgz", - "integrity": "sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.2" - } - }, - "object.fromentries": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz", - "integrity": "sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "has": "^1.0.3" - } - }, - "object.values": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", - "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.2" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "optjs": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", - "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=" - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "requires": { - "lcid": "^1.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - }, - "dependencies": { - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - } - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-duration": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-1.0.0.tgz", - "integrity": "sha512-X4kUkCTHU1N/kEbwK9FpUJ0UZQa90VzeczfS704frR30gljxDG0pSziws06XlK+CGRSo/1wtG1mFIdBFQTMQNw==" - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "parse-ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", - "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==" - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "pify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", - "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==" - }, - "pino": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/pino/-/pino-5.17.0.tgz", - "integrity": "sha512-LqrqmRcJz8etUjyV0ddqB6OTUutCgQULPFg2b4dtijRHUsucaAdBgSUW58vY6RFSX+NT8963F+q0tM6lNwGShA==", - "requires": { - "fast-redact": "^2.0.0", - "fast-safe-stringify": "^2.0.7", - "flatstr": "^1.0.12", - "pino-std-serializers": "^2.4.2", - "quick-format-unescaped": "^3.0.3", - "sonic-boom": "^0.7.5" - } - }, - "pino-std-serializers": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-2.5.0.tgz", - "integrity": "sha512-wXqbqSrIhE58TdrxxlfLwU9eDhrzppQDvGhBEr1gYbzzM4KKo3Y63gSjiDXRKLVS2UOXdPNR2v+KnQgNrs+xUg==" - }, - "pkg-conf": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz", - "integrity": "sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ==", - "dev": true, - "requires": { - "find-up": "^3.0.0", - "load-json-file": "^5.2.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "load-json-file": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", - "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.15", - "parse-json": "^4.0.0", - "pify": "^4.0.1", - "strip-bom": "^3.0.0", - "type-fest": "^0.3.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "type-fest": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", - "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", - "dev": true - } - } - }, - "pkg-config": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pkg-config/-/pkg-config-1.1.1.tgz", - "integrity": "sha1-VX7yLXPaPIg3EHdmxS6tq94pj+Q=", - "dev": true, - "requires": { - "debug-log": "^1.0.0", - "find-root": "^1.0.0", - "xtend": "^4.0.1" - } - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - }, - "pprof": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pprof/-/pprof-3.1.0.tgz", - "integrity": "sha512-nbYfVzZYQ/TPV9QZFPMb59FRZrIe4M4FTruH11+vd4gR5cGUG3dfoXpXdfki50eeVeqWQrXuWdUsrRIZi2SteQ==", - "requires": { - "@mapbox/node-pre-gyp": "^1.0.0", - "bindings": "^1.2.1", - "delay": "^5.0.0", - "findit2": "^2.2.3", - "nan": "^2.14.0", - "p-limit": "^3.0.0", - "pify": "^5.0.0", - "protobufjs": "~6.10.0", - "source-map": "^0.7.3", - "split": "^1.0.1" - }, - "dependencies": { - "@types/node": { - "version": "13.13.52", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", - "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==" - }, - "protobufjs": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz", - "integrity": "sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==", - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": "^13.7.0", - "long": "^4.0.0" - } - } - } - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "pretty-ms": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", - "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", - "requires": { - "parse-ms": "^2.1.0" - } - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "dev": true, - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, - "protobufjs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", - "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "quick-format-unescaped": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-3.0.3.tgz", - "integrity": "sha512-dy1yjycmn9blucmJLXOfZDx1ikZJUi6E8bBZLnhPG5gBrVhHXx2xVyqqgKBubVNEXmx51dBACMHpoMQK/N/AXQ==" - }, - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "regexp.prototype.flags": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", - "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-in-the-middle": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.1.0.tgz", - "integrity": "sha512-M2rLKVupQfJ5lf9OvqFGIT+9iVLnTmjgbOmpil12hiSQNn5zJTKGPoIisETNjfK+09vP3rpm1zJajmErpr2sEQ==", - "requires": { - "debug": "^4.1.1", - "module-details-from-path": "^1.0.3", - "resolve": "^1.12.0" - } - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "retry-request": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.2.1.tgz", - "integrity": "sha512-afiCoZZ7D/AR2mf+9ajr75dwGFgWmPEshv3h+oKtf9P1AsHfHvcVXumdbAEq2qNy4UXFEXsEX5HpyGj4axvoaA==", - "requires": { - "debug": "^4.1.1" - } - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { - "glob": "^7.1.3" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "semistandard": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/semistandard/-/semistandard-15.0.0.tgz", - "integrity": "sha512-qWMJubk+WeTHXtdoe4Kh81SqwcVPwOsJcDFu1QbXqO3vh60PwEJ1VrlhaHXNwP3fjfGdFPJBYXlA8x4QRNIbdw==", - "dev": true, - "requires": { - "eslint": "~7.12.1", - "eslint-config-semistandard": "15.0.1", - "eslint-config-standard": "15.0.1", - "eslint-config-standard-jsx": "9.0.0", - "eslint-plugin-import": "~2.22.1", - "eslint-plugin-node": "~11.1.0", - "eslint-plugin-promise": "~4.2.1", - "eslint-plugin-react": "~7.21.5", - "eslint-plugin-standard": "~4.0.2", - "standard-engine": "^13.0.0" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" - }, - "simple-card-validator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/simple-card-validator/-/simple-card-validator-1.1.0.tgz", - "integrity": "sha1-675uRp/q7Cy7SBX4Qyu+BMccNvk=" - }, - "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - } - } - }, - "sonic-boom": { - "version": "0.7.7", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-0.7.7.tgz", - "integrity": "sha512-Ei5YOo5J64GKClHIL/5evJPgASXFVpfVYbJV9PILZQytTK6/LCwHvsZJW2Ig4p9FMC2OrBrMnXKgRN/OEoAWfg==", - "requires": { - "atomic-sleep": "^1.0.0", - "flatstr": "^1.0.12" - } - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", - "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", - "dev": true - }, - "split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "requires": { - "through": "2" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "standard-engine": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-13.0.0.tgz", - "integrity": "sha512-fQ8/0SQ84hRtxru3tsyhc8JDBDrUFzJc/lOxh5Of/wCEpMZ0J0j7XX5kymtgdZZEke0Lb1HxzvSYdnjmg05ewA==", - "dev": true, - "requires": { - "deglob": "^4.0.1", - "get-stdin": "^8.0.0", - "minimist": "^1.2.5", - "pkg-conf": "^3.1.0", - "xdg-basedir": "^4.0.0" - } - }, - "stream-events": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", - "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", - "requires": { - "stubs": "^3.0.0" - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string.prototype.matchall": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz", - "integrity": "sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.2", - "get-intrinsic": "^1.1.1", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.3.1", - "side-channel": "^1.0.4" - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "stubs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "tar": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", - "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - } - }, - "teeny-request": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.1.1.tgz", - "integrity": "sha512-iwY6rkW5DDGq8hE2YgNQlKbptYpY5Nn2xecjQiNjOXWbKzPGUfmeUBCSQbbr306d7Z7U2N0TPl+/SwYRfua1Dg==", - "requires": { - "http-proxy-agent": "^4.0.0", - "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.6.1", - "stream-events": "^1.0.5", - "uuid": "^8.0.0" - }, - "dependencies": { - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "tsconfig-paths": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz", - "integrity": "sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q==", - "dev": true, - "requires": { - "json5": "^2.2.0", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - } - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", - "dev": true - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "walkdir": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", - "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "window-size": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=" - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - }, - "dependencies": { - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - } - } - }, - "xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" - } - } -} diff --git a/src/paymentservice/package.json b/src/paymentservice/package.json deleted file mode 100644 index 7bcf8491c..000000000 --- a/src/paymentservice/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "paymentservice", - "version": "0.0.1", - "description": "Payment Microservice demo", - "repository": "https://github.com/GoogleCloudPlatform/microservices-demo", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "lint": "semistandard *.js" - }, - "author": "Jonathan Lui", - "license": "ISC", - "dependencies": { - "@google-cloud/debug-agent": "^5.1.2", - "@google-cloud/opentelemetry-cloud-trace-exporter": "^0.9.0", - "@google-cloud/profiler": "^4.1.1", - "@grpc/proto-loader": "^0.6.0", - "@opentelemetry/api": "^0.11.0", - "@opentelemetry/node": "^0.11.0", - "@opentelemetry/plugin-grpc": "^0.11.0", - "@opentelemetry/tracing": "^0.11.0", - "axios": "0.21.1", - "grpc": "^1.22.2", - "pino": "^5.6.2", - "simple-card-validator": "^1.1.0", - "uuid": "^3.2.1" - }, - "devDependencies": { - "semistandard": "^15.0.0" - } -} diff --git a/src/paymentservice/proto/demo.proto b/src/paymentservice/proto/demo.proto deleted file mode 100644 index e5981af58..000000000 --- a/src/paymentservice/proto/demo.proto +++ /dev/null @@ -1,260 +0,0 @@ -// 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 "vintage" or "gardening" 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; -} diff --git a/src/paymentservice/proto/grpc/health/v1/health.proto b/src/paymentservice/proto/grpc/health/v1/health.proto deleted file mode 100644 index 4b4677b8a..000000000 --- a/src/paymentservice/proto/grpc/health/v1/health.proto +++ /dev/null @@ -1,43 +0,0 @@ -// 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); -} diff --git a/src/paymentservice/server.js b/src/paymentservice/server.js deleted file mode 100644 index 8783a6231..000000000 --- a/src/paymentservice/server.js +++ /dev/null @@ -1,106 +0,0 @@ -// 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'); -const pino = require('pino'); -const protoLoader = require('@grpc/proto-loader'); - -const charge = require('./charge'); -const tracer = require('./tracer')(); - -const logger = pino({ - name: 'paymentservice-server', - messageKey: 'message', - changeLevelName: 'severity', - useLevelLabels: true -}); - -class HipsterShopServer { - constructor (protoRoot, port = HipsterShopServer.DEFAULT_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 { - tracer.getCurrentSpan().addEvent("Charge Credit Card"); - 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 () { - this.server.bind(`0.0.0.0:${this.port}`, grpc.ServerCredentials.createInsecure()); - logger.info(`PaymentService grpc server listening on ${this.port}`); - this.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.DEFAULT_PORT = 50051; - -module.exports = HipsterShopServer; diff --git a/src/paymentservice/tracer.js b/src/paymentservice/tracer.js deleted file mode 100644 index b6c1dea6e..000000000 --- a/src/paymentservice/tracer.js +++ /dev/null @@ -1,44 +0,0 @@ -// 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. - -// Initialize OpenTelemetry tracing for the payment service. -// This tracer is needed in both server.js and index.js -const opentelemetry = require('@opentelemetry/api'); -const {NodeTracerProvider} = require('@opentelemetry/node'); -const {BatchSpanProcessor} = require('@opentelemetry/tracing'); - -// Enable OpenTelemetry exporters to export traces to Google Cloud Trace. -// Exporters use Application Default Credentials (ADCs) to authenticate. -// See https://developers.google.com/identity/protocols/application-default-credentials -// for more details. When your application is running on GCP, -// you don't need to provide auth credentials or a project id. -const {TraceExporter} = require('@google-cloud/opentelemetry-cloud-trace-exporter'); - -module.exports = () => { - const provider = new NodeTracerProvider({ - // Use grpc plugin to receive trace contexts from client (checkout) - plugins: { - grpc: { - enabled: true, - path: '@opentelemetry/plugin-grpc', - } - } - }); - provider.addSpanProcessor(new BatchSpanProcessor(new TraceExporter())); - - // Initialize the OpenTelemetry APIs to use the NodeTracerProvider bindings - provider.register(); - - return opentelemetry.trace.getTracer('payment'); -} diff --git a/src/productcatalogservice/.dockerignore b/src/productcatalogservice/.dockerignore deleted file mode 100644 index 48b8bf907..000000000 --- a/src/productcatalogservice/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -vendor/ diff --git a/src/productcatalogservice/Dockerfile b/src/productcatalogservice/Dockerfile deleted file mode 100644 index b24819b13..000000000 --- a/src/productcatalogservice/Dockerfile +++ /dev/null @@ -1,38 +0,0 @@ -# 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.16-alpine AS builder -RUN apk add --no-cache ca-certificates git -ENV PROJECT github.com/GoogleCloudPlatform/microservices-demo/src/productcatalogservice -WORKDIR /go/src/$PROJECT - -# restore dependencies -COPY server.go go.mod go.sum ./ -COPY genproto ./genproto/ -RUN go mod vendor -v - -COPY . . -RUN go build -o /server - -FROM alpine AS release -RUN apk add --no-cache ca-certificates -RUN GRPC_HEALTH_PROBE_VERSION=v0.4.2 && \ - 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 /productcatalogservice -COPY --from=builder /server /productcatalogservice/server -COPY products.json . -EXPOSE 3550 -ENTRYPOINT ["/productcatalogservice/server"] - diff --git a/src/productcatalogservice/README.md b/src/productcatalogservice/README.md deleted file mode 100644 index 77739433b..000000000 --- a/src/productcatalogservice/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# productcatalogservice - -Run the following command to restore dependencies to `vendor/` directory: - - go mod vendor -v - -## 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. diff --git a/src/productcatalogservice/genproto.sh b/src/productcatalogservice/genproto.sh deleted file mode 100755 index 3a8b26eff..000000000 --- a/src/productcatalogservice/genproto.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/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. - -#!/bin/bash -e - -PATH=$PATH:$(go env GOPATH)/bin -protodir=../../pb - -protoc --go_out=genproto --go-grpc_out=genproto -I $protodir $protodir/demo.proto diff --git a/src/productcatalogservice/genproto/demo.pb.go b/src/productcatalogservice/genproto/demo.pb.go deleted file mode 100644 index d3ef85c1c..000000000 --- a/src/productcatalogservice/genproto/demo.pb.go +++ /dev/null @@ -1,2607 +0,0 @@ -// 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. -// versions: -// protoc-gen-go v1.26.0 -// protoc v3.12.4 -// source: demo.proto - -package hipstershop - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type CartItem struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *CartItem) Reset() { - *x = CartItem{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CartItem) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CartItem) ProtoMessage() {} - -func (x *CartItem) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CartItem.ProtoReflect.Descriptor instead. -func (*CartItem) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{0} -} - -func (x *CartItem) GetProductId() string { - if x != nil { - return x.ProductId - } - return "" -} - -func (x *CartItem) GetQuantity() int32 { - if x != nil { - return x.Quantity - } - return 0 -} - -type AddItemRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *AddItemRequest) Reset() { - *x = AddItemRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AddItemRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AddItemRequest) ProtoMessage() {} - -func (x *AddItemRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AddItemRequest.ProtoReflect.Descriptor instead. -func (*AddItemRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{1} -} - -func (x *AddItemRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -func (x *AddItemRequest) GetItem() *CartItem { - if x != nil { - return x.Item - } - return nil -} - -type EmptyCartRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` -} - -func (x *EmptyCartRequest) Reset() { - *x = EmptyCartRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *EmptyCartRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EmptyCartRequest) ProtoMessage() {} - -func (x *EmptyCartRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use EmptyCartRequest.ProtoReflect.Descriptor instead. -func (*EmptyCartRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{2} -} - -func (x *EmptyCartRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -type GetCartRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` -} - -func (x *GetCartRequest) Reset() { - *x = GetCartRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetCartRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetCartRequest) ProtoMessage() {} - -func (x *GetCartRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetCartRequest.ProtoReflect.Descriptor instead. -func (*GetCartRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{3} -} - -func (x *GetCartRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -type Cart struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *Cart) Reset() { - *x = Cart{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Cart) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Cart) ProtoMessage() {} - -func (x *Cart) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Cart.ProtoReflect.Descriptor instead. -func (*Cart) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{4} -} - -func (x *Cart) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -func (x *Cart) GetItems() []*CartItem { - if x != nil { - return x.Items - } - return nil -} - -type Empty struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *Empty) Reset() { - *x = Empty{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Empty) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Empty) ProtoMessage() {} - -func (x *Empty) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Empty.ProtoReflect.Descriptor instead. -func (*Empty) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{5} -} - -type ListRecommendationsRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *ListRecommendationsRequest) Reset() { - *x = ListRecommendationsRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListRecommendationsRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListRecommendationsRequest) ProtoMessage() {} - -func (x *ListRecommendationsRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListRecommendationsRequest.ProtoReflect.Descriptor instead. -func (*ListRecommendationsRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{6} -} - -func (x *ListRecommendationsRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -func (x *ListRecommendationsRequest) GetProductIds() []string { - if x != nil { - return x.ProductIds - } - return nil -} - -type ListRecommendationsResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ProductIds []string `protobuf:"bytes,1,rep,name=product_ids,json=productIds,proto3" json:"product_ids,omitempty"` -} - -func (x *ListRecommendationsResponse) Reset() { - *x = ListRecommendationsResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListRecommendationsResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListRecommendationsResponse) ProtoMessage() {} - -func (x *ListRecommendationsResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListRecommendationsResponse.ProtoReflect.Descriptor instead. -func (*ListRecommendationsResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{7} -} - -func (x *ListRecommendationsResponse) GetProductIds() []string { - if x != nil { - return x.ProductIds - } - return nil -} - -type Product struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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 "vintage" or "gardening" that can be used to look up - // other related products. - Categories []string `protobuf:"bytes,6,rep,name=categories,proto3" json:"categories,omitempty"` -} - -func (x *Product) Reset() { - *x = Product{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Product) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Product) ProtoMessage() {} - -func (x *Product) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Product.ProtoReflect.Descriptor instead. -func (*Product) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{8} -} - -func (x *Product) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Product) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Product) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} - -func (x *Product) GetPicture() string { - if x != nil { - return x.Picture - } - return "" -} - -func (x *Product) GetPriceUsd() *Money { - if x != nil { - return x.PriceUsd - } - return nil -} - -func (x *Product) GetCategories() []string { - if x != nil { - return x.Categories - } - return nil -} - -type ListProductsResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Products []*Product `protobuf:"bytes,1,rep,name=products,proto3" json:"products,omitempty"` -} - -func (x *ListProductsResponse) Reset() { - *x = ListProductsResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListProductsResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListProductsResponse) ProtoMessage() {} - -func (x *ListProductsResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListProductsResponse.ProtoReflect.Descriptor instead. -func (*ListProductsResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{9} -} - -func (x *ListProductsResponse) GetProducts() []*Product { - if x != nil { - return x.Products - } - return nil -} - -type GetProductRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` -} - -func (x *GetProductRequest) Reset() { - *x = GetProductRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetProductRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetProductRequest) ProtoMessage() {} - -func (x *GetProductRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetProductRequest.ProtoReflect.Descriptor instead. -func (*GetProductRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{10} -} - -func (x *GetProductRequest) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -type SearchProductsRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` -} - -func (x *SearchProductsRequest) Reset() { - *x = SearchProductsRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SearchProductsRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SearchProductsRequest) ProtoMessage() {} - -func (x *SearchProductsRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SearchProductsRequest.ProtoReflect.Descriptor instead. -func (*SearchProductsRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{11} -} - -func (x *SearchProductsRequest) GetQuery() string { - if x != nil { - return x.Query - } - return "" -} - -type SearchProductsResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Results []*Product `protobuf:"bytes,1,rep,name=results,proto3" json:"results,omitempty"` -} - -func (x *SearchProductsResponse) Reset() { - *x = SearchProductsResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SearchProductsResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SearchProductsResponse) ProtoMessage() {} - -func (x *SearchProductsResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SearchProductsResponse.ProtoReflect.Descriptor instead. -func (*SearchProductsResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{12} -} - -func (x *SearchProductsResponse) GetResults() []*Product { - if x != nil { - return x.Results - } - return nil -} - -type GetQuoteRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Address *Address `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` - Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` -} - -func (x *GetQuoteRequest) Reset() { - *x = GetQuoteRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetQuoteRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetQuoteRequest) ProtoMessage() {} - -func (x *GetQuoteRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetQuoteRequest.ProtoReflect.Descriptor instead. -func (*GetQuoteRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{13} -} - -func (x *GetQuoteRequest) GetAddress() *Address { - if x != nil { - return x.Address - } - return nil -} - -func (x *GetQuoteRequest) GetItems() []*CartItem { - if x != nil { - return x.Items - } - return nil -} - -type GetQuoteResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - CostUsd *Money `protobuf:"bytes,1,opt,name=cost_usd,json=costUsd,proto3" json:"cost_usd,omitempty"` -} - -func (x *GetQuoteResponse) Reset() { - *x = GetQuoteResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetQuoteResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetQuoteResponse) ProtoMessage() {} - -func (x *GetQuoteResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetQuoteResponse.ProtoReflect.Descriptor instead. -func (*GetQuoteResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{14} -} - -func (x *GetQuoteResponse) GetCostUsd() *Money { - if x != nil { - return x.CostUsd - } - return nil -} - -type ShipOrderRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Address *Address `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` - Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` -} - -func (x *ShipOrderRequest) Reset() { - *x = ShipOrderRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ShipOrderRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ShipOrderRequest) ProtoMessage() {} - -func (x *ShipOrderRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ShipOrderRequest.ProtoReflect.Descriptor instead. -func (*ShipOrderRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{15} -} - -func (x *ShipOrderRequest) GetAddress() *Address { - if x != nil { - return x.Address - } - return nil -} - -func (x *ShipOrderRequest) GetItems() []*CartItem { - if x != nil { - return x.Items - } - return nil -} - -type ShipOrderResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - TrackingId string `protobuf:"bytes,1,opt,name=tracking_id,json=trackingId,proto3" json:"tracking_id,omitempty"` -} - -func (x *ShipOrderResponse) Reset() { - *x = ShipOrderResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ShipOrderResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ShipOrderResponse) ProtoMessage() {} - -func (x *ShipOrderResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[16] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ShipOrderResponse.ProtoReflect.Descriptor instead. -func (*ShipOrderResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{16} -} - -func (x *ShipOrderResponse) GetTrackingId() string { - if x != nil { - return x.TrackingId - } - return "" -} - -type Address struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *Address) Reset() { - *x = Address{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Address) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Address) ProtoMessage() {} - -func (x *Address) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[17] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Address.ProtoReflect.Descriptor instead. -func (*Address) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{17} -} - -func (x *Address) GetStreetAddress() string { - if x != nil { - return x.StreetAddress - } - return "" -} - -func (x *Address) GetCity() string { - if x != nil { - return x.City - } - return "" -} - -func (x *Address) GetState() string { - if x != nil { - return x.State - } - return "" -} - -func (x *Address) GetCountry() string { - if x != nil { - return x.Country - } - return "" -} - -func (x *Address) GetZipCode() int32 { - if x != nil { - return x.ZipCode - } - return 0 -} - -// Represents an amount of money with its currency type. -type Money struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // 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"` -} - -func (x *Money) Reset() { - *x = Money{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Money) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Money) ProtoMessage() {} - -func (x *Money) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[18] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Money.ProtoReflect.Descriptor instead. -func (*Money) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{18} -} - -func (x *Money) GetCurrencyCode() string { - if x != nil { - return x.CurrencyCode - } - return "" -} - -func (x *Money) GetUnits() int64 { - if x != nil { - return x.Units - } - return 0 -} - -func (x *Money) GetNanos() int32 { - if x != nil { - return x.Nanos - } - return 0 -} - -type GetSupportedCurrenciesResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // 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"` -} - -func (x *GetSupportedCurrenciesResponse) Reset() { - *x = GetSupportedCurrenciesResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetSupportedCurrenciesResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetSupportedCurrenciesResponse) ProtoMessage() {} - -func (x *GetSupportedCurrenciesResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[19] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetSupportedCurrenciesResponse.ProtoReflect.Descriptor instead. -func (*GetSupportedCurrenciesResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{19} -} - -func (x *GetSupportedCurrenciesResponse) GetCurrencyCodes() []string { - if x != nil { - return x.CurrencyCodes - } - return nil -} - -type CurrencyConversionRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *CurrencyConversionRequest) Reset() { - *x = CurrencyConversionRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CurrencyConversionRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CurrencyConversionRequest) ProtoMessage() {} - -func (x *CurrencyConversionRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[20] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CurrencyConversionRequest.ProtoReflect.Descriptor instead. -func (*CurrencyConversionRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{20} -} - -func (x *CurrencyConversionRequest) GetFrom() *Money { - if x != nil { - return x.From - } - return nil -} - -func (x *CurrencyConversionRequest) GetToCode() string { - if x != nil { - return x.ToCode - } - return "" -} - -type CreditCardInfo struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *CreditCardInfo) Reset() { - *x = CreditCardInfo{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreditCardInfo) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreditCardInfo) ProtoMessage() {} - -func (x *CreditCardInfo) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[21] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreditCardInfo.ProtoReflect.Descriptor instead. -func (*CreditCardInfo) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{21} -} - -func (x *CreditCardInfo) GetCreditCardNumber() string { - if x != nil { - return x.CreditCardNumber - } - return "" -} - -func (x *CreditCardInfo) GetCreditCardCvv() int32 { - if x != nil { - return x.CreditCardCvv - } - return 0 -} - -func (x *CreditCardInfo) GetCreditCardExpirationYear() int32 { - if x != nil { - return x.CreditCardExpirationYear - } - return 0 -} - -func (x *CreditCardInfo) GetCreditCardExpirationMonth() int32 { - if x != nil { - return x.CreditCardExpirationMonth - } - return 0 -} - -type ChargeRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *ChargeRequest) Reset() { - *x = ChargeRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ChargeRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ChargeRequest) ProtoMessage() {} - -func (x *ChargeRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[22] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ChargeRequest.ProtoReflect.Descriptor instead. -func (*ChargeRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{22} -} - -func (x *ChargeRequest) GetAmount() *Money { - if x != nil { - return x.Amount - } - return nil -} - -func (x *ChargeRequest) GetCreditCard() *CreditCardInfo { - if x != nil { - return x.CreditCard - } - return nil -} - -type ChargeResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - TransactionId string `protobuf:"bytes,1,opt,name=transaction_id,json=transactionId,proto3" json:"transaction_id,omitempty"` -} - -func (x *ChargeResponse) Reset() { - *x = ChargeResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[23] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ChargeResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ChargeResponse) ProtoMessage() {} - -func (x *ChargeResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[23] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ChargeResponse.ProtoReflect.Descriptor instead. -func (*ChargeResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{23} -} - -func (x *ChargeResponse) GetTransactionId() string { - if x != nil { - return x.TransactionId - } - return "" -} - -type OrderItem struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Item *CartItem `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` - Cost *Money `protobuf:"bytes,2,opt,name=cost,proto3" json:"cost,omitempty"` -} - -func (x *OrderItem) Reset() { - *x = OrderItem{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[24] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *OrderItem) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*OrderItem) ProtoMessage() {} - -func (x *OrderItem) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[24] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use OrderItem.ProtoReflect.Descriptor instead. -func (*OrderItem) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{24} -} - -func (x *OrderItem) GetItem() *CartItem { - if x != nil { - return x.Item - } - return nil -} - -func (x *OrderItem) GetCost() *Money { - if x != nil { - return x.Cost - } - return nil -} - -type OrderResult struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *OrderResult) Reset() { - *x = OrderResult{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[25] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *OrderResult) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*OrderResult) ProtoMessage() {} - -func (x *OrderResult) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[25] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use OrderResult.ProtoReflect.Descriptor instead. -func (*OrderResult) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{25} -} - -func (x *OrderResult) GetOrderId() string { - if x != nil { - return x.OrderId - } - return "" -} - -func (x *OrderResult) GetShippingTrackingId() string { - if x != nil { - return x.ShippingTrackingId - } - return "" -} - -func (x *OrderResult) GetShippingCost() *Money { - if x != nil { - return x.ShippingCost - } - return nil -} - -func (x *OrderResult) GetShippingAddress() *Address { - if x != nil { - return x.ShippingAddress - } - return nil -} - -func (x *OrderResult) GetItems() []*OrderItem { - if x != nil { - return x.Items - } - return nil -} - -type SendOrderConfirmationRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` - Order *OrderResult `protobuf:"bytes,2,opt,name=order,proto3" json:"order,omitempty"` -} - -func (x *SendOrderConfirmationRequest) Reset() { - *x = SendOrderConfirmationRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[26] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SendOrderConfirmationRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SendOrderConfirmationRequest) ProtoMessage() {} - -func (x *SendOrderConfirmationRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[26] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SendOrderConfirmationRequest.ProtoReflect.Descriptor instead. -func (*SendOrderConfirmationRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{26} -} - -func (x *SendOrderConfirmationRequest) GetEmail() string { - if x != nil { - return x.Email - } - return "" -} - -func (x *SendOrderConfirmationRequest) GetOrder() *OrderResult { - if x != nil { - return x.Order - } - return nil -} - -type PlaceOrderRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *PlaceOrderRequest) Reset() { - *x = PlaceOrderRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[27] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PlaceOrderRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PlaceOrderRequest) ProtoMessage() {} - -func (x *PlaceOrderRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[27] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PlaceOrderRequest.ProtoReflect.Descriptor instead. -func (*PlaceOrderRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{27} -} - -func (x *PlaceOrderRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -func (x *PlaceOrderRequest) GetUserCurrency() string { - if x != nil { - return x.UserCurrency - } - return "" -} - -func (x *PlaceOrderRequest) GetAddress() *Address { - if x != nil { - return x.Address - } - return nil -} - -func (x *PlaceOrderRequest) GetEmail() string { - if x != nil { - return x.Email - } - return "" -} - -func (x *PlaceOrderRequest) GetCreditCard() *CreditCardInfo { - if x != nil { - return x.CreditCard - } - return nil -} - -type PlaceOrderResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Order *OrderResult `protobuf:"bytes,1,opt,name=order,proto3" json:"order,omitempty"` -} - -func (x *PlaceOrderResponse) Reset() { - *x = PlaceOrderResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[28] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PlaceOrderResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PlaceOrderResponse) ProtoMessage() {} - -func (x *PlaceOrderResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[28] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PlaceOrderResponse.ProtoReflect.Descriptor instead. -func (*PlaceOrderResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{28} -} - -func (x *PlaceOrderResponse) GetOrder() *OrderResult { - if x != nil { - return x.Order - } - return nil -} - -type AdRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // 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"` -} - -func (x *AdRequest) Reset() { - *x = AdRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[29] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AdRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AdRequest) ProtoMessage() {} - -func (x *AdRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[29] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AdRequest.ProtoReflect.Descriptor instead. -func (*AdRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{29} -} - -func (x *AdRequest) GetContextKeys() []string { - if x != nil { - return x.ContextKeys - } - return nil -} - -type AdResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Ads []*Ad `protobuf:"bytes,1,rep,name=ads,proto3" json:"ads,omitempty"` -} - -func (x *AdResponse) Reset() { - *x = AdResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[30] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AdResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AdResponse) ProtoMessage() {} - -func (x *AdResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[30] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AdResponse.ProtoReflect.Descriptor instead. -func (*AdResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{30} -} - -func (x *AdResponse) GetAds() []*Ad { - if x != nil { - return x.Ads - } - return nil -} - -type Ad struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // 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"` -} - -func (x *Ad) Reset() { - *x = Ad{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[31] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Ad) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Ad) ProtoMessage() {} - -func (x *Ad) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[31] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Ad.ProtoReflect.Descriptor instead. -func (*Ad) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{31} -} - -func (x *Ad) GetRedirectUrl() string { - if x != nil { - return x.RedirectUrl - } - return "" -} - -func (x *Ad) GetText() string { - if x != nil { - return x.Text - } - return "" -} - -var File_demo_proto protoreflect.FileDescriptor - -var file_demo_proto_rawDesc = []byte{ - 0x0a, 0x0a, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x68, 0x69, - 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x22, 0x45, 0x0a, 0x08, 0x43, 0x61, 0x72, - 0x74, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, - 0x63, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x22, 0x54, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x04, 0x69, - 0x74, 0x65, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x69, 0x70, 0x73, - 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x61, 0x72, 0x74, 0x49, 0x74, 0x65, 0x6d, - 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x2b, 0x0a, 0x10, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x43, - 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, - 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, - 0x72, 0x49, 0x64, 0x22, 0x29, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x43, 0x61, 0x72, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x4c, - 0x0a, 0x04, 0x43, 0x61, 0x72, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, - 0x2b, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, - 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x61, 0x72, - 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x07, 0x0a, 0x05, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x56, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, - 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, - 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x73, 0x22, 0x3e, 0x0a, - 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, - 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x73, 0x22, 0xba, 0x01, - 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, - 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x18, 0x0a, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x70, 0x72, 0x69, - 0x63, 0x65, 0x5f, 0x75, 0x73, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x68, - 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, - 0x52, 0x08, 0x70, 0x72, 0x69, 0x63, 0x65, 0x55, 0x73, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x61, - 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, - 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x22, 0x48, 0x0a, 0x14, 0x4c, 0x69, - 0x73, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x30, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, - 0x6f, 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x64, - 0x75, 0x63, 0x74, 0x73, 0x22, 0x23, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, - 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x2d, 0x0a, 0x15, 0x53, 0x65, 0x61, - 0x72, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x48, 0x0a, 0x16, 0x53, 0x65, 0x61, 0x72, - 0x63, 0x68, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, - 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x73, 0x22, 0x6e, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, - 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x07, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2b, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, - 0x6f, 0x70, 0x2e, 0x43, 0x61, 0x72, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, - 0x6d, 0x73, 0x22, 0x41, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x08, 0x63, 0x6f, 0x73, 0x74, 0x5f, 0x75, - 0x73, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, - 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x07, 0x63, 0x6f, - 0x73, 0x74, 0x55, 0x73, 0x64, 0x22, 0x6f, 0x0a, 0x10, 0x53, 0x68, 0x69, 0x70, 0x4f, 0x72, 0x64, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x07, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x68, 0x69, 0x70, - 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2b, 0x0a, 0x05, 0x69, 0x74, 0x65, - 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, - 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x61, 0x72, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, - 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x34, 0x0a, 0x11, 0x53, 0x68, 0x69, 0x70, 0x4f, 0x72, - 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, - 0x72, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x64, 0x22, 0x8f, 0x01, 0x0a, - 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x74, 0x72, 0x65, - 0x65, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0d, 0x73, 0x74, 0x72, 0x65, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, - 0x12, 0x0a, 0x04, 0x63, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, - 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x7a, 0x69, 0x70, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x7a, 0x69, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x58, - 0x0a, 0x05, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65, - 0x6e, 0x63, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, - 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x75, 0x6e, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x75, 0x6e, 0x69, - 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x05, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x22, 0x47, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x53, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x69, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x75, - 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x64, 0x65, - 0x73, 0x22, 0x5c, 0x0a, 0x19, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x6e, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, - 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x68, - 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, - 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x64, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x22, - 0xe6, 0x01, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x49, 0x6e, - 0x66, 0x6f, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5f, 0x63, 0x61, 0x72, - 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, - 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, - 0x12, 0x26, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x5f, - 0x63, 0x76, 0x76, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x63, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x43, 0x61, 0x72, 0x64, 0x43, 0x76, 0x76, 0x12, 0x3d, 0x0a, 0x1b, 0x63, 0x72, 0x65, 0x64, - 0x69, 0x74, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x79, 0x65, 0x61, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x18, 0x63, - 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x59, 0x65, 0x61, 0x72, 0x12, 0x3f, 0x0a, 0x1c, 0x63, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x19, 0x63, - 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x22, 0x79, 0x0a, 0x0d, 0x43, 0x68, 0x61, 0x72, - 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x06, 0x61, 0x6d, 0x6f, - 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x68, 0x69, 0x70, 0x73, - 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x06, 0x61, - 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3c, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5f, - 0x63, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x68, 0x69, 0x70, - 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, - 0x61, 0x72, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, - 0x61, 0x72, 0x64, 0x22, 0x37, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, - 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x5e, 0x0a, 0x09, - 0x4f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x29, 0x0a, 0x04, 0x69, 0x74, 0x65, - 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, - 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x61, 0x72, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, - 0x69, 0x74, 0x65, 0x6d, 0x12, 0x26, 0x0a, 0x04, 0x63, 0x6f, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, - 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x04, 0x63, 0x6f, 0x73, 0x74, 0x22, 0x82, 0x02, 0x0a, - 0x0b, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x19, 0x0a, 0x08, - 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x6f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x68, 0x69, 0x70, 0x70, - 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x68, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x54, - 0x72, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x64, 0x12, 0x37, 0x0a, 0x0d, 0x73, 0x68, 0x69, - 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x12, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4d, - 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x0c, 0x73, 0x68, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x43, 0x6f, - 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x10, 0x73, 0x68, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x68, - 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x52, 0x0f, 0x73, 0x68, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x41, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x12, 0x2c, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, - 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, - 0x73, 0x22, 0x64, 0x0a, 0x1c, 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x2e, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, - 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x22, 0xd5, 0x01, 0x0a, 0x11, 0x50, 0x6c, 0x61, 0x63, - 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, - 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, - 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x75, - 0x73, 0x65, 0x72, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x2e, 0x0a, 0x07, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x68, - 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, - 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, - 0x6c, 0x12, 0x3c, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5f, 0x63, 0x61, 0x72, 0x64, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, - 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x22, - 0x44, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x63, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, - 0x6f, 0x70, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x05, - 0x6f, 0x72, 0x64, 0x65, 0x72, 0x22, 0x2e, 0x0a, 0x09, 0x41, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x6b, 0x65, - 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, - 0x74, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x2f, 0x0a, 0x0a, 0x41, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x03, 0x61, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0f, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, - 0x64, 0x52, 0x03, 0x61, 0x64, 0x73, 0x22, 0x3b, 0x0a, 0x02, 0x41, 0x64, 0x12, 0x21, 0x0a, 0x0c, - 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x55, 0x72, 0x6c, 0x12, - 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, - 0x65, 0x78, 0x74, 0x32, 0xca, 0x01, 0x0a, 0x0b, 0x43, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x3c, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x1b, - 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, 0x64, 0x64, - 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x68, 0x69, - 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, - 0x00, 0x12, 0x3b, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x43, 0x61, 0x72, 0x74, 0x12, 0x1b, 0x2e, 0x68, - 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x61, - 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x68, 0x69, 0x70, 0x73, - 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x61, 0x72, 0x74, 0x22, 0x00, 0x12, 0x40, - 0x0a, 0x09, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x43, 0x61, 0x72, 0x74, 0x12, 0x1d, 0x2e, 0x68, 0x69, - 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x43, - 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x68, 0x69, 0x70, - 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, - 0x32, 0x83, 0x01, 0x0a, 0x15, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6a, 0x0a, 0x13, 0x4c, 0x69, - 0x73, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x27, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x69, 0x70, - 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, - 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0x83, 0x02, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x64, 0x75, - 0x63, 0x74, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x47, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, - 0x12, 0x12, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x21, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, - 0x6f, 0x70, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x0a, 0x47, 0x65, 0x74, - 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x1e, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, - 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, - 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x22, 0x00, 0x12, - 0x5b, 0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, - 0x73, 0x12, 0x22, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, - 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, - 0x68, 0x6f, 0x70, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, - 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0xaa, 0x01, 0x0a, - 0x0f, 0x53, 0x68, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x49, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x1c, 0x2e, 0x68, - 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x51, 0x75, - 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x68, 0x69, 0x70, - 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x09, 0x53, - 0x68, 0x69, 0x70, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x1d, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, - 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x53, 0x68, 0x69, 0x70, 0x4f, 0x72, 0x64, 0x65, 0x72, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, - 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x53, 0x68, 0x69, 0x70, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0xb7, 0x01, 0x0a, 0x0f, 0x43, 0x75, - 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5b, 0x0a, - 0x16, 0x47, 0x65, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x43, 0x75, 0x72, - 0x72, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x12, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, - 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x2b, 0x2e, 0x68, 0x69, - 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x07, 0x43, 0x6f, - 0x6e, 0x76, 0x65, 0x72, 0x74, 0x12, 0x26, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, - 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x6e, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, - 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4d, 0x6f, 0x6e, 0x65, - 0x79, 0x22, 0x00, 0x32, 0x55, 0x0a, 0x0e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x12, - 0x1a, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x68, - 0x61, 0x72, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x68, 0x69, - 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0x68, 0x0a, 0x0c, 0x45, 0x6d, - 0x61, 0x69, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x58, 0x0a, 0x15, 0x53, 0x65, - 0x6e, 0x64, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, - 0x70, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, - 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x22, 0x00, 0x32, 0x62, 0x0a, 0x0f, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4f, 0x0a, 0x0a, 0x50, 0x6c, 0x61, 0x63, 0x65, - 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x1e, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, - 0x68, 0x6f, 0x70, 0x2e, 0x50, 0x6c, 0x61, 0x63, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, - 0x68, 0x6f, 0x70, 0x2e, 0x50, 0x6c, 0x61, 0x63, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0x48, 0x0a, 0x09, 0x41, 0x64, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x41, 0x64, 0x73, 0x12, - 0x16, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, 0x64, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, - 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x42, 0x10, 0x5a, 0x0e, 0x2e, 0x2f, 0x3b, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, - 0x73, 0x68, 0x6f, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_demo_proto_rawDescOnce sync.Once - file_demo_proto_rawDescData = file_demo_proto_rawDesc -) - -func file_demo_proto_rawDescGZIP() []byte { - file_demo_proto_rawDescOnce.Do(func() { - file_demo_proto_rawDescData = protoimpl.X.CompressGZIP(file_demo_proto_rawDescData) - }) - return file_demo_proto_rawDescData -} - -var file_demo_proto_msgTypes = make([]protoimpl.MessageInfo, 32) -var file_demo_proto_goTypes = []interface{}{ - (*CartItem)(nil), // 0: hipstershop.CartItem - (*AddItemRequest)(nil), // 1: hipstershop.AddItemRequest - (*EmptyCartRequest)(nil), // 2: hipstershop.EmptyCartRequest - (*GetCartRequest)(nil), // 3: hipstershop.GetCartRequest - (*Cart)(nil), // 4: hipstershop.Cart - (*Empty)(nil), // 5: hipstershop.Empty - (*ListRecommendationsRequest)(nil), // 6: hipstershop.ListRecommendationsRequest - (*ListRecommendationsResponse)(nil), // 7: hipstershop.ListRecommendationsResponse - (*Product)(nil), // 8: hipstershop.Product - (*ListProductsResponse)(nil), // 9: hipstershop.ListProductsResponse - (*GetProductRequest)(nil), // 10: hipstershop.GetProductRequest - (*SearchProductsRequest)(nil), // 11: hipstershop.SearchProductsRequest - (*SearchProductsResponse)(nil), // 12: hipstershop.SearchProductsResponse - (*GetQuoteRequest)(nil), // 13: hipstershop.GetQuoteRequest - (*GetQuoteResponse)(nil), // 14: hipstershop.GetQuoteResponse - (*ShipOrderRequest)(nil), // 15: hipstershop.ShipOrderRequest - (*ShipOrderResponse)(nil), // 16: hipstershop.ShipOrderResponse - (*Address)(nil), // 17: hipstershop.Address - (*Money)(nil), // 18: hipstershop.Money - (*GetSupportedCurrenciesResponse)(nil), // 19: hipstershop.GetSupportedCurrenciesResponse - (*CurrencyConversionRequest)(nil), // 20: hipstershop.CurrencyConversionRequest - (*CreditCardInfo)(nil), // 21: hipstershop.CreditCardInfo - (*ChargeRequest)(nil), // 22: hipstershop.ChargeRequest - (*ChargeResponse)(nil), // 23: hipstershop.ChargeResponse - (*OrderItem)(nil), // 24: hipstershop.OrderItem - (*OrderResult)(nil), // 25: hipstershop.OrderResult - (*SendOrderConfirmationRequest)(nil), // 26: hipstershop.SendOrderConfirmationRequest - (*PlaceOrderRequest)(nil), // 27: hipstershop.PlaceOrderRequest - (*PlaceOrderResponse)(nil), // 28: hipstershop.PlaceOrderResponse - (*AdRequest)(nil), // 29: hipstershop.AdRequest - (*AdResponse)(nil), // 30: hipstershop.AdResponse - (*Ad)(nil), // 31: hipstershop.Ad -} -var file_demo_proto_depIdxs = []int32{ - 0, // 0: hipstershop.AddItemRequest.item:type_name -> hipstershop.CartItem - 0, // 1: hipstershop.Cart.items:type_name -> hipstershop.CartItem - 18, // 2: hipstershop.Product.price_usd:type_name -> hipstershop.Money - 8, // 3: hipstershop.ListProductsResponse.products:type_name -> hipstershop.Product - 8, // 4: hipstershop.SearchProductsResponse.results:type_name -> hipstershop.Product - 17, // 5: hipstershop.GetQuoteRequest.address:type_name -> hipstershop.Address - 0, // 6: hipstershop.GetQuoteRequest.items:type_name -> hipstershop.CartItem - 18, // 7: hipstershop.GetQuoteResponse.cost_usd:type_name -> hipstershop.Money - 17, // 8: hipstershop.ShipOrderRequest.address:type_name -> hipstershop.Address - 0, // 9: hipstershop.ShipOrderRequest.items:type_name -> hipstershop.CartItem - 18, // 10: hipstershop.CurrencyConversionRequest.from:type_name -> hipstershop.Money - 18, // 11: hipstershop.ChargeRequest.amount:type_name -> hipstershop.Money - 21, // 12: hipstershop.ChargeRequest.credit_card:type_name -> hipstershop.CreditCardInfo - 0, // 13: hipstershop.OrderItem.item:type_name -> hipstershop.CartItem - 18, // 14: hipstershop.OrderItem.cost:type_name -> hipstershop.Money - 18, // 15: hipstershop.OrderResult.shipping_cost:type_name -> hipstershop.Money - 17, // 16: hipstershop.OrderResult.shipping_address:type_name -> hipstershop.Address - 24, // 17: hipstershop.OrderResult.items:type_name -> hipstershop.OrderItem - 25, // 18: hipstershop.SendOrderConfirmationRequest.order:type_name -> hipstershop.OrderResult - 17, // 19: hipstershop.PlaceOrderRequest.address:type_name -> hipstershop.Address - 21, // 20: hipstershop.PlaceOrderRequest.credit_card:type_name -> hipstershop.CreditCardInfo - 25, // 21: hipstershop.PlaceOrderResponse.order:type_name -> hipstershop.OrderResult - 31, // 22: hipstershop.AdResponse.ads:type_name -> hipstershop.Ad - 1, // 23: hipstershop.CartService.AddItem:input_type -> hipstershop.AddItemRequest - 3, // 24: hipstershop.CartService.GetCart:input_type -> hipstershop.GetCartRequest - 2, // 25: hipstershop.CartService.EmptyCart:input_type -> hipstershop.EmptyCartRequest - 6, // 26: hipstershop.RecommendationService.ListRecommendations:input_type -> hipstershop.ListRecommendationsRequest - 5, // 27: hipstershop.ProductCatalogService.ListProducts:input_type -> hipstershop.Empty - 10, // 28: hipstershop.ProductCatalogService.GetProduct:input_type -> hipstershop.GetProductRequest - 11, // 29: hipstershop.ProductCatalogService.SearchProducts:input_type -> hipstershop.SearchProductsRequest - 13, // 30: hipstershop.ShippingService.GetQuote:input_type -> hipstershop.GetQuoteRequest - 15, // 31: hipstershop.ShippingService.ShipOrder:input_type -> hipstershop.ShipOrderRequest - 5, // 32: hipstershop.CurrencyService.GetSupportedCurrencies:input_type -> hipstershop.Empty - 20, // 33: hipstershop.CurrencyService.Convert:input_type -> hipstershop.CurrencyConversionRequest - 22, // 34: hipstershop.PaymentService.Charge:input_type -> hipstershop.ChargeRequest - 26, // 35: hipstershop.EmailService.SendOrderConfirmation:input_type -> hipstershop.SendOrderConfirmationRequest - 27, // 36: hipstershop.CheckoutService.PlaceOrder:input_type -> hipstershop.PlaceOrderRequest - 29, // 37: hipstershop.AdService.GetAds:input_type -> hipstershop.AdRequest - 5, // 38: hipstershop.CartService.AddItem:output_type -> hipstershop.Empty - 4, // 39: hipstershop.CartService.GetCart:output_type -> hipstershop.Cart - 5, // 40: hipstershop.CartService.EmptyCart:output_type -> hipstershop.Empty - 7, // 41: hipstershop.RecommendationService.ListRecommendations:output_type -> hipstershop.ListRecommendationsResponse - 9, // 42: hipstershop.ProductCatalogService.ListProducts:output_type -> hipstershop.ListProductsResponse - 8, // 43: hipstershop.ProductCatalogService.GetProduct:output_type -> hipstershop.Product - 12, // 44: hipstershop.ProductCatalogService.SearchProducts:output_type -> hipstershop.SearchProductsResponse - 14, // 45: hipstershop.ShippingService.GetQuote:output_type -> hipstershop.GetQuoteResponse - 16, // 46: hipstershop.ShippingService.ShipOrder:output_type -> hipstershop.ShipOrderResponse - 19, // 47: hipstershop.CurrencyService.GetSupportedCurrencies:output_type -> hipstershop.GetSupportedCurrenciesResponse - 18, // 48: hipstershop.CurrencyService.Convert:output_type -> hipstershop.Money - 23, // 49: hipstershop.PaymentService.Charge:output_type -> hipstershop.ChargeResponse - 5, // 50: hipstershop.EmailService.SendOrderConfirmation:output_type -> hipstershop.Empty - 28, // 51: hipstershop.CheckoutService.PlaceOrder:output_type -> hipstershop.PlaceOrderResponse - 30, // 52: hipstershop.AdService.GetAds:output_type -> hipstershop.AdResponse - 38, // [38:53] is the sub-list for method output_type - 23, // [23:38] is the sub-list for method input_type - 23, // [23:23] is the sub-list for extension type_name - 23, // [23:23] is the sub-list for extension extendee - 0, // [0:23] is the sub-list for field type_name -} - -func init() { file_demo_proto_init() } -func file_demo_proto_init() { - if File_demo_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_demo_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CartItem); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddItemRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EmptyCartRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetCartRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Cart); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Empty); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListRecommendationsRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListRecommendationsResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Product); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListProductsResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetProductRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SearchProductsRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SearchProductsResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetQuoteRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetQuoteResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ShipOrderRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ShipOrderResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Address); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Money); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSupportedCurrenciesResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CurrencyConversionRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreditCardInfo); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ChargeRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ChargeResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OrderItem); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OrderResult); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SendOrderConfirmationRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PlaceOrderRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PlaceOrderResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AdRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AdResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Ad); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_demo_proto_rawDesc, - NumEnums: 0, - NumMessages: 32, - NumExtensions: 0, - NumServices: 9, - }, - GoTypes: file_demo_proto_goTypes, - DependencyIndexes: file_demo_proto_depIdxs, - MessageInfos: file_demo_proto_msgTypes, - }.Build() - File_demo_proto = out.File - file_demo_proto_rawDesc = nil - file_demo_proto_goTypes = nil - file_demo_proto_depIdxs = nil -} diff --git a/src/productcatalogservice/genproto/demo_grpc.pb.go b/src/productcatalogservice/genproto/demo_grpc.pb.go deleted file mode 100644 index f4c37599a..000000000 --- a/src/productcatalogservice/genproto/demo_grpc.pb.go +++ /dev/null @@ -1,1019 +0,0 @@ -// 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. - -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. - -package hipstershop - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 - -// CartServiceClient is the client API for CartService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type 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.ClientConnInterface -} - -func NewCartServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedCartServiceServer -// for forward compatibility -type CartServiceServer interface { - AddItem(context.Context, *AddItemRequest) (*Empty, error) - GetCart(context.Context, *GetCartRequest) (*Cart, error) - EmptyCart(context.Context, *EmptyCartRequest) (*Empty, error) - mustEmbedUnimplementedCartServiceServer() -} - -// UnimplementedCartServiceServer must be embedded to have forward compatible implementations. -type UnimplementedCartServiceServer struct { -} - -func (UnimplementedCartServiceServer) AddItem(context.Context, *AddItemRequest) (*Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method AddItem not implemented") -} -func (UnimplementedCartServiceServer) GetCart(context.Context, *GetCartRequest) (*Cart, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetCart not implemented") -} -func (UnimplementedCartServiceServer) EmptyCart(context.Context, *EmptyCartRequest) (*Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method EmptyCart not implemented") -} -func (UnimplementedCartServiceServer) mustEmbedUnimplementedCartServiceServer() {} - -// UnsafeCartServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to CartServiceServer will -// result in compilation errors. -type UnsafeCartServiceServer interface { - mustEmbedUnimplementedCartServiceServer() -} - -func RegisterCartServiceServer(s grpc.ServiceRegistrar, 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) -} - -// CartService_ServiceDesc is the grpc.ServiceDesc for CartService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type RecommendationServiceClient interface { - ListRecommendations(ctx context.Context, in *ListRecommendationsRequest, opts ...grpc.CallOption) (*ListRecommendationsResponse, error) -} - -type recommendationServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewRecommendationServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedRecommendationServiceServer -// for forward compatibility -type RecommendationServiceServer interface { - ListRecommendations(context.Context, *ListRecommendationsRequest) (*ListRecommendationsResponse, error) - mustEmbedUnimplementedRecommendationServiceServer() -} - -// UnimplementedRecommendationServiceServer must be embedded to have forward compatible implementations. -type UnimplementedRecommendationServiceServer struct { -} - -func (UnimplementedRecommendationServiceServer) ListRecommendations(context.Context, *ListRecommendationsRequest) (*ListRecommendationsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListRecommendations not implemented") -} -func (UnimplementedRecommendationServiceServer) mustEmbedUnimplementedRecommendationServiceServer() {} - -// UnsafeRecommendationServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to RecommendationServiceServer will -// result in compilation errors. -type UnsafeRecommendationServiceServer interface { - mustEmbedUnimplementedRecommendationServiceServer() -} - -func RegisterRecommendationServiceServer(s grpc.ServiceRegistrar, 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) -} - -// RecommendationService_ServiceDesc is the grpc.ServiceDesc for RecommendationService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#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.ClientConnInterface -} - -func NewProductCatalogServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedProductCatalogServiceServer -// for forward compatibility -type ProductCatalogServiceServer interface { - ListProducts(context.Context, *Empty) (*ListProductsResponse, error) - GetProduct(context.Context, *GetProductRequest) (*Product, error) - SearchProducts(context.Context, *SearchProductsRequest) (*SearchProductsResponse, error) - mustEmbedUnimplementedProductCatalogServiceServer() -} - -// UnimplementedProductCatalogServiceServer must be embedded to have forward compatible implementations. -type UnimplementedProductCatalogServiceServer struct { -} - -func (UnimplementedProductCatalogServiceServer) ListProducts(context.Context, *Empty) (*ListProductsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListProducts not implemented") -} -func (UnimplementedProductCatalogServiceServer) GetProduct(context.Context, *GetProductRequest) (*Product, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetProduct not implemented") -} -func (UnimplementedProductCatalogServiceServer) SearchProducts(context.Context, *SearchProductsRequest) (*SearchProductsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method SearchProducts not implemented") -} -func (UnimplementedProductCatalogServiceServer) mustEmbedUnimplementedProductCatalogServiceServer() {} - -// UnsafeProductCatalogServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to ProductCatalogServiceServer will -// result in compilation errors. -type UnsafeProductCatalogServiceServer interface { - mustEmbedUnimplementedProductCatalogServiceServer() -} - -func RegisterProductCatalogServiceServer(s grpc.ServiceRegistrar, 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) -} - -// ProductCatalogService_ServiceDesc is the grpc.ServiceDesc for ProductCatalogService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#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.ClientConnInterface -} - -func NewShippingServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedShippingServiceServer -// for forward compatibility -type ShippingServiceServer interface { - GetQuote(context.Context, *GetQuoteRequest) (*GetQuoteResponse, error) - ShipOrder(context.Context, *ShipOrderRequest) (*ShipOrderResponse, error) - mustEmbedUnimplementedShippingServiceServer() -} - -// UnimplementedShippingServiceServer must be embedded to have forward compatible implementations. -type UnimplementedShippingServiceServer struct { -} - -func (UnimplementedShippingServiceServer) GetQuote(context.Context, *GetQuoteRequest) (*GetQuoteResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetQuote not implemented") -} -func (UnimplementedShippingServiceServer) ShipOrder(context.Context, *ShipOrderRequest) (*ShipOrderResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ShipOrder not implemented") -} -func (UnimplementedShippingServiceServer) mustEmbedUnimplementedShippingServiceServer() {} - -// UnsafeShippingServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to ShippingServiceServer will -// result in compilation errors. -type UnsafeShippingServiceServer interface { - mustEmbedUnimplementedShippingServiceServer() -} - -func RegisterShippingServiceServer(s grpc.ServiceRegistrar, 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) -} - -// ShippingService_ServiceDesc is the grpc.ServiceDesc for ShippingService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#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.ClientConnInterface -} - -func NewCurrencyServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedCurrencyServiceServer -// for forward compatibility -type CurrencyServiceServer interface { - GetSupportedCurrencies(context.Context, *Empty) (*GetSupportedCurrenciesResponse, error) - Convert(context.Context, *CurrencyConversionRequest) (*Money, error) - mustEmbedUnimplementedCurrencyServiceServer() -} - -// UnimplementedCurrencyServiceServer must be embedded to have forward compatible implementations. -type UnimplementedCurrencyServiceServer struct { -} - -func (UnimplementedCurrencyServiceServer) GetSupportedCurrencies(context.Context, *Empty) (*GetSupportedCurrenciesResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetSupportedCurrencies not implemented") -} -func (UnimplementedCurrencyServiceServer) Convert(context.Context, *CurrencyConversionRequest) (*Money, error) { - return nil, status.Errorf(codes.Unimplemented, "method Convert not implemented") -} -func (UnimplementedCurrencyServiceServer) mustEmbedUnimplementedCurrencyServiceServer() {} - -// UnsafeCurrencyServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to CurrencyServiceServer will -// result in compilation errors. -type UnsafeCurrencyServiceServer interface { - mustEmbedUnimplementedCurrencyServiceServer() -} - -func RegisterCurrencyServiceServer(s grpc.ServiceRegistrar, 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) -} - -// CurrencyService_ServiceDesc is the grpc.ServiceDesc for CurrencyService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type PaymentServiceClient interface { - Charge(ctx context.Context, in *ChargeRequest, opts ...grpc.CallOption) (*ChargeResponse, error) -} - -type paymentServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewPaymentServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedPaymentServiceServer -// for forward compatibility -type PaymentServiceServer interface { - Charge(context.Context, *ChargeRequest) (*ChargeResponse, error) - mustEmbedUnimplementedPaymentServiceServer() -} - -// UnimplementedPaymentServiceServer must be embedded to have forward compatible implementations. -type UnimplementedPaymentServiceServer struct { -} - -func (UnimplementedPaymentServiceServer) Charge(context.Context, *ChargeRequest) (*ChargeResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Charge not implemented") -} -func (UnimplementedPaymentServiceServer) mustEmbedUnimplementedPaymentServiceServer() {} - -// UnsafePaymentServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to PaymentServiceServer will -// result in compilation errors. -type UnsafePaymentServiceServer interface { - mustEmbedUnimplementedPaymentServiceServer() -} - -func RegisterPaymentServiceServer(s grpc.ServiceRegistrar, 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) -} - -// PaymentService_ServiceDesc is the grpc.ServiceDesc for PaymentService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type EmailServiceClient interface { - SendOrderConfirmation(ctx context.Context, in *SendOrderConfirmationRequest, opts ...grpc.CallOption) (*Empty, error) -} - -type emailServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewEmailServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedEmailServiceServer -// for forward compatibility -type EmailServiceServer interface { - SendOrderConfirmation(context.Context, *SendOrderConfirmationRequest) (*Empty, error) - mustEmbedUnimplementedEmailServiceServer() -} - -// UnimplementedEmailServiceServer must be embedded to have forward compatible implementations. -type UnimplementedEmailServiceServer struct { -} - -func (UnimplementedEmailServiceServer) SendOrderConfirmation(context.Context, *SendOrderConfirmationRequest) (*Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method SendOrderConfirmation not implemented") -} -func (UnimplementedEmailServiceServer) mustEmbedUnimplementedEmailServiceServer() {} - -// UnsafeEmailServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to EmailServiceServer will -// result in compilation errors. -type UnsafeEmailServiceServer interface { - mustEmbedUnimplementedEmailServiceServer() -} - -func RegisterEmailServiceServer(s grpc.ServiceRegistrar, 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) -} - -// EmailService_ServiceDesc is the grpc.ServiceDesc for EmailService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type CheckoutServiceClient interface { - PlaceOrder(ctx context.Context, in *PlaceOrderRequest, opts ...grpc.CallOption) (*PlaceOrderResponse, error) -} - -type checkoutServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewCheckoutServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedCheckoutServiceServer -// for forward compatibility -type CheckoutServiceServer interface { - PlaceOrder(context.Context, *PlaceOrderRequest) (*PlaceOrderResponse, error) - mustEmbedUnimplementedCheckoutServiceServer() -} - -// UnimplementedCheckoutServiceServer must be embedded to have forward compatible implementations. -type UnimplementedCheckoutServiceServer struct { -} - -func (UnimplementedCheckoutServiceServer) PlaceOrder(context.Context, *PlaceOrderRequest) (*PlaceOrderResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method PlaceOrder not implemented") -} -func (UnimplementedCheckoutServiceServer) mustEmbedUnimplementedCheckoutServiceServer() {} - -// UnsafeCheckoutServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to CheckoutServiceServer will -// result in compilation errors. -type UnsafeCheckoutServiceServer interface { - mustEmbedUnimplementedCheckoutServiceServer() -} - -func RegisterCheckoutServiceServer(s grpc.ServiceRegistrar, 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) -} - -// CheckoutService_ServiceDesc is the grpc.ServiceDesc for CheckoutService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type AdServiceClient interface { - GetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error) -} - -type adServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewAdServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedAdServiceServer -// for forward compatibility -type AdServiceServer interface { - GetAds(context.Context, *AdRequest) (*AdResponse, error) - mustEmbedUnimplementedAdServiceServer() -} - -// UnimplementedAdServiceServer must be embedded to have forward compatible implementations. -type UnimplementedAdServiceServer struct { -} - -func (UnimplementedAdServiceServer) GetAds(context.Context, *AdRequest) (*AdResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetAds not implemented") -} -func (UnimplementedAdServiceServer) mustEmbedUnimplementedAdServiceServer() {} - -// UnsafeAdServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to AdServiceServer will -// result in compilation errors. -type UnsafeAdServiceServer interface { - mustEmbedUnimplementedAdServiceServer() -} - -func RegisterAdServiceServer(s grpc.ServiceRegistrar, 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) -} - -// AdService_ServiceDesc is the grpc.ServiceDesc for AdService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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", -} diff --git a/src/productcatalogservice/go.mod b/src/productcatalogservice/go.mod deleted file mode 100644 index 1b8c7d508..000000000 --- a/src/productcatalogservice/go.mod +++ /dev/null @@ -1,23 +0,0 @@ -module github.com/GoogleCloudPlatform/cloud-ops-sandbox/src/productcatalogservice - -go 1.16 - -require ( - cloud.google.com/go v0.61.0 - contrib.go.opencensus.io/exporter/stackdriver v0.13.0 - github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v0.20.0 - github.com/aws/aws-sdk-go v1.29.25 // indirect - github.com/golang/protobuf v1.5.2 - github.com/google/go-cmp v0.5.5 - github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect - github.com/sirupsen/logrus v1.4.2 - go.opencensus.io v0.22.4 - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0 - go.opentelemetry.io/otel v0.20.0 - go.opentelemetry.io/otel/sdk v0.20.0 - go.opentelemetry.io/otel/trace v0.20.0 - golang.org/x/net v0.0.0-20210614182718-04defd469f4e - google.golang.org/grpc v1.38.0 - google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 - google.golang.org/protobuf v1.26.0 -) diff --git a/src/productcatalogservice/go.sum b/src/productcatalogservice/go.sum deleted file mode 100644 index 8a78d6e97..000000000 --- a/src/productcatalogservice/go.sum +++ /dev/null @@ -1,453 +0,0 @@ -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.61.0 h1:NLQf5e1OMspfNT1RAHOB3ublr1TW3YTXO8OiWwVjK2U= -cloud.google.com/go v0.61.0/go.mod h1:XukKJg4Y7QsUu0Hxg3qQKUWR4VuWivmyMK2+rUyxAqw= -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/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/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= -contrib.go.opencensus.io/exporter/stackdriver v0.13.0 h1:Jaz7WbqjtfoCPa1KbfisCX+P5aM3DizEY9pQMU0oAQo= -contrib.go.opencensus.io/exporter/stackdriver v0.13.0/go.mod h1:z2tyTZtPmQ2HvWH4cOmVDgtY+1lomfKdbLnkJvZdc8c= -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/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v0.20.0 h1:ExGRyJwOUijAPv/RzCJ3p1CNUxBQGzVO238m1lFjLS4= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v0.20.0/go.mod h1:f4BFp2+kV6s/OKj3IP/34keB/OE7tTTaZZQyX/mQ7Ng= -github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.29.25 h1:03yt6K6vCxfxFHT7mXGqFeISsNDE27LO2u+5AQBnTzQ= -github.com/aws/aws-sdk-go v1.29.25/go.mod h1:1KvfttTE3SPKMpo8g2c6jL3ZKfXtFvKscTgahTma5Xg= -github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -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-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -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.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -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/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -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/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 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -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.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -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/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.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -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/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 h1:Ak8CrdlwwXwAZxzS66vgPt4U8yUZX7JwLvVR58FN5jM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -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/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleinterns/cloud-operations-api-mock v0.0.0-20200709193332-a1e58c29bdd3 h1:eHv/jVY/JNop1xg2J9cBb4EzyMpWZoNCP1BslSAIkOI= -github.com/googleinterns/cloud-operations-api-mock v0.0.0-20200709193332-a1e58c29bdd3/go.mod h1:h/KNeRx7oYU4SpA4SoY7W2/NxDKEEVuwA6j9A27L4OI= -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/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -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 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= -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/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -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/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/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.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -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= -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.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= -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 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opentelemetry.io/contrib v0.20.0 h1:ubFQUn0VCZ0gPwIoJfBJVpeBlyRMxu8Mm/huKWYd9p0= -go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0 h1:sO4WKdPAudZGKPcpZT4MJn6JaDmpyLrMPDGGyA1SttE= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0 h1:Q3C9yzW6I9jqEc8sawxzxZmY48fs9u220KXq6d5s3XU= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= -go.opentelemetry.io/otel v0.20.0 h1:eaP0Fqu7SXHwvjiqDq83zImeehOHX8doTvU9AwXON8g= -go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= -go.opentelemetry.io/otel/metric v0.20.0 h1:4kzhXFP+btKm4jwxpjIqjs41A7MakRFUS86bqLHTIw8= -go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= -go.opentelemetry.io/otel/oteltest v0.20.0 h1:HiITxCawalo5vQzdHfKeZurV8x7ljcqAgiWzF6Vaeaw= -go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= -go.opentelemetry.io/otel/sdk v0.20.0 h1:JsxtGXd06J8jrnya7fdI/U/MR6yXA5DtbZy+qoHQlr8= -go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= -go.opentelemetry.io/otel/trace v0.20.0 h1:1DL6EXUdcg95gukhuRRvLDO/4X5THh/5dIV52lqtnbw= -go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= -go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -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 h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/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 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= -golang.org/x/mod v0.3.0/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-20190923162816-aa69164e4478/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-20200602114024-627f9648deb9/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 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20210510120150-4163338589ed h1:p9UgmWI9wKpfYmgaV/IZKGdXc5qEK45tDwwwDyjS26I= -golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-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 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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-20190422165155-953cdadca894/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-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-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -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 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -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-20191010075000-0337d82405ff/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-20191108193012-7d206e10da11/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-20200701151220-7cb253f4c4f8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed h1:+qzWo37K31KxduIYaBeMqJ8MUOyTayOQKpH9aDPLMSY= -golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -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 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/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.10.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 h1:BaiDisFir8O4IJxvAabCGGkQ6yCJegNQqSVoYUNAnbk= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -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.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= -google.golang.org/appengine v1.6.6/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-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-20200605102947-12044bf5ea91/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200711021454-869866162049/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200715011427-11fb19a81f2c h1:6DWnZZ6EY/59QRRQttZKiktVL23UuQYs7uy75MhhLRM= -google.golang.org/genproto v0.0.0-20200715011427-11fb19a81f2c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -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.23.1/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.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= -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 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -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.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= diff --git a/src/productcatalogservice/products.json b/src/productcatalogservice/products.json deleted file mode 100644 index f41b2d9b2..000000000 --- a/src/productcatalogservice/products.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "products": [ - { - "id": "OLJCESPC7Z", - "name": "Vintage Typewriter", - "description": "This typewriter looks good in your living room.", - "picture": "/static/img/products/typewriter.jpg", - "priceUsd": { - "currencyCode": "USD", - "units": 67, - "nanos": 990000000 - }, - "categories": ["vintage"] - }, - { - "id": "66VCHSJNUP", - "name": "Vintage Camera Lens", - "description": "You won't have a camera to use it and it probably doesn't work anyway.", - "picture": "/static/img/products/camera-lens.jpg", - "priceUsd": { - "currencyCode": "USD", - "units": 12, - "nanos": 490000000 - }, - "categories": ["photography", "vintage"] - }, - { - "id": "1YMWWN1N4O", - "name": "Home Barista Kit", - "description": "Always wanted to brew coffee with Chemex and Aeropress at home?", - "picture": "/static/img/products/barista-kit.jpg", - "priceUsd": { - "currencyCode": "USD", - "units": 124 - }, - "categories": ["cookware"] - }, - { - "id": "L9ECAV7KIM", - "name": "Terrarium", - "description": "This terrarium will looks great in your white painted living room.", - "picture": "/static/img/products/terrarium.jpg", - "priceUsd": { - "currencyCode": "USD", - "units": 36, - "nanos": 450000000 - }, - "categories": ["gardening"] - }, - { - "id": "2ZYFJ3GM2N", - "name": "Film Camera", - "description": "This camera looks like it's a film camera, but it's actually digital.", - "picture": "/static/img/products/film-camera.jpg", - "priceUsd": { - "currencyCode": "USD", - "units": 2245 - }, - "categories": ["photography", "vintage"] - }, - { - "id": "0PUK6V6EV0", - "name": "Vintage Record Player", - "description": "It still works.", - "picture": "/static/img/products/record-player.jpg", - "priceUsd": { - "currencyCode": "USD", - "units": 65, - "nanos": 500000000 - }, - "categories": ["music", "vintage"] - }, - { - "id": "LS4PSXUNUM", - "name": "Metal Camping Mug", - "description": "You probably don't go camping that often but this is better than plastic cups.", - "picture": "/static/img/products/camp-mug.jpg", - "priceUsd": { - "currencyCode": "USD", - "units": 24, - "nanos": 330000000 - }, - "categories": ["cookware"] - }, - { - "id": "9SIQT8TOJO", - "name": "City Bike", - "description": "This single gear bike probably cannot climb the hills of San Francisco.", - "picture": "/static/img/products/city-bike.jpg", - "priceUsd": { - "currencyCode": "USD", - "units": 789, - "nanos": 500000000 - }, - "categories": ["cycling"] - }, - { - "id": "6E92ZMYYFZ", - "name": "Air Plant", - "description": "Have you ever wondered whether air plants need water? Buy one and figure out.", - "picture": "/static/img/products/air-plant.jpg", - "priceUsd": { - "currencyCode": "USD", - "units": 12, - "nanos": 300000000 - }, - "categories": ["gardening"] - } - ] -} diff --git a/src/productcatalogservice/server.go b/src/productcatalogservice/server.go deleted file mode 100644 index 5f06df954..000000000 --- a/src/productcatalogservice/server.go +++ /dev/null @@ -1,310 +0,0 @@ -// 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/cloud-ops-sandbox/src/productcatalogservice/genproto" - healthpb "google.golang.org/grpc/health/grpc_health_v1" - - "cloud.google.com/go/profiler" - "contrib.go.opencensus.io/exporter/stackdriver" - "contrib.go.opencensus.io/exporter/stackdriver/monitoredresource" - "github.com/golang/protobuf/jsonpb" - "github.com/sirupsen/logrus" - "go.opencensus.io/examples/exporter" - "go.opencensus.io/plugin/ocgrpc" - "go.opencensus.io/stats" - "go.opencensus.io/stats/view" - - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - // OpenTelemetry - // OTel traces -> GCP Trace direct exporter - texporter "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace" - "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/sdk/resource" - sdktrace "go.opentelemetry.io/otel/sdk/trace" - "go.opentelemetry.io/otel/semconv" - apitrace "go.opentelemetry.io/otel/trace" -) - -var ( - cat pb.ListProductsResponse - catalogMutex *sync.Mutex - log *logrus.Logger - extraLatency time.Duration - - port = flag.Int("port", 3550, "port to listen at") - reloadCatalog bool - - videoSize = stats.Int64("my.org/measure/video_size", "size of processed videos", stats.UnitBytes) -) - -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() { - initOpenCensusStats() - initTraceProvider() - go initProfiling("productcatalogservice", "1.0.0") - 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(2) - } - - 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") - } - } - }() - - log.Infof("starting grpc server at :%d", *port) - run(*port) - select {} -} - -func run(port int) string { - l, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) - if err != nil { - log.Fatal(err) - } - - intercepterOpt := otelgrpc.WithTracerProvider(otel.GetTracerProvider()) - srv := grpc.NewServer( - grpc.StatsHandler(&ocgrpc.ServerHandler{}), // TODO: replace with OTel grpc metrics collector - // OpenTelemetry gRPC server channel interceptors receive trace contexts from clients. - grpc.UnaryInterceptor(otelgrpc.UnaryServerInterceptor(intercepterOpt)), - grpc.StreamInterceptor(otelgrpc.StreamServerInterceptor(intercepterOpt)), - ) - svc := &productCatalog{} - pb.RegisterProductCatalogServiceServer(srv, svc) - healthpb.RegisterHealthServer(srv, svc) - go srv.Serve(l) - return l.Addr().String() -} - -// Initialize Stats using OpenCensus -// TODO: remove this after conversion to using OpenTelemetry Metrics -func initOpenCensusStats() { - for i := 1; i <= 3; i++ { - view.RegisterExporter(&exporter.PrintExporter{}) - exporter, err := stackdriver.NewExporter(stackdriver.Options{ - ProjectID: "test-exemplar-project", - MonitoredResource: monitoredresource.Autodetect(), - ReportingInterval: 60 * time.Second, - }) - if err != nil { - log.Warnf("failed to initialize stackdriver exporter: %+v", err) - } else { - exporter.StartMetricsExporter() - if err := view.Register(ocgrpc.DefaultServerViews...); err != nil { - log.Info("Error registering default grpc server views") - } else { - log.Info("Registered default grpc server views") - } - 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") -} - -// Initialize OTel trace provider that exports to Cloud Trace -func initTraceProvider() { - // When running on GCP, authentication is handled automatically - // using default credentials. This environment variable check - // is to help debug projects running locally. It's possible for this - // warning to be printed while the exporter works normally. See - // https://developers.google.com/identity/protocols/application-default-credentials - // for more details. - projectID := os.Getenv("GOOGLE_CLOUD_PROJECT") - if len(projectID) == 0 { - log.Warn("GOOGLE_CLOUD_PROJECT not set") - } - for i := 1; i <= 3; i++ { - exporter, err := texporter.NewExporter(texporter.WithProjectID(projectID)) - if err != nil { - log.Infof("failed to initialize exporter: %v", err) - } else { - // Create trace provider with the exporter. - // The AlwaysSample sampling policy is used here for demonstration - // purposes and should not be used in production environments. - tp := sdktrace.NewTracerProvider( - sdktrace.WithSampler(sdktrace.AlwaysSample()), - sdktrace.WithSyncer(exporter), - // TODO: replace with predefined constant for GKE or autodetection when available - sdktrace.WithResource(resource.NewWithAttributes(semconv.ServiceNameKey.String("GKE")))) - if err == nil { - log.Info("initialized trace provider") - otel.SetTracerProvider(tp) - return - } else { - d := time.Second * 10 * time.Duration(i) - log.Infof("sleeping %v to retry initializing trace provider", d) - time.Sleep(d) - } - } - - } - log.Warn("failed to initialize trace provider") -} - -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 { - pb.UnimplementedProductCatalogServiceServer -} - -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, srv healthpb.Health_WatchServer) error { - return nil -} - -func (p *productCatalog) ListProducts(ctx context.Context, _ *pb.Empty) (*pb.ListProductsResponse, error) { - span := apitrace.SpanFromContext(ctx) - span.AddEvent("List Products") - time.Sleep(extraLatency) - return &pb.ListProductsResponse{Products: parseCatalog()}, nil -} - -func (p *productCatalog) GetProduct(ctx context.Context, req *pb.GetProductRequest) (*pb.Product, error) { - span := apitrace.SpanFromContext(ctx) - span.AddEvent(fmt.Sprintf("Get Product %v", req.Id)) - log.Info("DEBUG successfully get product ") - 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 %v", 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 -} diff --git a/src/productcatalogservice/server_test.go b/src/productcatalogservice/server_test.go deleted file mode 100644 index bf666e6e7..000000000 --- a/src/productcatalogservice/server_test.go +++ /dev/null @@ -1,68 +0,0 @@ -// 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/cloud-ops-sandbox/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(0) - conn, err := grpc.Dial(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: "typewriter"}) - if err != nil { - t.Fatal(err) - } - if diff := cmp.Diff(sres.Results, []*pb.Product{parseCatalog()[0]}, cmp.Comparer(proto.Equal)); diff != "" { - t.Error(diff) - } -} diff --git a/src/productcatalogservice/tools.go b/src/productcatalogservice/tools.go deleted file mode 100644 index 0600f7bb9..000000000 --- a/src/productcatalogservice/tools.go +++ /dev/null @@ -1,22 +0,0 @@ -// 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. - -// +build tools - -package main - -import ( - _ "google.golang.org/grpc/cmd/protoc-gen-go-grpc" - _ "google.golang.org/protobuf/cmd/protoc-gen-go" -) diff --git a/src/ratingservice/README.md b/src/ratingservice/README.md deleted file mode 100644 index 0df7b2d02..000000000 --- a/src/ratingservice/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# Rating Service - -Rating Service is a microservice in Python developed to run on App Engine Standard Environment. -It manages ratings of the Hipster shop products graded in scale from 1 to 5. -The collection of pairs {entity id, rating} are stored in Postgres database managed by Cloud SQL. -The service exposes GET APIs to get a collection of all managed ratings or to get a rating of the specific product. -It is possible to submit a new vote for the product's rating. New vote get recollected on demand and the new product rating is calculated as an average of the current rating and all submitted votes. -The vote recollection is implemented as a scheduled task (using Cloud Schedule) which is triggered each two minutes. - -## Deployment - -The service is deployed using Terraform module [ratingservice](../../terraform/ratingservice). -To deploy the service during development you should generate `app.yaml` file with the following parameters: - -```yaml -``` - -A template of the file can be found in the [ratingservice](../../terraform/ratingservice) folder. - -## Testing - -Rating service [e2e test](../../tests/ratingservice) verifies API correctness. To launch it manually, use the following command: - -```bash -python3 main_test.py $SERVICE_URL $PATH_TO_PRODUCTS_JSON -``` - -where `SERVICE_URL` is a root URL of the rating service and `PATH_TO_PRODUCTS_YAML` is a local path to `product.json` file location. diff --git a/src/ratingservice/main.py b/src/ratingservice/main.py deleted file mode 100644 index d4b93e798..000000000 --- a/src/ratingservice/main.py +++ /dev/null @@ -1,243 +0,0 @@ -# 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. - -import os -from flask import Flask, jsonify, request -from psycopg2 import pool, DatabaseError, IntegrityError -# enable GCP debugger when not running locally -if __name__ != "__main__": - try: - import googleclouddebugger - googleclouddebugger.enable( - breakpoint_enable_canary=False - ) - except ImportError: - pass - - -# If `entrypoint` is not defined in app.yaml, App Engine will look for an app -# called `app` in `main.py`. -db_connection_pool = None - -app = Flask(__name__) -db_user = os.environ.get('DB_USERNAME') -db_name = os.environ.get('DB_NAME') -db_pass = os.environ.get('DB_PASSWORD') -db_host = os.environ.get('DB_HOST') -if not all([db_name, db_user, db_pass, db_host]): - print('error: environment vars DB_USERNAME, DB_PASSWORD, DB_NAME and DB_HOST must be defined.') - exit(1) -if os.environ.get('GAE_ENV') == 'standard': - db_host = '/cloudsql/{}'.format(db_host) - - -def getConnection(): - global db_connection_pool - if db_connection_pool == None: - cfg = { - 'user': db_user, - 'password': db_pass, - 'database': db_name, - 'host': db_host - } - max_connections = int(os.getenv("MAX_DB_CONNECTIONS", "10")) - try: - db_connection_pool = pool.SimpleConnectionPool( - minconn=1, maxconn=max_connections, **cfg) - except (Exception, DatabaseError) as error: - print(error) - return None - return db_connection_pool.getconn() - - -def makeError(code, message): - result = jsonify({'error': message}) - result.status_code = code - return result - - -def makeResult(data): - result = jsonify(data) - result.status_code = 200 - return result - -# -# APIs -# - -@app.route('/_ah/warmup') -def warmup(): - '''Handles App Engine warmup logic - ''' - conn = getConnection() - if conn is not None: - db_connection_pool.putconn(conn) - return '', 200, {} - - -@app.route('/ratings', methods=['GET']) -def getRatings(): - '''Gets a list of all ratings. - - Returns: - HTTP status 200 and Json payload { ratings: [{'id': (string), 'rating': (number)}] } - HTTP status 500 when there is an error querying DB or no data - ''' - - conn = getConnection() - if conn == None: - return makeError(500, 'failed to connect to DB') - try: - with conn.cursor() as cursor: - cursor.execute("SELECT eid, ROUND(rating,4) FROM ratings") - result = cursor.fetchall() - conn.commit() - if result is not None: - # cast to float because flask.jsonify doesn't work with decimal - ratings = [{"id": eid.strip(), "rating": float(rating)} - for (eid, rating) in result] - return makeResult({ - 'ratings': ratings, - }) - else: - return makeError(500, 'No available ratings') - except DatabaseError: - return makeError(500, 'DB error') - finally: - db_connection_pool.putconn(conn) - - -@app.route('/rating/', methods=['GET']) -def getRatingById(eid): - '''Gets rating of the entity by its id. - - Args: - eid (string): the entity id. - - Returns: - HTTP status 200 and Json payload { 'id': (string), 'rating': (number), 'votes': (int) } - HTTP status 400 when eid is is missing or invalid - HTTP status 404 when rating for eid cannot be found - HTTP status 500 when there is an error querying DB - ''' - - if not eid: - return makeError(400, "malformed entity id") - conn = getConnection() - if conn == None: - return makeError(500, 'failed to connect to DB') - try: - with conn.cursor() as cursor: - cursor.execute( - "SELECT ROUND(rating,4), votes FROM ratings WHERE eid=%s", (eid,)) - result = cursor.fetchone() - conn.commit() - if result != None: - return makeResult({ - 'id': eid, - # cast to float because flas.jsonify doesn't work with decimal - 'rating': float(result[0]), - 'votes': result[1] - }) - else: - return makeError(404, "invalid entity id") - except DatabaseError: - return makeError(500, 'DB error') - finally: - db_connection_pool.putconn(conn) - - -@app.route('/rating', methods=['POST']) -def postRating(): - '''Adds new vote for entity's rating. - - Args: - Json payload {'id': (string), 'rating': (integer) } - - Returns: - HTTP status 200 and empty Json payload { } - HTTP status 400 when payload is malformed (e.g. missing expected field) - HTTP status 400 when eid is missing or invalid or rating is missing, invalid or out of [1..5] range - HTTP status 404 when rating for eid cannot be reported - HTTP status 500 when there is an error querying DB - ''' - - data = request.get_json() - if data == None: - return makeError(400, "missing json payload") - eid = data.get('id') - if not eid: - return makeError(400, "malformed entity id") - rating = 0 - try: - rating = int(data['rating']) - except KeyError: - return makeError(400, "missing 'rating' field in payload") - except ValueError: - return makeError(400, "rating should be integer number") - if rating < 1 or rating > 5: - return makeError(400, "rating should be value between 1 and 5") - - conn = getConnection() - if conn == None: - return makeError(500, 'failed to connect to DB') - try: - with conn.cursor() as cursor: - cursor.execute( - "INSERT INTO votes (eid, rating) VALUES (%s, %s)", (str(eid), rating)) - conn.commit() - return makeResult({}) - except IntegrityError: - return makeError(404, 'invalid entity id') - except DatabaseError: - return makeError(500, 'DB error') - finally: - db_connection_pool.putconn(conn) - - -@ app.route('/ratings:recollect', methods=['POST']) -def aggregateRatings(): - '''Updates current ratings for all entities based on new votes received until now. - - Returns: - HTTP status 200 and empty Json payload { } - HTTP status 500 when there is an error querying DB - ''' - conn = getConnection() - if conn == None: - return makeError(500, 'failed to connect to DB') - try: - with conn.cursor() as cursor: - cursor.execute("UPDATE votes SET in_process=TRUE") - cursor.execute( - "UPDATE ratings AS r SET " - "rating=(r.rating*r.votes/(r.votes+v.votes))+(v.avg_rating*v.votes/(r.votes+v.votes)), " - "votes=r.votes+v.votes " - "FROM (SELECT eid, ROUND(AVG(rating),4) AS avg_rating, COUNT(eid) AS votes FROM votes WHERE in_process=TRUE GROUP BY eid) AS v " - "WHERE r.eid = v.eid") - cursor.execute("DELETE FROM votes WHERE in_process=TRUE") - conn.commit() - return makeResult({}) - except DatabaseError: - return makeError(500, 'DB error') - finally: - db_connection_pool.putconn(conn) - return resp - - -if __name__ == "__main__": - # Used when running locally only. When deploying to Google App - # Engine, a webserver process such as Gunicorn will serve the app. This - # can be configured by adding an `entrypoint` to app.yaml. - app.run(host="localhost", port=8080, debug=True) diff --git a/src/ratingservice/pong.py b/src/ratingservice/pong.py deleted file mode 100644 index 6824cfeaa..000000000 --- a/src/ratingservice/pong.py +++ /dev/null @@ -1,30 +0,0 @@ -# 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 flask import Flask - -app = Flask(__name__) - - -@app.route('/', methods=['GET']) -def pingpong(): - """Return ping pong.""" - return 'pong' - - -if __name__ == "__main__": - # Used when running locally only. When deploying to Google App - # Engine, a webserver process such as Gunicorn will serve the app. This - # can be configured by adding an `entrypoint` to app.yaml. - app.run(host="localhost", port=8080, debug=True) diff --git a/src/ratingservice/requirements.txt b/src/ratingservice/requirements.txt deleted file mode 100644 index cdd0052d2..000000000 --- a/src/ratingservice/requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ -uwsgi==2.0.20 -flask==2.1.2 -psycopg2-binary==2.9.3 -google-python-cloud-debugger==2.18 -# pyparsing pin solves related issue: https://github.com/GoogleCloudPlatform/cloud-ops-sandbox/issues/877 -pyparsing==2.4.7 diff --git a/src/recommendationservice/.gitignore b/src/recommendationservice/.gitignore deleted file mode 100644 index 0d20b6487..000000000 --- a/src/recommendationservice/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/src/recommendationservice/Dockerfile b/src/recommendationservice/Dockerfile deleted file mode 100644 index 264cf16b6..000000000 --- a/src/recommendationservice/Dockerfile +++ /dev/null @@ -1,44 +0,0 @@ -# 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 -RUN apt-get update -qqy && \ - apt-get -qqy install wget && \ - 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.3.5 && \ - 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 - -# install gcc (not included in slim image) -RUN apt-get update \ -&& apt-get install gcc g++ -y \ -&& apt-get clean - -# 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"] diff --git a/src/recommendationservice/client.py b/src/recommendationservice/client.py deleted file mode 100644 index f55071c6b..000000000 --- a/src/recommendationservice/client.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/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 as oc_client_interceptor - -from opentelemetry import trace -from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter -from opentelemetry.ext.grpc import client_interceptor -from opentelemetry.ext.grpc.grpcext import intercept_channel -from opentelemetry.sdk.trace import TracerProvider -from opentelemetry.sdk.trace.export import SimpleExportSpanProcessor - -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" - - # TODO: remove OpenCensus after conversion to OpenTelemetry - try: - exporter = stackdriver_exporter.StackdriverExporter() - tracer = Tracer(exporter=exporter) - oc_interceptor = oc_client_interceptor.OpenCensusClientInterceptor(tracer, host_port='localhost:'+port) - except: - oc_interceptor = oc_client_interceptor.OpenCensusClientInterceptor() - - # OpenTelemetry Tracing - trace.set_tracer_provider(TracerProvider()) - - cloud_trace_exporter = CloudTraceSpanExporter() - trace.get_tracer_provider().add_span_processor( - SimpleExportSpanProcessor(cloud_trace_exporter) - ) - - # set up server stub - channel = grpc.insecure_channel('localhost:'+port) - channel = intercept_channel(channel, client_interceptor(trace.get_tracer_provider())) - 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) diff --git a/src/recommendationservice/demo_pb2.py b/src/recommendationservice/demo_pb2.py deleted file mode 100644 index 430dee261..000000000 --- a/src/recommendationservice/demo_pb2.py +++ /dev/null @@ -1,1802 +0,0 @@ -# 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. - -# 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) diff --git a/src/recommendationservice/demo_pb2_grpc.py b/src/recommendationservice/demo_pb2_grpc.py deleted file mode 100644 index a51a2a080..000000000 --- a/src/recommendationservice/demo_pb2_grpc.py +++ /dev/null @@ -1,516 +0,0 @@ -# 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. - -# 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,)) diff --git a/src/recommendationservice/genproto.sh b/src/recommendationservice/genproto.sh deleted file mode 100755 index 3f3b1e6a6..000000000 --- a/src/recommendationservice/genproto.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/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. - -#!/bin/bash -set -e - -# 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 diff --git a/src/recommendationservice/logger.py b/src/recommendationservice/logger.py deleted file mode 100644 index 5ecf27993..000000000 --- a/src/recommendationservice/logger.py +++ /dev/null @@ -1,45 +0,0 @@ -#!/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 get_json_logger(name): - logger = logging.getLogger(name) - handler = logging.StreamHandler(sys.stdout) - formatter = CustomJsonFormatter( - '%(timestamp)s %(severity)s %(name)s %(message)s') - handler.setFormatter(formatter) - logger.addHandler(handler) - logger.setLevel(logging.INFO) - return logger diff --git a/src/recommendationservice/recommendation_server.py b/src/recommendationservice/recommendation_server.py deleted file mode 100644 index 1bbff21e2..000000000 --- a/src/recommendationservice/recommendation_server.py +++ /dev/null @@ -1,139 +0,0 @@ -#!/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 grpc -from grpc_health.v1 import health_pb2, health_pb2_grpc -from opentelemetry import propagate, trace -from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter -from opentelemetry.instrumentation.grpc import (client_interceptor, - server_interceptor) -from opentelemetry.instrumentation.grpc.grpcext import intercept_channel -from opentelemetry.propagators.cloud_trace_propagator import \ - CloudTraceFormatPropagator -from opentelemetry.sdk.trace import TracerProvider -from opentelemetry.sdk.trace.export import SimpleSpanProcessor - -import demo_pb2 -import demo_pb2_grpc -from logger import get_json_logger - -logger = get_json_logger('recommendationservice-server') - -try: - import googleclouddebugger - googleclouddebugger.enable( - module='recommendationservice', - version='1.0.0' - ) -except ImportError: - logger.error("could not enable debugger") - logger.error(traceback.print_exc()) - pass - - -class RecommendationService(demo_pb2_grpc.RecommendationServiceServicer): - def ListRecommendations(self, request, context): - try: - # number of responses configurable by env var. defaults to 5 - max_responses = int(os.environ.get("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 - except Exception as e: - # if an exception occurred, make sure it is printed before raising - logger.error(e) - raise - - 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") - - # OpenTelemetry Tracing - # TracerProvider provides global state and access to tracers. - trace.set_tracer_provider(TracerProvider()) - - # Export traces to Google Cloud Trace - # When running on GCP, the exporter handles authentication - # using automatically default application credentials. - # When running locally, credentials may need to be set explicitly. - trace.get_tracer_provider().add_span_processor( - SimpleSpanProcessor(CloudTraceSpanExporter()) - ) - propagate.set_global_textmap(CloudTraceFormatPropagator()) - - 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) - - # Create the gRPC client channel to ProductCatalog (server). - channel = grpc.insecure_channel(catalog_addr) - - # OpenTelemetry client interceptor passes trace contexts to the server. - channel = intercept_channel( - channel, client_interceptor(trace.get_tracer_provider())) - product_catalog_stub = demo_pb2_grpc.ProductCatalogServiceStub(channel) - - # Create the gRPC server for accepting ListRecommendations Requests from frontend (client). - interceptor = server_interceptor(trace.get_tracer_provider()) - server = grpc.server(futures.ThreadPoolExecutor(max_workers=10), - interceptors=(interceptor,)) - - # Add RecommendationService 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) diff --git a/src/recommendationservice/requirements.in b/src/recommendationservice/requirements.in deleted file mode 100644 index b9248bc5d..000000000 --- a/src/recommendationservice/requirements.in +++ /dev/null @@ -1,15 +0,0 @@ -google-api-core==1.26.3 -google-python-cloud-debugger==2.17 -grpcio-health-checking==1.33.2 -grpcio==1.36.1 -opentelemetry-api==1.0 -opentelemetry-sdk==1.0 -opentelemetry-exporter-gcp-trace==1.0.0 -opentelemetry-propagator-gcp==1.0.0 -opentelemetry-instrumentation-grpc==0.19b0 -opentelemetry-instrumentation==0.19b0 -python-json-logger==0.1.11 -requests==2.25.1 -wrapt==1.12.1 -httplib2==0.19.0 -urllib3==1.26.5 diff --git a/src/recommendationservice/requirements.txt b/src/recommendationservice/requirements.txt deleted file mode 100644 index 1fb34bb11..000000000 --- a/src/recommendationservice/requirements.txt +++ /dev/null @@ -1,44 +0,0 @@ -# -# This file is autogenerated by pip-compile -# To update, run: -# -# pip-compile -# -cachetools==4.2.2 # via google-auth -certifi==2020.12.5 # via requests -chardet==3.0.4 # via requests -google-api-core[grpc]==1.26.3 # via -r requirements.in, google-api-python-client, google-cloud-core, google-cloud-trace, google-python-cloud-debugger -google-api-python-client==1.12.8 # via google-python-cloud-debugger -google-auth-httplib2==0.0.4 # via google-api-python-client, google-python-cloud-debugger -google-auth==1.24.0 # via google-api-core, google-api-python-client, google-auth-httplib2, google-python-cloud-debugger -google-cloud-core==1.5.0 # via google-cloud-trace -google-cloud-trace==0.24.0 # via opentelemetry-exporter-gcp-trace -google-python-cloud-debugger==2.17 # via -r requirements.in -googleapis-common-protos==1.52.0 # via google-api-core -grpcio-health-checking==1.33.2 # via -r requirements.in -grpcio==1.36.1 # via -r requirements.in, google-api-core, grpcio-health-checking, opentelemetry-instrumentation-grpc -httplib2==0.19.0 # via -r requirements.in, google-api-python-client, google-auth-httplib2 -idna==2.10 # via requests -opentelemetry-api==1.0.0 # via -r requirements.in, opentelemetry-exporter-gcp-trace, opentelemetry-instrumentation, opentelemetry-instrumentation-grpc, opentelemetry-propagator-gcp, opentelemetry-sdk -opentelemetry-exporter-gcp-trace==1.0.0 # via -r requirements.in -opentelemetry-instrumentation-grpc==0.19b0 # via -r requirements.in -opentelemetry-instrumentation==0.19b0 # via -r requirements.in, opentelemetry-instrumentation-grpc -opentelemetry-propagator-gcp==1.0.0 # via -r requirements.in -opentelemetry-sdk==1.0.0 # via -r requirements.in, opentelemetry-exporter-gcp-trace, opentelemetry-instrumentation-grpc -packaging==20.9 # via google-api-core -protobuf==3.13.0 # via google-api-core, googleapis-common-protos, grpcio-health-checking -pyasn1-modules==0.2.8 # via google-auth -pyasn1==0.4.8 # via pyasn1-modules, rsa -pyparsing==2.4.7 # via httplib2, packaging -python-json-logger==0.1.11 # via -r requirements.in -pytz==2018.9 # via google-api-core -pyyaml==5.4.1 # via google-python-cloud-debugger -requests==2.25.1 # via -r requirements.in, google-api-core -rsa==4.7 # via google-auth -six==1.15.0 # via google-api-core, google-api-python-client, google-auth, google-auth-httplib2, google-cloud-core, google-python-cloud-debugger, grpcio, protobuf -uritemplate==3.0.1 # via google-api-python-client -urllib3==1.26.5 # via -r requirements.in, requests -wrapt==1.12.1 # via -r requirements.in, opentelemetry-instrumentation, opentelemetry-instrumentation-grpc - -# The following packages are considered to be unsafe in a requirements file: -# setuptools diff --git a/src/shippingservice/.dockerignore b/src/shippingservice/.dockerignore deleted file mode 100644 index 48b8bf907..000000000 --- a/src/shippingservice/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -vendor/ diff --git a/src/shippingservice/Dockerfile b/src/shippingservice/Dockerfile deleted file mode 100644 index bdd98d62c..000000000 --- a/src/shippingservice/Dockerfile +++ /dev/null @@ -1,34 +0,0 @@ -# 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.16-alpine as builder -RUN apk add --no-cache ca-certificates git -ENV PROJECT github.com/GoogleCloudPlatform/cloud-ops-sandbox/src/shippingservice -WORKDIR /go/src/$PROJECT - -# restore dependencies -COPY go.mod go.sum main.go quote.go tracker.go ./ -COPY genproto ./genproto/ -RUN go mod vendor -v -RUN go build -gcflags='-N -l' -o /shippingservice - -FROM alpine as release -RUN apk add --no-cache ca-certificates -RUN GRPC_HEALTH_PROBE_VERSION=v0.4.2 && \ - 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 -COPY --from=builder /shippingservice /shippingservice -ENV APP_PORT=50051 -EXPOSE 50051 -ENTRYPOINT ["/shippingservice"] diff --git a/src/shippingservice/README.md b/src/shippingservice/README.md deleted file mode 100644 index 9960dc373..000000000 --- a/src/shippingservice/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# 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: - - go mod vendor -v - -## Build - -From repository root, run: - -``` -docker build --file src/shippingservice/Dockerfile . -``` - -## Test - -``` -go test . -``` diff --git a/src/shippingservice/genproto.sh b/src/shippingservice/genproto.sh deleted file mode 100755 index 3a8b26eff..000000000 --- a/src/shippingservice/genproto.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/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. - -#!/bin/bash -e - -PATH=$PATH:$(go env GOPATH)/bin -protodir=../../pb - -protoc --go_out=genproto --go-grpc_out=genproto -I $protodir $protodir/demo.proto diff --git a/src/shippingservice/genproto/demo.pb.go b/src/shippingservice/genproto/demo.pb.go deleted file mode 100644 index d3ef85c1c..000000000 --- a/src/shippingservice/genproto/demo.pb.go +++ /dev/null @@ -1,2607 +0,0 @@ -// 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. -// versions: -// protoc-gen-go v1.26.0 -// protoc v3.12.4 -// source: demo.proto - -package hipstershop - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type CartItem struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *CartItem) Reset() { - *x = CartItem{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CartItem) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CartItem) ProtoMessage() {} - -func (x *CartItem) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CartItem.ProtoReflect.Descriptor instead. -func (*CartItem) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{0} -} - -func (x *CartItem) GetProductId() string { - if x != nil { - return x.ProductId - } - return "" -} - -func (x *CartItem) GetQuantity() int32 { - if x != nil { - return x.Quantity - } - return 0 -} - -type AddItemRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *AddItemRequest) Reset() { - *x = AddItemRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AddItemRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AddItemRequest) ProtoMessage() {} - -func (x *AddItemRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AddItemRequest.ProtoReflect.Descriptor instead. -func (*AddItemRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{1} -} - -func (x *AddItemRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -func (x *AddItemRequest) GetItem() *CartItem { - if x != nil { - return x.Item - } - return nil -} - -type EmptyCartRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` -} - -func (x *EmptyCartRequest) Reset() { - *x = EmptyCartRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *EmptyCartRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EmptyCartRequest) ProtoMessage() {} - -func (x *EmptyCartRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use EmptyCartRequest.ProtoReflect.Descriptor instead. -func (*EmptyCartRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{2} -} - -func (x *EmptyCartRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -type GetCartRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` -} - -func (x *GetCartRequest) Reset() { - *x = GetCartRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetCartRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetCartRequest) ProtoMessage() {} - -func (x *GetCartRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetCartRequest.ProtoReflect.Descriptor instead. -func (*GetCartRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{3} -} - -func (x *GetCartRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -type Cart struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *Cart) Reset() { - *x = Cart{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Cart) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Cart) ProtoMessage() {} - -func (x *Cart) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Cart.ProtoReflect.Descriptor instead. -func (*Cart) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{4} -} - -func (x *Cart) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -func (x *Cart) GetItems() []*CartItem { - if x != nil { - return x.Items - } - return nil -} - -type Empty struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *Empty) Reset() { - *x = Empty{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Empty) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Empty) ProtoMessage() {} - -func (x *Empty) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Empty.ProtoReflect.Descriptor instead. -func (*Empty) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{5} -} - -type ListRecommendationsRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *ListRecommendationsRequest) Reset() { - *x = ListRecommendationsRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListRecommendationsRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListRecommendationsRequest) ProtoMessage() {} - -func (x *ListRecommendationsRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListRecommendationsRequest.ProtoReflect.Descriptor instead. -func (*ListRecommendationsRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{6} -} - -func (x *ListRecommendationsRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -func (x *ListRecommendationsRequest) GetProductIds() []string { - if x != nil { - return x.ProductIds - } - return nil -} - -type ListRecommendationsResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ProductIds []string `protobuf:"bytes,1,rep,name=product_ids,json=productIds,proto3" json:"product_ids,omitempty"` -} - -func (x *ListRecommendationsResponse) Reset() { - *x = ListRecommendationsResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListRecommendationsResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListRecommendationsResponse) ProtoMessage() {} - -func (x *ListRecommendationsResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListRecommendationsResponse.ProtoReflect.Descriptor instead. -func (*ListRecommendationsResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{7} -} - -func (x *ListRecommendationsResponse) GetProductIds() []string { - if x != nil { - return x.ProductIds - } - return nil -} - -type Product struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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 "vintage" or "gardening" that can be used to look up - // other related products. - Categories []string `protobuf:"bytes,6,rep,name=categories,proto3" json:"categories,omitempty"` -} - -func (x *Product) Reset() { - *x = Product{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Product) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Product) ProtoMessage() {} - -func (x *Product) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Product.ProtoReflect.Descriptor instead. -func (*Product) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{8} -} - -func (x *Product) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Product) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Product) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} - -func (x *Product) GetPicture() string { - if x != nil { - return x.Picture - } - return "" -} - -func (x *Product) GetPriceUsd() *Money { - if x != nil { - return x.PriceUsd - } - return nil -} - -func (x *Product) GetCategories() []string { - if x != nil { - return x.Categories - } - return nil -} - -type ListProductsResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Products []*Product `protobuf:"bytes,1,rep,name=products,proto3" json:"products,omitempty"` -} - -func (x *ListProductsResponse) Reset() { - *x = ListProductsResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListProductsResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListProductsResponse) ProtoMessage() {} - -func (x *ListProductsResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListProductsResponse.ProtoReflect.Descriptor instead. -func (*ListProductsResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{9} -} - -func (x *ListProductsResponse) GetProducts() []*Product { - if x != nil { - return x.Products - } - return nil -} - -type GetProductRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` -} - -func (x *GetProductRequest) Reset() { - *x = GetProductRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetProductRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetProductRequest) ProtoMessage() {} - -func (x *GetProductRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetProductRequest.ProtoReflect.Descriptor instead. -func (*GetProductRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{10} -} - -func (x *GetProductRequest) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -type SearchProductsRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` -} - -func (x *SearchProductsRequest) Reset() { - *x = SearchProductsRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SearchProductsRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SearchProductsRequest) ProtoMessage() {} - -func (x *SearchProductsRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SearchProductsRequest.ProtoReflect.Descriptor instead. -func (*SearchProductsRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{11} -} - -func (x *SearchProductsRequest) GetQuery() string { - if x != nil { - return x.Query - } - return "" -} - -type SearchProductsResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Results []*Product `protobuf:"bytes,1,rep,name=results,proto3" json:"results,omitempty"` -} - -func (x *SearchProductsResponse) Reset() { - *x = SearchProductsResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SearchProductsResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SearchProductsResponse) ProtoMessage() {} - -func (x *SearchProductsResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SearchProductsResponse.ProtoReflect.Descriptor instead. -func (*SearchProductsResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{12} -} - -func (x *SearchProductsResponse) GetResults() []*Product { - if x != nil { - return x.Results - } - return nil -} - -type GetQuoteRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Address *Address `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` - Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` -} - -func (x *GetQuoteRequest) Reset() { - *x = GetQuoteRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetQuoteRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetQuoteRequest) ProtoMessage() {} - -func (x *GetQuoteRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetQuoteRequest.ProtoReflect.Descriptor instead. -func (*GetQuoteRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{13} -} - -func (x *GetQuoteRequest) GetAddress() *Address { - if x != nil { - return x.Address - } - return nil -} - -func (x *GetQuoteRequest) GetItems() []*CartItem { - if x != nil { - return x.Items - } - return nil -} - -type GetQuoteResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - CostUsd *Money `protobuf:"bytes,1,opt,name=cost_usd,json=costUsd,proto3" json:"cost_usd,omitempty"` -} - -func (x *GetQuoteResponse) Reset() { - *x = GetQuoteResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetQuoteResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetQuoteResponse) ProtoMessage() {} - -func (x *GetQuoteResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetQuoteResponse.ProtoReflect.Descriptor instead. -func (*GetQuoteResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{14} -} - -func (x *GetQuoteResponse) GetCostUsd() *Money { - if x != nil { - return x.CostUsd - } - return nil -} - -type ShipOrderRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Address *Address `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` - Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` -} - -func (x *ShipOrderRequest) Reset() { - *x = ShipOrderRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ShipOrderRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ShipOrderRequest) ProtoMessage() {} - -func (x *ShipOrderRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ShipOrderRequest.ProtoReflect.Descriptor instead. -func (*ShipOrderRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{15} -} - -func (x *ShipOrderRequest) GetAddress() *Address { - if x != nil { - return x.Address - } - return nil -} - -func (x *ShipOrderRequest) GetItems() []*CartItem { - if x != nil { - return x.Items - } - return nil -} - -type ShipOrderResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - TrackingId string `protobuf:"bytes,1,opt,name=tracking_id,json=trackingId,proto3" json:"tracking_id,omitempty"` -} - -func (x *ShipOrderResponse) Reset() { - *x = ShipOrderResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ShipOrderResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ShipOrderResponse) ProtoMessage() {} - -func (x *ShipOrderResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[16] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ShipOrderResponse.ProtoReflect.Descriptor instead. -func (*ShipOrderResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{16} -} - -func (x *ShipOrderResponse) GetTrackingId() string { - if x != nil { - return x.TrackingId - } - return "" -} - -type Address struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *Address) Reset() { - *x = Address{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Address) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Address) ProtoMessage() {} - -func (x *Address) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[17] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Address.ProtoReflect.Descriptor instead. -func (*Address) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{17} -} - -func (x *Address) GetStreetAddress() string { - if x != nil { - return x.StreetAddress - } - return "" -} - -func (x *Address) GetCity() string { - if x != nil { - return x.City - } - return "" -} - -func (x *Address) GetState() string { - if x != nil { - return x.State - } - return "" -} - -func (x *Address) GetCountry() string { - if x != nil { - return x.Country - } - return "" -} - -func (x *Address) GetZipCode() int32 { - if x != nil { - return x.ZipCode - } - return 0 -} - -// Represents an amount of money with its currency type. -type Money struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // 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"` -} - -func (x *Money) Reset() { - *x = Money{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Money) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Money) ProtoMessage() {} - -func (x *Money) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[18] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Money.ProtoReflect.Descriptor instead. -func (*Money) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{18} -} - -func (x *Money) GetCurrencyCode() string { - if x != nil { - return x.CurrencyCode - } - return "" -} - -func (x *Money) GetUnits() int64 { - if x != nil { - return x.Units - } - return 0 -} - -func (x *Money) GetNanos() int32 { - if x != nil { - return x.Nanos - } - return 0 -} - -type GetSupportedCurrenciesResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // 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"` -} - -func (x *GetSupportedCurrenciesResponse) Reset() { - *x = GetSupportedCurrenciesResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetSupportedCurrenciesResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetSupportedCurrenciesResponse) ProtoMessage() {} - -func (x *GetSupportedCurrenciesResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[19] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetSupportedCurrenciesResponse.ProtoReflect.Descriptor instead. -func (*GetSupportedCurrenciesResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{19} -} - -func (x *GetSupportedCurrenciesResponse) GetCurrencyCodes() []string { - if x != nil { - return x.CurrencyCodes - } - return nil -} - -type CurrencyConversionRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *CurrencyConversionRequest) Reset() { - *x = CurrencyConversionRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CurrencyConversionRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CurrencyConversionRequest) ProtoMessage() {} - -func (x *CurrencyConversionRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[20] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CurrencyConversionRequest.ProtoReflect.Descriptor instead. -func (*CurrencyConversionRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{20} -} - -func (x *CurrencyConversionRequest) GetFrom() *Money { - if x != nil { - return x.From - } - return nil -} - -func (x *CurrencyConversionRequest) GetToCode() string { - if x != nil { - return x.ToCode - } - return "" -} - -type CreditCardInfo struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *CreditCardInfo) Reset() { - *x = CreditCardInfo{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreditCardInfo) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreditCardInfo) ProtoMessage() {} - -func (x *CreditCardInfo) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[21] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreditCardInfo.ProtoReflect.Descriptor instead. -func (*CreditCardInfo) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{21} -} - -func (x *CreditCardInfo) GetCreditCardNumber() string { - if x != nil { - return x.CreditCardNumber - } - return "" -} - -func (x *CreditCardInfo) GetCreditCardCvv() int32 { - if x != nil { - return x.CreditCardCvv - } - return 0 -} - -func (x *CreditCardInfo) GetCreditCardExpirationYear() int32 { - if x != nil { - return x.CreditCardExpirationYear - } - return 0 -} - -func (x *CreditCardInfo) GetCreditCardExpirationMonth() int32 { - if x != nil { - return x.CreditCardExpirationMonth - } - return 0 -} - -type ChargeRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *ChargeRequest) Reset() { - *x = ChargeRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ChargeRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ChargeRequest) ProtoMessage() {} - -func (x *ChargeRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[22] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ChargeRequest.ProtoReflect.Descriptor instead. -func (*ChargeRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{22} -} - -func (x *ChargeRequest) GetAmount() *Money { - if x != nil { - return x.Amount - } - return nil -} - -func (x *ChargeRequest) GetCreditCard() *CreditCardInfo { - if x != nil { - return x.CreditCard - } - return nil -} - -type ChargeResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - TransactionId string `protobuf:"bytes,1,opt,name=transaction_id,json=transactionId,proto3" json:"transaction_id,omitempty"` -} - -func (x *ChargeResponse) Reset() { - *x = ChargeResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[23] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ChargeResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ChargeResponse) ProtoMessage() {} - -func (x *ChargeResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[23] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ChargeResponse.ProtoReflect.Descriptor instead. -func (*ChargeResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{23} -} - -func (x *ChargeResponse) GetTransactionId() string { - if x != nil { - return x.TransactionId - } - return "" -} - -type OrderItem struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Item *CartItem `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` - Cost *Money `protobuf:"bytes,2,opt,name=cost,proto3" json:"cost,omitempty"` -} - -func (x *OrderItem) Reset() { - *x = OrderItem{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[24] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *OrderItem) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*OrderItem) ProtoMessage() {} - -func (x *OrderItem) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[24] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use OrderItem.ProtoReflect.Descriptor instead. -func (*OrderItem) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{24} -} - -func (x *OrderItem) GetItem() *CartItem { - if x != nil { - return x.Item - } - return nil -} - -func (x *OrderItem) GetCost() *Money { - if x != nil { - return x.Cost - } - return nil -} - -type OrderResult struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *OrderResult) Reset() { - *x = OrderResult{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[25] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *OrderResult) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*OrderResult) ProtoMessage() {} - -func (x *OrderResult) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[25] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use OrderResult.ProtoReflect.Descriptor instead. -func (*OrderResult) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{25} -} - -func (x *OrderResult) GetOrderId() string { - if x != nil { - return x.OrderId - } - return "" -} - -func (x *OrderResult) GetShippingTrackingId() string { - if x != nil { - return x.ShippingTrackingId - } - return "" -} - -func (x *OrderResult) GetShippingCost() *Money { - if x != nil { - return x.ShippingCost - } - return nil -} - -func (x *OrderResult) GetShippingAddress() *Address { - if x != nil { - return x.ShippingAddress - } - return nil -} - -func (x *OrderResult) GetItems() []*OrderItem { - if x != nil { - return x.Items - } - return nil -} - -type SendOrderConfirmationRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` - Order *OrderResult `protobuf:"bytes,2,opt,name=order,proto3" json:"order,omitempty"` -} - -func (x *SendOrderConfirmationRequest) Reset() { - *x = SendOrderConfirmationRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[26] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SendOrderConfirmationRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SendOrderConfirmationRequest) ProtoMessage() {} - -func (x *SendOrderConfirmationRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[26] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SendOrderConfirmationRequest.ProtoReflect.Descriptor instead. -func (*SendOrderConfirmationRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{26} -} - -func (x *SendOrderConfirmationRequest) GetEmail() string { - if x != nil { - return x.Email - } - return "" -} - -func (x *SendOrderConfirmationRequest) GetOrder() *OrderResult { - if x != nil { - return x.Order - } - return nil -} - -type PlaceOrderRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - 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"` -} - -func (x *PlaceOrderRequest) Reset() { - *x = PlaceOrderRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[27] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PlaceOrderRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PlaceOrderRequest) ProtoMessage() {} - -func (x *PlaceOrderRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[27] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PlaceOrderRequest.ProtoReflect.Descriptor instead. -func (*PlaceOrderRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{27} -} - -func (x *PlaceOrderRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -func (x *PlaceOrderRequest) GetUserCurrency() string { - if x != nil { - return x.UserCurrency - } - return "" -} - -func (x *PlaceOrderRequest) GetAddress() *Address { - if x != nil { - return x.Address - } - return nil -} - -func (x *PlaceOrderRequest) GetEmail() string { - if x != nil { - return x.Email - } - return "" -} - -func (x *PlaceOrderRequest) GetCreditCard() *CreditCardInfo { - if x != nil { - return x.CreditCard - } - return nil -} - -type PlaceOrderResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Order *OrderResult `protobuf:"bytes,1,opt,name=order,proto3" json:"order,omitempty"` -} - -func (x *PlaceOrderResponse) Reset() { - *x = PlaceOrderResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[28] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PlaceOrderResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PlaceOrderResponse) ProtoMessage() {} - -func (x *PlaceOrderResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[28] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PlaceOrderResponse.ProtoReflect.Descriptor instead. -func (*PlaceOrderResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{28} -} - -func (x *PlaceOrderResponse) GetOrder() *OrderResult { - if x != nil { - return x.Order - } - return nil -} - -type AdRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // 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"` -} - -func (x *AdRequest) Reset() { - *x = AdRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[29] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AdRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AdRequest) ProtoMessage() {} - -func (x *AdRequest) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[29] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AdRequest.ProtoReflect.Descriptor instead. -func (*AdRequest) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{29} -} - -func (x *AdRequest) GetContextKeys() []string { - if x != nil { - return x.ContextKeys - } - return nil -} - -type AdResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Ads []*Ad `protobuf:"bytes,1,rep,name=ads,proto3" json:"ads,omitempty"` -} - -func (x *AdResponse) Reset() { - *x = AdResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[30] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AdResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AdResponse) ProtoMessage() {} - -func (x *AdResponse) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[30] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AdResponse.ProtoReflect.Descriptor instead. -func (*AdResponse) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{30} -} - -func (x *AdResponse) GetAds() []*Ad { - if x != nil { - return x.Ads - } - return nil -} - -type Ad struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // 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"` -} - -func (x *Ad) Reset() { - *x = Ad{} - if protoimpl.UnsafeEnabled { - mi := &file_demo_proto_msgTypes[31] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Ad) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Ad) ProtoMessage() {} - -func (x *Ad) ProtoReflect() protoreflect.Message { - mi := &file_demo_proto_msgTypes[31] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Ad.ProtoReflect.Descriptor instead. -func (*Ad) Descriptor() ([]byte, []int) { - return file_demo_proto_rawDescGZIP(), []int{31} -} - -func (x *Ad) GetRedirectUrl() string { - if x != nil { - return x.RedirectUrl - } - return "" -} - -func (x *Ad) GetText() string { - if x != nil { - return x.Text - } - return "" -} - -var File_demo_proto protoreflect.FileDescriptor - -var file_demo_proto_rawDesc = []byte{ - 0x0a, 0x0a, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x68, 0x69, - 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x22, 0x45, 0x0a, 0x08, 0x43, 0x61, 0x72, - 0x74, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, - 0x63, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x22, 0x54, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x04, 0x69, - 0x74, 0x65, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x69, 0x70, 0x73, - 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x61, 0x72, 0x74, 0x49, 0x74, 0x65, 0x6d, - 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x2b, 0x0a, 0x10, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x43, - 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, - 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, - 0x72, 0x49, 0x64, 0x22, 0x29, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x43, 0x61, 0x72, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x4c, - 0x0a, 0x04, 0x43, 0x61, 0x72, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, - 0x2b, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, - 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x61, 0x72, - 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x07, 0x0a, 0x05, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x56, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, - 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, - 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x73, 0x22, 0x3e, 0x0a, - 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, - 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x73, 0x22, 0xba, 0x01, - 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, - 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x18, 0x0a, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x70, 0x72, 0x69, - 0x63, 0x65, 0x5f, 0x75, 0x73, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x68, - 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, - 0x52, 0x08, 0x70, 0x72, 0x69, 0x63, 0x65, 0x55, 0x73, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x61, - 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, - 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x22, 0x48, 0x0a, 0x14, 0x4c, 0x69, - 0x73, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x30, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, - 0x6f, 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x64, - 0x75, 0x63, 0x74, 0x73, 0x22, 0x23, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, - 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x2d, 0x0a, 0x15, 0x53, 0x65, 0x61, - 0x72, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x48, 0x0a, 0x16, 0x53, 0x65, 0x61, 0x72, - 0x63, 0x68, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, - 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x73, 0x22, 0x6e, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, - 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x07, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2b, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, - 0x6f, 0x70, 0x2e, 0x43, 0x61, 0x72, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, - 0x6d, 0x73, 0x22, 0x41, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x08, 0x63, 0x6f, 0x73, 0x74, 0x5f, 0x75, - 0x73, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, - 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x07, 0x63, 0x6f, - 0x73, 0x74, 0x55, 0x73, 0x64, 0x22, 0x6f, 0x0a, 0x10, 0x53, 0x68, 0x69, 0x70, 0x4f, 0x72, 0x64, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x07, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x68, 0x69, 0x70, - 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2b, 0x0a, 0x05, 0x69, 0x74, 0x65, - 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, - 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x61, 0x72, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, - 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x34, 0x0a, 0x11, 0x53, 0x68, 0x69, 0x70, 0x4f, 0x72, - 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, - 0x72, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x64, 0x22, 0x8f, 0x01, 0x0a, - 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x74, 0x72, 0x65, - 0x65, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0d, 0x73, 0x74, 0x72, 0x65, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, - 0x12, 0x0a, 0x04, 0x63, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, - 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x7a, 0x69, 0x70, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x7a, 0x69, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x58, - 0x0a, 0x05, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65, - 0x6e, 0x63, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, - 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x75, 0x6e, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x75, 0x6e, 0x69, - 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x05, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x22, 0x47, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x53, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x69, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x75, - 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x64, 0x65, - 0x73, 0x22, 0x5c, 0x0a, 0x19, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x6e, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, - 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x68, - 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, - 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x64, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x22, - 0xe6, 0x01, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x49, 0x6e, - 0x66, 0x6f, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5f, 0x63, 0x61, 0x72, - 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, - 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, - 0x12, 0x26, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x5f, - 0x63, 0x76, 0x76, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x63, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x43, 0x61, 0x72, 0x64, 0x43, 0x76, 0x76, 0x12, 0x3d, 0x0a, 0x1b, 0x63, 0x72, 0x65, 0x64, - 0x69, 0x74, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x79, 0x65, 0x61, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x18, 0x63, - 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x59, 0x65, 0x61, 0x72, 0x12, 0x3f, 0x0a, 0x1c, 0x63, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x19, 0x63, - 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x22, 0x79, 0x0a, 0x0d, 0x43, 0x68, 0x61, 0x72, - 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x06, 0x61, 0x6d, 0x6f, - 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x68, 0x69, 0x70, 0x73, - 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x06, 0x61, - 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3c, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5f, - 0x63, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x68, 0x69, 0x70, - 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, - 0x61, 0x72, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, - 0x61, 0x72, 0x64, 0x22, 0x37, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, - 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x5e, 0x0a, 0x09, - 0x4f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x29, 0x0a, 0x04, 0x69, 0x74, 0x65, - 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, - 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x61, 0x72, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, - 0x69, 0x74, 0x65, 0x6d, 0x12, 0x26, 0x0a, 0x04, 0x63, 0x6f, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, - 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x04, 0x63, 0x6f, 0x73, 0x74, 0x22, 0x82, 0x02, 0x0a, - 0x0b, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x19, 0x0a, 0x08, - 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x6f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x68, 0x69, 0x70, 0x70, - 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x68, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x54, - 0x72, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x64, 0x12, 0x37, 0x0a, 0x0d, 0x73, 0x68, 0x69, - 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x12, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4d, - 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x0c, 0x73, 0x68, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x43, 0x6f, - 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x10, 0x73, 0x68, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x68, - 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x52, 0x0f, 0x73, 0x68, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x41, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x12, 0x2c, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, - 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, - 0x73, 0x22, 0x64, 0x0a, 0x1c, 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x2e, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, - 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x22, 0xd5, 0x01, 0x0a, 0x11, 0x50, 0x6c, 0x61, 0x63, - 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, - 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, - 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x75, - 0x73, 0x65, 0x72, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x2e, 0x0a, 0x07, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x68, - 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, - 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, - 0x6c, 0x12, 0x3c, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5f, 0x63, 0x61, 0x72, 0x64, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, - 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x22, - 0x44, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x63, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, - 0x6f, 0x70, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x05, - 0x6f, 0x72, 0x64, 0x65, 0x72, 0x22, 0x2e, 0x0a, 0x09, 0x41, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x6b, 0x65, - 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, - 0x74, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x2f, 0x0a, 0x0a, 0x41, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x03, 0x61, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0f, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, - 0x64, 0x52, 0x03, 0x61, 0x64, 0x73, 0x22, 0x3b, 0x0a, 0x02, 0x41, 0x64, 0x12, 0x21, 0x0a, 0x0c, - 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x55, 0x72, 0x6c, 0x12, - 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, - 0x65, 0x78, 0x74, 0x32, 0xca, 0x01, 0x0a, 0x0b, 0x43, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x3c, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x1b, - 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, 0x64, 0x64, - 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x68, 0x69, - 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, - 0x00, 0x12, 0x3b, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x43, 0x61, 0x72, 0x74, 0x12, 0x1b, 0x2e, 0x68, - 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x61, - 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x68, 0x69, 0x70, 0x73, - 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x61, 0x72, 0x74, 0x22, 0x00, 0x12, 0x40, - 0x0a, 0x09, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x43, 0x61, 0x72, 0x74, 0x12, 0x1d, 0x2e, 0x68, 0x69, - 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x43, - 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x68, 0x69, 0x70, - 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, - 0x32, 0x83, 0x01, 0x0a, 0x15, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6a, 0x0a, 0x13, 0x4c, 0x69, - 0x73, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x27, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x69, 0x70, - 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, - 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0x83, 0x02, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x64, 0x75, - 0x63, 0x74, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x47, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, - 0x12, 0x12, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x21, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, - 0x6f, 0x70, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x0a, 0x47, 0x65, 0x74, - 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x1e, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, - 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, - 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x22, 0x00, 0x12, - 0x5b, 0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, - 0x73, 0x12, 0x22, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, - 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, - 0x68, 0x6f, 0x70, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, - 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0xaa, 0x01, 0x0a, - 0x0f, 0x53, 0x68, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x49, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x1c, 0x2e, 0x68, - 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x51, 0x75, - 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x68, 0x69, 0x70, - 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x09, 0x53, - 0x68, 0x69, 0x70, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x1d, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, - 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x53, 0x68, 0x69, 0x70, 0x4f, 0x72, 0x64, 0x65, 0x72, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, - 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x53, 0x68, 0x69, 0x70, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0xb7, 0x01, 0x0a, 0x0f, 0x43, 0x75, - 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5b, 0x0a, - 0x16, 0x47, 0x65, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x43, 0x75, 0x72, - 0x72, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x12, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, - 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x2b, 0x2e, 0x68, 0x69, - 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x07, 0x43, 0x6f, - 0x6e, 0x76, 0x65, 0x72, 0x74, 0x12, 0x26, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, - 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x6e, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, - 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x4d, 0x6f, 0x6e, 0x65, - 0x79, 0x22, 0x00, 0x32, 0x55, 0x0a, 0x0e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x12, - 0x1a, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x68, - 0x61, 0x72, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x68, 0x69, - 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0x68, 0x0a, 0x0c, 0x45, 0x6d, - 0x61, 0x69, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x58, 0x0a, 0x15, 0x53, 0x65, - 0x6e, 0x64, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, - 0x70, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, - 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x22, 0x00, 0x32, 0x62, 0x0a, 0x0f, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4f, 0x0a, 0x0a, 0x50, 0x6c, 0x61, 0x63, 0x65, - 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x1e, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, - 0x68, 0x6f, 0x70, 0x2e, 0x50, 0x6c, 0x61, 0x63, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, - 0x68, 0x6f, 0x70, 0x2e, 0x50, 0x6c, 0x61, 0x63, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0x48, 0x0a, 0x09, 0x41, 0x64, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x41, 0x64, 0x73, 0x12, - 0x16, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, 0x64, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, - 0x72, 0x73, 0x68, 0x6f, 0x70, 0x2e, 0x41, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x42, 0x10, 0x5a, 0x0e, 0x2e, 0x2f, 0x3b, 0x68, 0x69, 0x70, 0x73, 0x74, 0x65, 0x72, - 0x73, 0x68, 0x6f, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_demo_proto_rawDescOnce sync.Once - file_demo_proto_rawDescData = file_demo_proto_rawDesc -) - -func file_demo_proto_rawDescGZIP() []byte { - file_demo_proto_rawDescOnce.Do(func() { - file_demo_proto_rawDescData = protoimpl.X.CompressGZIP(file_demo_proto_rawDescData) - }) - return file_demo_proto_rawDescData -} - -var file_demo_proto_msgTypes = make([]protoimpl.MessageInfo, 32) -var file_demo_proto_goTypes = []interface{}{ - (*CartItem)(nil), // 0: hipstershop.CartItem - (*AddItemRequest)(nil), // 1: hipstershop.AddItemRequest - (*EmptyCartRequest)(nil), // 2: hipstershop.EmptyCartRequest - (*GetCartRequest)(nil), // 3: hipstershop.GetCartRequest - (*Cart)(nil), // 4: hipstershop.Cart - (*Empty)(nil), // 5: hipstershop.Empty - (*ListRecommendationsRequest)(nil), // 6: hipstershop.ListRecommendationsRequest - (*ListRecommendationsResponse)(nil), // 7: hipstershop.ListRecommendationsResponse - (*Product)(nil), // 8: hipstershop.Product - (*ListProductsResponse)(nil), // 9: hipstershop.ListProductsResponse - (*GetProductRequest)(nil), // 10: hipstershop.GetProductRequest - (*SearchProductsRequest)(nil), // 11: hipstershop.SearchProductsRequest - (*SearchProductsResponse)(nil), // 12: hipstershop.SearchProductsResponse - (*GetQuoteRequest)(nil), // 13: hipstershop.GetQuoteRequest - (*GetQuoteResponse)(nil), // 14: hipstershop.GetQuoteResponse - (*ShipOrderRequest)(nil), // 15: hipstershop.ShipOrderRequest - (*ShipOrderResponse)(nil), // 16: hipstershop.ShipOrderResponse - (*Address)(nil), // 17: hipstershop.Address - (*Money)(nil), // 18: hipstershop.Money - (*GetSupportedCurrenciesResponse)(nil), // 19: hipstershop.GetSupportedCurrenciesResponse - (*CurrencyConversionRequest)(nil), // 20: hipstershop.CurrencyConversionRequest - (*CreditCardInfo)(nil), // 21: hipstershop.CreditCardInfo - (*ChargeRequest)(nil), // 22: hipstershop.ChargeRequest - (*ChargeResponse)(nil), // 23: hipstershop.ChargeResponse - (*OrderItem)(nil), // 24: hipstershop.OrderItem - (*OrderResult)(nil), // 25: hipstershop.OrderResult - (*SendOrderConfirmationRequest)(nil), // 26: hipstershop.SendOrderConfirmationRequest - (*PlaceOrderRequest)(nil), // 27: hipstershop.PlaceOrderRequest - (*PlaceOrderResponse)(nil), // 28: hipstershop.PlaceOrderResponse - (*AdRequest)(nil), // 29: hipstershop.AdRequest - (*AdResponse)(nil), // 30: hipstershop.AdResponse - (*Ad)(nil), // 31: hipstershop.Ad -} -var file_demo_proto_depIdxs = []int32{ - 0, // 0: hipstershop.AddItemRequest.item:type_name -> hipstershop.CartItem - 0, // 1: hipstershop.Cart.items:type_name -> hipstershop.CartItem - 18, // 2: hipstershop.Product.price_usd:type_name -> hipstershop.Money - 8, // 3: hipstershop.ListProductsResponse.products:type_name -> hipstershop.Product - 8, // 4: hipstershop.SearchProductsResponse.results:type_name -> hipstershop.Product - 17, // 5: hipstershop.GetQuoteRequest.address:type_name -> hipstershop.Address - 0, // 6: hipstershop.GetQuoteRequest.items:type_name -> hipstershop.CartItem - 18, // 7: hipstershop.GetQuoteResponse.cost_usd:type_name -> hipstershop.Money - 17, // 8: hipstershop.ShipOrderRequest.address:type_name -> hipstershop.Address - 0, // 9: hipstershop.ShipOrderRequest.items:type_name -> hipstershop.CartItem - 18, // 10: hipstershop.CurrencyConversionRequest.from:type_name -> hipstershop.Money - 18, // 11: hipstershop.ChargeRequest.amount:type_name -> hipstershop.Money - 21, // 12: hipstershop.ChargeRequest.credit_card:type_name -> hipstershop.CreditCardInfo - 0, // 13: hipstershop.OrderItem.item:type_name -> hipstershop.CartItem - 18, // 14: hipstershop.OrderItem.cost:type_name -> hipstershop.Money - 18, // 15: hipstershop.OrderResult.shipping_cost:type_name -> hipstershop.Money - 17, // 16: hipstershop.OrderResult.shipping_address:type_name -> hipstershop.Address - 24, // 17: hipstershop.OrderResult.items:type_name -> hipstershop.OrderItem - 25, // 18: hipstershop.SendOrderConfirmationRequest.order:type_name -> hipstershop.OrderResult - 17, // 19: hipstershop.PlaceOrderRequest.address:type_name -> hipstershop.Address - 21, // 20: hipstershop.PlaceOrderRequest.credit_card:type_name -> hipstershop.CreditCardInfo - 25, // 21: hipstershop.PlaceOrderResponse.order:type_name -> hipstershop.OrderResult - 31, // 22: hipstershop.AdResponse.ads:type_name -> hipstershop.Ad - 1, // 23: hipstershop.CartService.AddItem:input_type -> hipstershop.AddItemRequest - 3, // 24: hipstershop.CartService.GetCart:input_type -> hipstershop.GetCartRequest - 2, // 25: hipstershop.CartService.EmptyCart:input_type -> hipstershop.EmptyCartRequest - 6, // 26: hipstershop.RecommendationService.ListRecommendations:input_type -> hipstershop.ListRecommendationsRequest - 5, // 27: hipstershop.ProductCatalogService.ListProducts:input_type -> hipstershop.Empty - 10, // 28: hipstershop.ProductCatalogService.GetProduct:input_type -> hipstershop.GetProductRequest - 11, // 29: hipstershop.ProductCatalogService.SearchProducts:input_type -> hipstershop.SearchProductsRequest - 13, // 30: hipstershop.ShippingService.GetQuote:input_type -> hipstershop.GetQuoteRequest - 15, // 31: hipstershop.ShippingService.ShipOrder:input_type -> hipstershop.ShipOrderRequest - 5, // 32: hipstershop.CurrencyService.GetSupportedCurrencies:input_type -> hipstershop.Empty - 20, // 33: hipstershop.CurrencyService.Convert:input_type -> hipstershop.CurrencyConversionRequest - 22, // 34: hipstershop.PaymentService.Charge:input_type -> hipstershop.ChargeRequest - 26, // 35: hipstershop.EmailService.SendOrderConfirmation:input_type -> hipstershop.SendOrderConfirmationRequest - 27, // 36: hipstershop.CheckoutService.PlaceOrder:input_type -> hipstershop.PlaceOrderRequest - 29, // 37: hipstershop.AdService.GetAds:input_type -> hipstershop.AdRequest - 5, // 38: hipstershop.CartService.AddItem:output_type -> hipstershop.Empty - 4, // 39: hipstershop.CartService.GetCart:output_type -> hipstershop.Cart - 5, // 40: hipstershop.CartService.EmptyCart:output_type -> hipstershop.Empty - 7, // 41: hipstershop.RecommendationService.ListRecommendations:output_type -> hipstershop.ListRecommendationsResponse - 9, // 42: hipstershop.ProductCatalogService.ListProducts:output_type -> hipstershop.ListProductsResponse - 8, // 43: hipstershop.ProductCatalogService.GetProduct:output_type -> hipstershop.Product - 12, // 44: hipstershop.ProductCatalogService.SearchProducts:output_type -> hipstershop.SearchProductsResponse - 14, // 45: hipstershop.ShippingService.GetQuote:output_type -> hipstershop.GetQuoteResponse - 16, // 46: hipstershop.ShippingService.ShipOrder:output_type -> hipstershop.ShipOrderResponse - 19, // 47: hipstershop.CurrencyService.GetSupportedCurrencies:output_type -> hipstershop.GetSupportedCurrenciesResponse - 18, // 48: hipstershop.CurrencyService.Convert:output_type -> hipstershop.Money - 23, // 49: hipstershop.PaymentService.Charge:output_type -> hipstershop.ChargeResponse - 5, // 50: hipstershop.EmailService.SendOrderConfirmation:output_type -> hipstershop.Empty - 28, // 51: hipstershop.CheckoutService.PlaceOrder:output_type -> hipstershop.PlaceOrderResponse - 30, // 52: hipstershop.AdService.GetAds:output_type -> hipstershop.AdResponse - 38, // [38:53] is the sub-list for method output_type - 23, // [23:38] is the sub-list for method input_type - 23, // [23:23] is the sub-list for extension type_name - 23, // [23:23] is the sub-list for extension extendee - 0, // [0:23] is the sub-list for field type_name -} - -func init() { file_demo_proto_init() } -func file_demo_proto_init() { - if File_demo_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_demo_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CartItem); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddItemRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EmptyCartRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetCartRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Cart); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Empty); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListRecommendationsRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListRecommendationsResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Product); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListProductsResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetProductRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SearchProductsRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SearchProductsResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetQuoteRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetQuoteResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ShipOrderRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ShipOrderResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Address); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Money); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSupportedCurrenciesResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CurrencyConversionRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreditCardInfo); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ChargeRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ChargeResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OrderItem); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OrderResult); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SendOrderConfirmationRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PlaceOrderRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PlaceOrderResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AdRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AdResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_demo_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Ad); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_demo_proto_rawDesc, - NumEnums: 0, - NumMessages: 32, - NumExtensions: 0, - NumServices: 9, - }, - GoTypes: file_demo_proto_goTypes, - DependencyIndexes: file_demo_proto_depIdxs, - MessageInfos: file_demo_proto_msgTypes, - }.Build() - File_demo_proto = out.File - file_demo_proto_rawDesc = nil - file_demo_proto_goTypes = nil - file_demo_proto_depIdxs = nil -} diff --git a/src/shippingservice/genproto/demo_grpc.pb.go b/src/shippingservice/genproto/demo_grpc.pb.go deleted file mode 100644 index f4c37599a..000000000 --- a/src/shippingservice/genproto/demo_grpc.pb.go +++ /dev/null @@ -1,1019 +0,0 @@ -// 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. - -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. - -package hipstershop - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 - -// CartServiceClient is the client API for CartService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type 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.ClientConnInterface -} - -func NewCartServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedCartServiceServer -// for forward compatibility -type CartServiceServer interface { - AddItem(context.Context, *AddItemRequest) (*Empty, error) - GetCart(context.Context, *GetCartRequest) (*Cart, error) - EmptyCart(context.Context, *EmptyCartRequest) (*Empty, error) - mustEmbedUnimplementedCartServiceServer() -} - -// UnimplementedCartServiceServer must be embedded to have forward compatible implementations. -type UnimplementedCartServiceServer struct { -} - -func (UnimplementedCartServiceServer) AddItem(context.Context, *AddItemRequest) (*Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method AddItem not implemented") -} -func (UnimplementedCartServiceServer) GetCart(context.Context, *GetCartRequest) (*Cart, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetCart not implemented") -} -func (UnimplementedCartServiceServer) EmptyCart(context.Context, *EmptyCartRequest) (*Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method EmptyCart not implemented") -} -func (UnimplementedCartServiceServer) mustEmbedUnimplementedCartServiceServer() {} - -// UnsafeCartServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to CartServiceServer will -// result in compilation errors. -type UnsafeCartServiceServer interface { - mustEmbedUnimplementedCartServiceServer() -} - -func RegisterCartServiceServer(s grpc.ServiceRegistrar, 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) -} - -// CartService_ServiceDesc is the grpc.ServiceDesc for CartService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type RecommendationServiceClient interface { - ListRecommendations(ctx context.Context, in *ListRecommendationsRequest, opts ...grpc.CallOption) (*ListRecommendationsResponse, error) -} - -type recommendationServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewRecommendationServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedRecommendationServiceServer -// for forward compatibility -type RecommendationServiceServer interface { - ListRecommendations(context.Context, *ListRecommendationsRequest) (*ListRecommendationsResponse, error) - mustEmbedUnimplementedRecommendationServiceServer() -} - -// UnimplementedRecommendationServiceServer must be embedded to have forward compatible implementations. -type UnimplementedRecommendationServiceServer struct { -} - -func (UnimplementedRecommendationServiceServer) ListRecommendations(context.Context, *ListRecommendationsRequest) (*ListRecommendationsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListRecommendations not implemented") -} -func (UnimplementedRecommendationServiceServer) mustEmbedUnimplementedRecommendationServiceServer() {} - -// UnsafeRecommendationServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to RecommendationServiceServer will -// result in compilation errors. -type UnsafeRecommendationServiceServer interface { - mustEmbedUnimplementedRecommendationServiceServer() -} - -func RegisterRecommendationServiceServer(s grpc.ServiceRegistrar, 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) -} - -// RecommendationService_ServiceDesc is the grpc.ServiceDesc for RecommendationService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#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.ClientConnInterface -} - -func NewProductCatalogServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedProductCatalogServiceServer -// for forward compatibility -type ProductCatalogServiceServer interface { - ListProducts(context.Context, *Empty) (*ListProductsResponse, error) - GetProduct(context.Context, *GetProductRequest) (*Product, error) - SearchProducts(context.Context, *SearchProductsRequest) (*SearchProductsResponse, error) - mustEmbedUnimplementedProductCatalogServiceServer() -} - -// UnimplementedProductCatalogServiceServer must be embedded to have forward compatible implementations. -type UnimplementedProductCatalogServiceServer struct { -} - -func (UnimplementedProductCatalogServiceServer) ListProducts(context.Context, *Empty) (*ListProductsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListProducts not implemented") -} -func (UnimplementedProductCatalogServiceServer) GetProduct(context.Context, *GetProductRequest) (*Product, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetProduct not implemented") -} -func (UnimplementedProductCatalogServiceServer) SearchProducts(context.Context, *SearchProductsRequest) (*SearchProductsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method SearchProducts not implemented") -} -func (UnimplementedProductCatalogServiceServer) mustEmbedUnimplementedProductCatalogServiceServer() {} - -// UnsafeProductCatalogServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to ProductCatalogServiceServer will -// result in compilation errors. -type UnsafeProductCatalogServiceServer interface { - mustEmbedUnimplementedProductCatalogServiceServer() -} - -func RegisterProductCatalogServiceServer(s grpc.ServiceRegistrar, 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) -} - -// ProductCatalogService_ServiceDesc is the grpc.ServiceDesc for ProductCatalogService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#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.ClientConnInterface -} - -func NewShippingServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedShippingServiceServer -// for forward compatibility -type ShippingServiceServer interface { - GetQuote(context.Context, *GetQuoteRequest) (*GetQuoteResponse, error) - ShipOrder(context.Context, *ShipOrderRequest) (*ShipOrderResponse, error) - mustEmbedUnimplementedShippingServiceServer() -} - -// UnimplementedShippingServiceServer must be embedded to have forward compatible implementations. -type UnimplementedShippingServiceServer struct { -} - -func (UnimplementedShippingServiceServer) GetQuote(context.Context, *GetQuoteRequest) (*GetQuoteResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetQuote not implemented") -} -func (UnimplementedShippingServiceServer) ShipOrder(context.Context, *ShipOrderRequest) (*ShipOrderResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ShipOrder not implemented") -} -func (UnimplementedShippingServiceServer) mustEmbedUnimplementedShippingServiceServer() {} - -// UnsafeShippingServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to ShippingServiceServer will -// result in compilation errors. -type UnsafeShippingServiceServer interface { - mustEmbedUnimplementedShippingServiceServer() -} - -func RegisterShippingServiceServer(s grpc.ServiceRegistrar, 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) -} - -// ShippingService_ServiceDesc is the grpc.ServiceDesc for ShippingService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#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.ClientConnInterface -} - -func NewCurrencyServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedCurrencyServiceServer -// for forward compatibility -type CurrencyServiceServer interface { - GetSupportedCurrencies(context.Context, *Empty) (*GetSupportedCurrenciesResponse, error) - Convert(context.Context, *CurrencyConversionRequest) (*Money, error) - mustEmbedUnimplementedCurrencyServiceServer() -} - -// UnimplementedCurrencyServiceServer must be embedded to have forward compatible implementations. -type UnimplementedCurrencyServiceServer struct { -} - -func (UnimplementedCurrencyServiceServer) GetSupportedCurrencies(context.Context, *Empty) (*GetSupportedCurrenciesResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetSupportedCurrencies not implemented") -} -func (UnimplementedCurrencyServiceServer) Convert(context.Context, *CurrencyConversionRequest) (*Money, error) { - return nil, status.Errorf(codes.Unimplemented, "method Convert not implemented") -} -func (UnimplementedCurrencyServiceServer) mustEmbedUnimplementedCurrencyServiceServer() {} - -// UnsafeCurrencyServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to CurrencyServiceServer will -// result in compilation errors. -type UnsafeCurrencyServiceServer interface { - mustEmbedUnimplementedCurrencyServiceServer() -} - -func RegisterCurrencyServiceServer(s grpc.ServiceRegistrar, 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) -} - -// CurrencyService_ServiceDesc is the grpc.ServiceDesc for CurrencyService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type PaymentServiceClient interface { - Charge(ctx context.Context, in *ChargeRequest, opts ...grpc.CallOption) (*ChargeResponse, error) -} - -type paymentServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewPaymentServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedPaymentServiceServer -// for forward compatibility -type PaymentServiceServer interface { - Charge(context.Context, *ChargeRequest) (*ChargeResponse, error) - mustEmbedUnimplementedPaymentServiceServer() -} - -// UnimplementedPaymentServiceServer must be embedded to have forward compatible implementations. -type UnimplementedPaymentServiceServer struct { -} - -func (UnimplementedPaymentServiceServer) Charge(context.Context, *ChargeRequest) (*ChargeResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Charge not implemented") -} -func (UnimplementedPaymentServiceServer) mustEmbedUnimplementedPaymentServiceServer() {} - -// UnsafePaymentServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to PaymentServiceServer will -// result in compilation errors. -type UnsafePaymentServiceServer interface { - mustEmbedUnimplementedPaymentServiceServer() -} - -func RegisterPaymentServiceServer(s grpc.ServiceRegistrar, 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) -} - -// PaymentService_ServiceDesc is the grpc.ServiceDesc for PaymentService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type EmailServiceClient interface { - SendOrderConfirmation(ctx context.Context, in *SendOrderConfirmationRequest, opts ...grpc.CallOption) (*Empty, error) -} - -type emailServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewEmailServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedEmailServiceServer -// for forward compatibility -type EmailServiceServer interface { - SendOrderConfirmation(context.Context, *SendOrderConfirmationRequest) (*Empty, error) - mustEmbedUnimplementedEmailServiceServer() -} - -// UnimplementedEmailServiceServer must be embedded to have forward compatible implementations. -type UnimplementedEmailServiceServer struct { -} - -func (UnimplementedEmailServiceServer) SendOrderConfirmation(context.Context, *SendOrderConfirmationRequest) (*Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method SendOrderConfirmation not implemented") -} -func (UnimplementedEmailServiceServer) mustEmbedUnimplementedEmailServiceServer() {} - -// UnsafeEmailServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to EmailServiceServer will -// result in compilation errors. -type UnsafeEmailServiceServer interface { - mustEmbedUnimplementedEmailServiceServer() -} - -func RegisterEmailServiceServer(s grpc.ServiceRegistrar, 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) -} - -// EmailService_ServiceDesc is the grpc.ServiceDesc for EmailService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type CheckoutServiceClient interface { - PlaceOrder(ctx context.Context, in *PlaceOrderRequest, opts ...grpc.CallOption) (*PlaceOrderResponse, error) -} - -type checkoutServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewCheckoutServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedCheckoutServiceServer -// for forward compatibility -type CheckoutServiceServer interface { - PlaceOrder(context.Context, *PlaceOrderRequest) (*PlaceOrderResponse, error) - mustEmbedUnimplementedCheckoutServiceServer() -} - -// UnimplementedCheckoutServiceServer must be embedded to have forward compatible implementations. -type UnimplementedCheckoutServiceServer struct { -} - -func (UnimplementedCheckoutServiceServer) PlaceOrder(context.Context, *PlaceOrderRequest) (*PlaceOrderResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method PlaceOrder not implemented") -} -func (UnimplementedCheckoutServiceServer) mustEmbedUnimplementedCheckoutServiceServer() {} - -// UnsafeCheckoutServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to CheckoutServiceServer will -// result in compilation errors. -type UnsafeCheckoutServiceServer interface { - mustEmbedUnimplementedCheckoutServiceServer() -} - -func RegisterCheckoutServiceServer(s grpc.ServiceRegistrar, 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) -} - -// CheckoutService_ServiceDesc is the grpc.ServiceDesc for CheckoutService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type AdServiceClient interface { - GetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error) -} - -type adServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewAdServiceClient(cc grpc.ClientConnInterface) 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. -// All implementations must embed UnimplementedAdServiceServer -// for forward compatibility -type AdServiceServer interface { - GetAds(context.Context, *AdRequest) (*AdResponse, error) - mustEmbedUnimplementedAdServiceServer() -} - -// UnimplementedAdServiceServer must be embedded to have forward compatible implementations. -type UnimplementedAdServiceServer struct { -} - -func (UnimplementedAdServiceServer) GetAds(context.Context, *AdRequest) (*AdResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetAds not implemented") -} -func (UnimplementedAdServiceServer) mustEmbedUnimplementedAdServiceServer() {} - -// UnsafeAdServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to AdServiceServer will -// result in compilation errors. -type UnsafeAdServiceServer interface { - mustEmbedUnimplementedAdServiceServer() -} - -func RegisterAdServiceServer(s grpc.ServiceRegistrar, 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) -} - -// AdService_ServiceDesc is the grpc.ServiceDesc for AdService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -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", -} diff --git a/src/shippingservice/go.mod b/src/shippingservice/go.mod deleted file mode 100644 index 868a7b173..000000000 --- a/src/shippingservice/go.mod +++ /dev/null @@ -1,21 +0,0 @@ -module github.com/GoogleCloudPlatform/cloud-ops-sandbox/src/shipping - -go 1.16 - -require ( - cloud.google.com/go v0.61.0 - contrib.go.opencensus.io/exporter/stackdriver v0.13.5 - github.com/GoogleCloudPlatform/cloud-ops-sandbox v0.6.0 - github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v0.20.0 - github.com/aws/aws-sdk-go v1.30.15 // indirect - github.com/sirupsen/logrus v1.6.0 - go.opencensus.io v0.23.0 - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0 - go.opentelemetry.io/otel v0.20.0 - go.opentelemetry.io/otel/sdk v0.20.0 - go.opentelemetry.io/otel/trace v0.20.0 - golang.org/x/net v0.0.0-20210614182718-04defd469f4e - google.golang.org/grpc v1.38.0 - google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 - google.golang.org/protobuf v1.26.0 -) diff --git a/src/shippingservice/go.sum b/src/shippingservice/go.sum deleted file mode 100644 index e6d36583b..000000000 --- a/src/shippingservice/go.sum +++ /dev/null @@ -1,460 +0,0 @@ -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.61.0 h1:NLQf5e1OMspfNT1RAHOB3ublr1TW3YTXO8OiWwVjK2U= -cloud.google.com/go v0.61.0/go.mod h1:XukKJg4Y7QsUu0Hxg3qQKUWR4VuWivmyMK2+rUyxAqw= -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/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/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= -contrib.go.opencensus.io/exporter/stackdriver v0.13.5 h1:TNaexHK16gPUoc7uzELKOU7JULqccn1NDuqUxmxSqfo= -contrib.go.opencensus.io/exporter/stackdriver v0.13.5/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= -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/GoogleCloudPlatform/cloud-ops-sandbox v0.6.0 h1:akI9dCBVHs+ituWhnjsKV9/91TtWjGL8BdfqK46Dk9g= -github.com/GoogleCloudPlatform/cloud-ops-sandbox v0.6.0/go.mod h1:7DMkdTXPCz2RuP31ThsFImF5OMcTdScg8yBkIKCmS9M= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v0.20.0 h1:ExGRyJwOUijAPv/RzCJ3p1CNUxBQGzVO238m1lFjLS4= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v0.20.0/go.mod h1:f4BFp2+kV6s/OKj3IP/34keB/OE7tTTaZZQyX/mQ7Ng= -github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.30.15 h1:Sd8QDVzzE8Sl+xNccmdj0HwMrFowv6uVUx9tGsCE1ZE= -github.com/aws/aws-sdk-go v1.30.15/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= -github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -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-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -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.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -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/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -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/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 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -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.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -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.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/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/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 h1:Ak8CrdlwwXwAZxzS66vgPt4U8yUZX7JwLvVR58FN5jM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -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/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleinterns/cloud-operations-api-mock v0.0.0-20200709193332-a1e58c29bdd3 h1:eHv/jVY/JNop1xg2J9cBb4EzyMpWZoNCP1BslSAIkOI= -github.com/googleinterns/cloud-operations-api-mock v0.0.0-20200709193332-a1e58c29bdd3/go.mod h1:h/KNeRx7oYU4SpA4SoY7W2/NxDKEEVuwA6j9A27L4OI= -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/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc= -github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= -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 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= -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/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -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/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -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/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= -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.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opentelemetry.io/contrib v0.20.0 h1:ubFQUn0VCZ0gPwIoJfBJVpeBlyRMxu8Mm/huKWYd9p0= -go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0 h1:sO4WKdPAudZGKPcpZT4MJn6JaDmpyLrMPDGGyA1SttE= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0 h1:Q3C9yzW6I9jqEc8sawxzxZmY48fs9u220KXq6d5s3XU= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= -go.opentelemetry.io/otel v0.20.0 h1:eaP0Fqu7SXHwvjiqDq83zImeehOHX8doTvU9AwXON8g= -go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= -go.opentelemetry.io/otel/metric v0.20.0 h1:4kzhXFP+btKm4jwxpjIqjs41A7MakRFUS86bqLHTIw8= -go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= -go.opentelemetry.io/otel/oteltest v0.20.0 h1:HiITxCawalo5vQzdHfKeZurV8x7ljcqAgiWzF6Vaeaw= -go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= -go.opentelemetry.io/otel/sdk v0.20.0 h1:JsxtGXd06J8jrnya7fdI/U/MR6yXA5DtbZy+qoHQlr8= -go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= -go.opentelemetry.io/otel/trace v0.20.0 h1:1DL6EXUdcg95gukhuRRvLDO/4X5THh/5dIV52lqtnbw= -go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= -go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -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 h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/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 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= -golang.org/x/mod v0.3.0/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-20190923162816-aa69164e4478/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-20200602114024-627f9648deb9/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-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210510120150-4163338589ed h1:p9UgmWI9wKpfYmgaV/IZKGdXc5qEK45tDwwwDyjS26I= -golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-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 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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-20190422165155-953cdadca894/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-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-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-20201214210602-f9fddec55a1e h1:AyodaIpKjppX+cBfTASF2E1US3H2JFBj920Ot3rtDjs= -golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -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 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -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-20191010075000-0337d82405ff/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-20191108193012-7d206e10da11/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-20200701151220-7cb253f4c4f8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed h1:+qzWo37K31KxduIYaBeMqJ8MUOyTayOQKpH9aDPLMSY= -golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -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 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/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.10.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 h1:BaiDisFir8O4IJxvAabCGGkQ6yCJegNQqSVoYUNAnbk= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -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.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= -google.golang.org/appengine v1.6.6/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-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-20200605102947-12044bf5ea91/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200711021454-869866162049/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200715011427-11fb19a81f2c h1:6DWnZZ6EY/59QRRQttZKiktVL23UuQYs7uy75MhhLRM= -google.golang.org/genproto v0.0.0-20200715011427-11fb19a81f2c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -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.23.1/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.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= -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 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -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.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= diff --git a/src/shippingservice/main.go b/src/shippingservice/main.go deleted file mode 100644 index 667650cdc..000000000 --- a/src/shippingservice/main.go +++ /dev/null @@ -1,240 +0,0 @@ -// 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/stackdriver" - "github.com/sirupsen/logrus" - "go.opencensus.io/plugin/ocgrpc" - "go.opencensus.io/stats/view" - "golang.org/x/net/context" - "google.golang.org/grpc" - "google.golang.org/grpc/reflection" - - // OpenTelemetry - // OTel traces -> GCP Trace direct exporter - texporter "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace" - "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/sdk/resource" - sdktrace "go.opentelemetry.io/otel/sdk/trace" - "go.opentelemetry.io/otel/semconv" - apitrace "go.opentelemetry.io/otel/trace" - - pb "github.com/GoogleCloudPlatform/cloud-ops-sandbox/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() { - go initOpenCensusStats() - initTraceProvider() - go initProfiling("shippingservice", "1.0.0") - - port := defaultPort - if value, ok := os.LookupEnv("APP_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) - } - // TOOD: replace ocgrpc with automatic OpenTelemetry grpc metrics collector - intercepterOpt := otelgrpc.WithTracerProvider(otel.GetTracerProvider()) - srv := grpc.NewServer(grpc.StatsHandler( - &ocgrpc.ServerHandler{}), // TODO: replace with automatic OTel grpc metrics collector when available - grpc.UnaryInterceptor(otelgrpc.UnaryServerInterceptor(intercepterOpt)), - grpc.StreamInterceptor(otelgrpc.StreamServerInterceptor(intercepterOpt)), - ) - 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 -} - -// Watch is for health checking. -func (s *server) Watch(req *healthpb.HealthCheckRequest, server healthpb.Health_WatchServer) error { - return nil -} - -// GetQuote produces a shipping quote (cost) in USD. -func (s *server) GetQuote(ctx context.Context, in *pb.GetQuoteRequest) (*pb.GetQuoteResponse, error) { - span := apitrace.SpanFromContext(ctx) - span.AddEvent("Get Shipping Quote") - log.Info("[GetQuote] received request") - defer log.Info("[GetQuote] completed request") - - // 1. Our quote system requires the total number of items to be shipped. - count := 0 - for _, item := range in.Items { - count += int(item.Quantity) - } - - // 2. Generate a quote based on the total number of items to be shipped. - quote := CreateQuoteFromCount(count) - - // 3. 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) { - span := apitrace.SpanFromContext(ctx) - span.AddEvent("Ship Order") - 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 -} - -// Initialize Stats using OpenCensus -// TODO: remove this after conversion to OpenTelemetry Metrics -func initOpenCensusStats() { - 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 { - // Register the views to collect server stats. - 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") - } - 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") -} - -// Initialize OTel trace provider that exports to Cloud Trace -func initTraceProvider() { - // When running on GCP, authentication is handled automatically - // using default credentials. This environment variable check - // is to help debug projects running locally. It's possible for this - // warning to be printed while the exporter works normally. See - // https://developers.google.com/identity/protocols/application-default-credentials - // for more details. - projectID := os.Getenv("GOOGLE_CLOUD_PROJECT") - if len(projectID) == 0 { - log.Warn("GOOGLE_CLOUD_PROJECT not set") - } - for i := 1; i <= 3; i++ { - exporter, err := texporter.NewExporter(texporter.WithProjectID(projectID)) - if err != nil { - log.Infof("failed to initialize exporter: %v", err) - } else { - // Create trace provider with the exporter. - // The AlwaysSample sampling policy is used here for demonstration - // purposes and should not be used in production environments. - tp := sdktrace.NewTracerProvider( - sdktrace.WithSampler(sdktrace.AlwaysSample()), - sdktrace.WithSyncer(exporter), - // TODO: replace with predefined constant for GKE or autodetection when available - sdktrace.WithResource(resource.NewWithAttributes(semconv.ServiceNameKey.String("GKE")))) - if err == nil { - log.Info("initialized trace provider") - otel.SetTracerProvider(tp) - return - } else { - d := time.Second * 10 * time.Duration(i) - log.Infof("sleeping %v to retry initializing trace provider", d) - time.Sleep(d) - } - } - } - log.Warn("failed to initialize trace provider") -} - -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") -} diff --git a/src/shippingservice/quote.go b/src/shippingservice/quote.go deleted file mode 100644 index 3732098dd..000000000 --- a/src/shippingservice/quote.go +++ /dev/null @@ -1,55 +0,0 @@ -// 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(quoteByCountFloat(count)) -} - -// 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)), - } -} - -// quoteByCountFloat takes a number of items and generates a price quote represented as a float. -func quoteByCountFloat(count int) float64 { - if count == 0 { - return 0 - } - count64 := float64(count) - var p = 1 + (count64 * 0.2) - return count64 + math.Pow(3, p) -} diff --git a/src/shippingservice/shippingservice_test.go b/src/shippingservice/shippingservice_test.go deleted file mode 100644 index e71968a4d..000000000 --- a/src/shippingservice/shippingservice_test.go +++ /dev/null @@ -1,90 +0,0 @@ -// 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/cloud-ops-sandbox/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() != 11 || res.CostUsd.GetNanos() != 220000000 { - 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) - } -} diff --git a/src/shippingservice/tools.go b/src/shippingservice/tools.go deleted file mode 100644 index 0600f7bb9..000000000 --- a/src/shippingservice/tools.go +++ /dev/null @@ -1,22 +0,0 @@ -// 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. - -// +build tools - -package main - -import ( - _ "google.golang.org/grpc/cmd/protoc-gen-go-grpc" - _ "google.golang.org/protobuf/cmd/protoc-gen-go" -) diff --git a/src/shippingservice/tracker.go b/src/shippingservice/tracker.go deleted file mode 100644 index 6ba3d934c..000000000 --- a/src/shippingservice/tracker.go +++ /dev/null @@ -1,56 +0,0 @@ -// 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 -} diff --git a/sre-recipes/README.md b/sre-recipes/README.md index 206b2a03f..ab9215d87 100644 --- a/sre-recipes/README.md +++ b/sre-recipes/README.md @@ -1,39 +1,6 @@ # SRE Recipes -SRE Recipes is a tool to help users familiarize themselves with finding the root cause of a breakage using monitoring. - -## Usage - -To view which active recipes exist, run the command below in this directory: - -``` -./sandboxctl sre-recipes --help -``` -To simulate a break in a specific recipe, run: -``` -./sandboxctl sre-recipes break -``` -To restore the original condition after simulating a break in a specific recipe, run: -``` -./sandboxctl sre-recipes restore -``` -To verify the root cause of the breakage in specific recipe, run: -``` -./sandboxctl sre-recipes verify -``` -To receive a hint about the root cause of the breakage, run: -``` -./sandboxctl sre-recipes hint -``` - -## Contributing - -To contribute a new recipe, you can either: - -1. Create a simple config based SRE Recipe (Recommended) - - See `recipes/configs_based/README.md` for contribution instruction and usage. - -2. Create a implementation based SRE Recipe class - - See `recipes/impl_based/README.md` for contribution instruction and usage. +> **Note** +> Cloud Ops Sandbox recipes feature is temporary unavailable. +> It will be restored in the following versions. +> You can track the work status in #1009 diff --git a/sre-recipes/__init__.py b/sre-recipes/__init__.py deleted file mode 100644 index 6913f02e3..000000000 --- a/sre-recipes/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# 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. diff --git a/sre-recipes/recipe_runner.py b/sre-recipes/recipe_runner.py deleted file mode 100644 index cee4c6f64..000000000 --- a/sre-recipes/recipe_runner.py +++ /dev/null @@ -1,267 +0,0 @@ -# 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. - -# -*- coding: utf-8 -*- - -""" -This file contains utility runtime classes implementing core SRE Recipes -features, such as breaking and restoring microservices, printing hints, and -running interactive multiple choice questions. - -Currently, it implements two SRE Recipe Runner: -- ImplBasedRecipeRunner: runs SRE Recipe implemented via python classes. -- ConfigBasedRecipeRunner: runs SRE Recipes defined as YAML configs. - -Refer to the class docstring for further explanations. -""" - -import abc -import importlib -import requests -import subprocess -import yaml - -from inspect import isclass -from os import path - -import utils -from recipes.impl_based.base import BaseRecipeImpl - - -# Default Load Generation Config -DEFAULT_LOADGEN_USER_TYPE = "BasicHomePageViewingUser" -DEFAULT_LOADGEN_USER_COUNT = 20 -DEFAULT_LOADGEN_SPAWN_RATE = 1 -DEFAULT_LOADGEN_TIMEOUT_SECONDS = 600 - - -class ImplBasedRecipeRunner: - """A SRE Recipe runner for running recipes implemented as class objects. - - Given a `recipe_name`, it tries to run `recipes/impl_based/recipe_name.py`. - - This runner will propgate all exceptions to the caller, and it is caller's - responsibility to handle any exception and to perform any error logging. - """ - - def __init__(self, recipe_name): - self.recipe = None - module = importlib.import_module(f"recipes.impl_based.{recipe_name}") - for attribute_name in dir(module): - attr = getattr(module, attribute_name) - if isclass(attr) and attr is not BaseRecipeImpl and issubclass(attr, BaseRecipeImpl): - self.recipe = attr() - break - if not self.recipe: - raise NotImplementedError( - f"No valid implementation exists for `{recipe_name}` recipe.") - - def get_name(self): - return self.recipe.get_name() - - def get_description(self): - return self.recipe.get_description() - - def run_break(self): - return self.recipe.run_break() - - def run_restore(self): - return self.recipe.run_restore() - - def run_hint(self): - return self.recipe.run_hint() - - def run_verify(self): - return self.recipe.run_verify() - - -class ConfigBasedRecipeRunner: - """A SRE Recipe runner for running recipes implemented using configs. - - Given a `recipe_name`, it tries to load `recipes/configs_based/recipe_name.yaml`. - - This runner will propagate all exceptions to the caller, and it is caller's - responsibility to handle any exception and to perform any error logging. - """ - - def __init__(self, recipe_name, skip_loadgen=False): - filepath = path.join(path.dirname( - path.abspath(__file__)), f"recipes/configs_based/{recipe_name}.yaml") - with open(filepath, "r") as file: - self.recipe = yaml.safe_load(file.read()) - if not self.recipe: - raise ValueError("Cannot parse config as YAML.") - self.action_handler = ActionHandler(skip_loadgen) - - def get_name(self): - return self.recipe.get("name", "No name found") - - def get_description(self): - return self.recipe.get("description", "No description found") - - @property - def config(self): - return self.recipe.get("config", {}) - - def run_break(self): - print('Deploying broken service...') - for action in self.config.get("break", []): - self.action_handler.handle_action(action) - print('Done. Deployed broken service') - - def run_restore(self): - print('Restoring service back to normal...') - for action in self.config.get("restore", []): - self.action_handler.handle_action(action) - print('Done. Restored broken service to working state.') - - def run_hint(self): - hint = self.config.get("hint", None) - if hint: - print(f'Here is your hint!\n\n{hint}') - else: - print("This recipe has no hints.") - - def run_verify(self): - verify_config = self.config.get("verify", []) - if not verify_config: - raise NotImplementedError("Verify is not configured") - for action in verify_config: - self.action_handler.handle_action(action) - - -class ActionHandler: - """A utility helper for executing actions supported by SRE Recipe configs. - - Implementation Guide - -------------------- - 1. Map the action name to the action handler in the `__init__` method. - 2. All action handlers should take exactly one argument, which is the full - config specified for the action itself, as it is defined in YAML. - For example: {action: "run-shell-commands", commands: ['echo Hi']} - - This runner will propgate all exceptions to the caller, and it is caller's - responsibility to handle any exception and to perform any error logging. - """ - - def __init__(self, skip_loadgen=False): - # Action types to action handlers - self.action_map = { - "run-shell-commands": self.run_shell_commands, - "multiple-choice-quiz": self.run_multiple_choice_quiz, - "loadgen-spawn": self.loadgen_spawn, - "loadgen-stop": self.loadgen_stop, - } - if skip_loadgen: - # ignore loadgen actions when requested - self.action_map["loadgen-spawn"] = lambda *args: None - self.action_map['loadgen-stop'] = lambda *args: None - # Reusable parameters shared between action handlers - self.loadgen_ip = None - - def handle_action(self, config): - if "action" not in config: - raise ValueError("Action config missing `action` type") - action_type = config["action"] - if action_type not in self.action_map: - raise NotImplementedError( - f"Action type not implemented: {action_type}") - return self.action_map[action_type](config) - - def init_loadgen_ip(self): - if not self.loadgen_ip: - self.loadgen_ip, err = utils.get_loadgen_ip() - if err: - raise RuntimeError(f"Failed to get loadgen IP: {err}") - - ############################ Action Handlers ############################### - - def run_shell_commands(self, config): - """Runs the commands one at a time in shell. - - Config Paramters - ---------------- - commands: string[] - Required. A list of shell command strings. - """ - for cmd in config["commands"]: - output, err = utils.run_shell_command(cmd) - if err and not "WARNING" in err.upper(): - raise RuntimeError( - f"Failed to run command `{cmd}`: {err}") - - def run_multiple_choice_quiz(self, config): - """Runs an interactive multiple choice quiz. - - Config Paramters - ---------------- - prompt: string - Required. The question prompt to display to the user. - choices: dict[] - option: string - Required. The answer display text to show to the user. - accept: bool - Optional. If true, the choice is considered correct. - """ - if "prompt" not in config: - raise ValueError("No prompt specified for the multiple choice.") - elif "choices" not in config: - raise ValueError( - "No answer choices available for the multiple choice.") - utils.run_interactive_multiple_choice( - config["prompt"], config["choices"]) - - def loadgen_spawn(self, config): - """ - Starts spawning a load shape at specified spawn rate until a total - user count is reached. Then, stop the load after a specified timesout. - - Config Paramters - ---------------- - user_type: string - Optional. Same as the `sre_recipe_user_identifier` for locust tasks - defined in `sre/loadgenerator/locust_tasks`. - Default: BasicHomePageViewingUser. - user_count: int - Optional. The number of total users to spawn. Default: 20. - spawn_rate: int - Optional. The number of users per second to spawn. Default: 1. - stop_after: int - Optional. The number of seconds to spawn before stopping. - Default: 600 seconds. - """ - self.init_loadgen_ip() - user_type = config.get( - "user_type", DEFAULT_LOADGEN_USER_TYPE) - resp = requests.post( - f"http://{self.loadgen_ip}:81/api/spawn/{user_type}", - { - "user_count": int(config.get("user_count", DEFAULT_LOADGEN_USER_COUNT)), - "spawn_rate": int(config.get("spawn_rate", DEFAULT_LOADGEN_SPAWN_RATE)), - "stop_after": int(config.get("stop_after", DEFAULT_LOADGEN_TIMEOUT_SECONDS)) - }) - if not resp.ok: - raise RuntimeError( - f"Failed to start load generation: {resp.status_code} {resp.reason}") - - def loadgen_stop(self, config): - """Stops any active load generation produced by SRE Recipes. - - Config Paramters is not required. - """ - self.init_loadgen_ip() - resp = requests.post(f"http://{self.loadgen_ip}:81/api/stop") - if not resp.ok: - raise RuntimeError( - f"Failed to stop existing load generation: {resp.status_code} {resp.reason}") diff --git a/sre-recipes/recipes/configs_based/README.md b/sre-recipes/recipes/configs_based/README.md deleted file mode 100644 index 62b7d37a9..000000000 --- a/sre-recipes/recipes/configs_based/README.md +++ /dev/null @@ -1,147 +0,0 @@ -# Configs-Based SRE Recipe - -This directory contains configs for supported config-based SRE Recipes. - -## Writing the Config - -Each SRE Recipe config is a YAML file with the following overall structure. - -```yaml -name: -description: -config: - # This section defines the actions to run when `sandboxctl sre-receipes break` - # is called" . In practice, this is where you try to break sandbox services. - # - # If your SRE Recipe has complex logic, prefer running a shell command to - # run a shell script instead. - # - # You can use, or contribute, more action templates by referring to the - # "Supported SRE Recipe Actions" below. - break: - # The `run-shell-commands` action template simply runs the given shell - # commands one at a time as it is. - - action: run-shell-commands - commands: - - echo 'first command' - - echo 'another command' - - # The `loadgen-spawn` action template will spawn the given load shape - # producible by `user_type` (see `sre/loadgenerator/locust_tasks`) at a - # `spawn_rate` of users per second until it reaches a total of `user_count` - # users. The users will keep generating load until at least `stop_after` - # seconds have passed. - - action: loadgen-spawn - user_type: BasicHomePageViewingUser - user_count: 20 - spawn_rate: 5 - stop_after: 600 - - # The `loadgen-stop` action template will stop any active load generation - # produced by SRE Recipes. It is ok to call this even if there is no load - # generation ongoing. - - action: loadgen-stop - # This section defines the actions to run when `sandboxctl sre-receipes restore` - # is called". In practice, this is where you try to restore sandbox services. - # - # If your SRE Recipe has complex logic, prefer running a shell command to - # run a shell script instead. - # - # You can use, or contribute, more action templates by referring to the - # "Supported SRE Recipe Actions" below. - restore: - # The same set of action templates as `break` are supported in `restore` - - action: run-shell-commands - commands: - - echo 'first command' - - echo 'another command' - - action: loadgen-stop - hint: Put the hint string for your recipe here - verify: - - action: multiple-choice-quiz - prompt: Put the question prompt here - choices: - # Put as many answers to choose from as you need - # Mark the correct option with `accept: true` - # You must at least mark one option as accepted, otherwise a runtime - # error will be thrown. You can mark multiple options as accepted. - - option: Answer 1 - accept: true - - option: Answer 2 - - option: Answer 3 -``` - -## Contributions - -If you want to add more pre-defined action templates, - -1. add your implementation to the `ActionHandlers` in `recipe_runner.py`. -2. add a short guide for how to use your new action in this README file -3. add schema validation for your new action config in `./schema` folder - -## Supported SRE Recipe Actions - -The `break` and `restore` sections support the following action templates: - -1. `run-shell-commands`: simply run the commands one at a time in shell - -Example: - -```yaml -- action: run-shell-commands - commands: - - kubectl delete pod $(kubectl get pod -l app=frontend -o jsonpath='{.items[0].metadata.name}') -``` - -2. `loadgen-stop`: stop any active load generation produced by SRE Recipes. - -It is ok to call this even if there is no load generation ongoing. - -Example: - -```yaml -- action: loadgen-stop -``` - -3. `loadgen-spawn`: start spawning the given load shape producible by - `user_type` at a `spawn_rate` of users per second until it reaches a total of `user_count` users. The users will keep generating load until at least - `stop_after` seconds have passed. - -_Optional Parameters:_ - -- `user_type`: same as the `sre_recipe_user_identifier` for locust - tasks defined in `sre/loadgenerator/locust_tasks`. You can implement new load - shapes by contributing in `sre/loadgenerator/locust_tasks`. - Default: `BasicHomePageViewingUser`. -- `user_count`: the number of total users to spawn. Default: `20`. -- `spawn_rate`: the number of users per second to spawn. Default: `1`. -- `stop_after`: the number of seconds to spawn before stopping. Default: `600`. - -Example: - -```yaml -- action: loadgen-spawn - # Defined in /src/loadgenerator/locust_tasks/sre_recipe_load_tasks.py - user_type: BasicHomePageViewingUser - user_count: 20 - spawn_rate: 5 - stop_after: 600 -``` - -4. `multiple-choice-quiz`: run an interactive multiple choice quiz. - -Example - -```yaml -- action: multiple-choice-quiz - prompt: Put the question prompt here - choices: - # Put as many answers to choose from as you need - # Mark the correct option with `accept: true` - # You must at least mark one option as accepted, otherwise a runtime - # error will be thrown. You can mark multiple options as accepted. - - option: Answer 1 - accept: true - - option: Answer 2 - - option: Answer 3 -``` diff --git a/sre-recipes/recipes/configs_based/disabled/README.md b/sre-recipes/recipes/configs_based/disabled/README.md deleted file mode 100644 index d552db570..000000000 --- a/sre-recipes/recipes/configs_based/disabled/README.md +++ /dev/null @@ -1,2 +0,0 @@ -Any recipe config in this directory is considered inactive or disabled, thus not -runnable via the `sandboxctl`. diff --git a/sre-recipes/recipes/configs_based/disabled/recipe1.yaml b/sre-recipes/recipes/configs_based/disabled/recipe1.yaml deleted file mode 100644 index b3a1689ac..000000000 --- a/sre-recipes/recipes/configs_based/disabled/recipe1.yaml +++ /dev/null @@ -1,67 +0,0 @@ -# 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. - -# -*- coding: utf-8 -*- - -name: Encoding Recipe -description: | - This implements recipe 1, which purposefully breaks encoding logic in the - email service, which is a part of the checkout flow for sending order - confirmation emails. -config: - break: - - action: run-shell-commands - commands: - - kubectl set env deployment/emailservice ENCODE_EMAIL=true - - kubectl delete pod $(kubectl get pod -l app=emailservice -o jsonpath='{.items[0].metadata.name}') - - kubectl wait --for=condition=available --timeout=600s deployment/emailservice - restore: - - action: run-shell-commands - commands: - - kubectl set env deployment/emailservice ENCODE_EMAIL=false - - kubectl delete pod $(kubectl get pod -l app=emailservice -o jsonpath='{.items[0].metadata.name}') - - kubectl wait --for=condition=available --timeout=600s deployment/emailservice - hint: | - Visit the external IP of the demo application and try buying some products. - You can also use monitoring dashboards to see metrics associated with each - service, and use Cloud Logging to view logs exported by each service. - Note: It may take up to 5 minutes for monitoring metrics to be updated. - You can also use `sandboxctl describe` to get information (such as project - ID, logs, core URLs) for your sandbox. - verify: - - action: multiple-choice-quiz - prompt: Which service has an issue? - choices: - - option: Ad - - option: Cart - - option: Checkout - - option: Currency - - option: Email - accept: true - - option: Frontend - - option: Payment - - option: Product Catalog - - option: Rating - - option: Recommendation - - option: Shipping - - action: multiple-choice-quiz - prompt: What was the cause of the issue? - choices: - - option: Dropped Requests - - option: Failed connections to other services - - option: High latency - - option: High memory usage - - option: Memory Quota Exceeded - - option: Internal Server Error - accept: true diff --git a/sre-recipes/recipes/configs_based/recipe0.yaml b/sre-recipes/recipes/configs_based/recipe0.yaml deleted file mode 100644 index 96124946d..000000000 --- a/sre-recipes/recipes/configs_based/recipe0.yaml +++ /dev/null @@ -1,72 +0,0 @@ -# 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. - -# -*- coding: utf-8 -*- - -name: Currency Recipe -description: | - This implements recipe 0, which purposefully introduces latency into the - frontend service by doing a lot of unnecessary currency conversions. -config: - break: - - action: loadgen-stop - - action: run-shell-commands - commands: - - kubectl set env deployment/frontend CONVERT_CURRENCIES=true - - kubectl delete pod $(kubectl get pod -l app=frontend -o jsonpath='{.items[0].metadata.name}') - - kubectl wait --for=condition=available --timeout=600s deployment/frontend - - action: loadgen-spawn - user_type: BasicHomePageViewingUser - user_count: 20 - spawn_rate: 5 - stop_after: 600 - restore: - - action: loadgen-stop - - action: run-shell-commands - commands: - - kubectl set env deployment/frontend CONVERT_CURRENCIES=false - - kubectl delete pod $(kubectl get pod -l app=frontend -o jsonpath='{.items[0].metadata.name}') - - kubectl wait --for=condition=available --timeout=600s deployment/frontend - hint: | - Visit the external IP of the demo application to see if there are any - visible changes. You can also use monitoring dashboards to see metrics - associated with each service. Note: It may take up to 5 minutes for - monitoring metrics to be updated. You can also use `sandboxctl describe` - to get information (such as project ID, logs, core URLs) for your sandbox. - verify: - - action: multiple-choice-quiz - prompt: Which service has an issue? - choices: - - option: Ad - - option: Cart - - option: Checkout - - option: Currency - - option: Email - - option: Frontend - accept: true - - option: Payment - - option: Product - - option: Rating - - option: Recommendation - - option: Shipping - - action: multiple-choice-quiz - prompt: What was the cause of the issue? - choices: - - option: Dropped Requests - - option: Failed connections to other services - - option: High latency - accept: true - - option: High memory usage - - option: Memory Quota Exceeded - - option: Internal Server Error diff --git a/sre-recipes/recipes/configs_based/recipe2.yaml b/sre-recipes/recipes/configs_based/recipe2.yaml deleted file mode 100644 index 9b2882e29..000000000 --- a/sre-recipes/recipes/configs_based/recipe2.yaml +++ /dev/null @@ -1,61 +0,0 @@ -# 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. - -# -*- coding: utf-8 -*- - -name: Ratings Freshness Recipe -description: | - This implements recipe 2, which purposefully stops ratings service recollect - API calls to rating service, so the ratings will become stale. -config: - break: - - action: run-shell-commands - commands: - - gcloud scheduler jobs pause ratingservice-recollect-job --project $(gcloud config list --format "value(core.project)") 2>&1 - restore: - - action: run-shell-commands - commands: - - gcloud scheduler jobs resume ratingservice-recollect-job --project $(gcloud config list --format "value(core.project)") 2>&1 - hint: | - Product ratings are managed by the "rating service", hosted on Google AppEngine. - The service provides APIs that allow other services to get and update products' ratings. - The rating data is kept up-to-date by periodically calling an API endpoint that collects, - all recently sent new rating scores for each product and calculates the new rating, - based on the old value and the new scores. Try to check if the rating service operates normally. - You can also use `sandboxctl describe` to get information (such as project - ID, logs, core URLs) for your sandbox. - verify: - - action: multiple-choice-quiz - prompt: Which service has an issue? - choices: - - option: Ad - - option: Cart - - option: Checkout - - option: Currency - - option: Email - - option: Frontend - - option: Payment - - option: Product Catalog - - option: Rating - accept: true - - option: Recommendation - - option: Shipping - - action: multiple-choice-quiz - prompt: What was the cause of the issue? - choices: - - option: Rating service does not run - - option: Rating votes data is missing in the database - - option: Scheduler job that sends recollect request to rating service does not work - accept: true - - option: New ratings are calculated incorrectly diff --git a/sre-recipes/recipes/configs_based/recipe3.yaml b/sre-recipes/recipes/configs_based/recipe3.yaml deleted file mode 100644 index 0e12e984e..000000000 --- a/sre-recipes/recipes/configs_based/recipe3.yaml +++ /dev/null @@ -1,63 +0,0 @@ -# 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. - -# -*- coding: utf-8 -*- - -name: Recommendation Crash Recipe -description: | - This implements recipe 3, which adds a crashing bug to the recommendation - service by causing an exception in request processing. -config: - break: - # Dev Note: the MAX_RESPONSES is 5.0, a float, which will cause crash - # during integer conversion stage in the service. - - action: run-shell-commands - commands: - - kubectl set env deployment/recommendationservice MAX_RESPONSES=5.0 - - kubectl delete pod $(kubectl get pod -l app=recommendationservice -o jsonpath='{.items[0].metadata.name}') - - kubectl wait --for=condition=available --timeout=600s deployment/recommendationservice - restore: - - action: run-shell-commands - commands: - - kubectl set env deployment/recommendationservice MAX_RESPONSES- - - kubectl delete pod $(kubectl get pod -l app=recommendationservice -o jsonpath='{.items[0].metadata.name}') - - kubectl wait --for=condition=available --timeout=600s deployment/recommendationservice - hint: | - Browse your website until you encounter an issue, and use Cloud Logging to - view logs exported by each service. You can also use `sandboxctl describe` - to get information (such as project ID, logs, core URLs) for your sandbox. - verify: - - action: multiple-choice-quiz - prompt: Which service has an issue? - choices: - - option: Ad - - option: Cart - - option: Checkout - - option: Currency - - option: Email - - option: Frontend - - option: Payment - - option: Product Catalog - - option: Rating - - option: Recommendation - accept: true - - option: Shipping - - action: multiple-choice-quiz - prompt: What was the cause of the issue? - choices: - - option: High Latency - - option: Internal Service Error - accept: true - - option: Failed Connection to Other Services - - option: Memory Quota Issues diff --git a/sre-recipes/recipes/configs_based/schema/README.md b/sre-recipes/recipes/configs_based/schema/README.md deleted file mode 100644 index fb219c709..000000000 --- a/sre-recipes/recipes/configs_based/schema/README.md +++ /dev/null @@ -1,61 +0,0 @@ -## Config Based SRE Recipe Schema - -This directory defines the schema validation for SRE Recipes configs. - -It uses the JSON Schema (https://json-schema.org/) definition based the parsed -JSON from the YAML format. - -### Usage - -If you need to write reusable schema definitions that can be referenced via -`$ref` field, define them in the `./defs` subdirectory. - -### Adding validation for a new SRE Recipe action - -1. Define the JSON schema for your action config under `./defs`. - - For example, our `loadgen-spawn` action config schema validation are defined - at `./defs/loadgen-spawn.schema.json` - -2. Add your new action to the `./defs/action-config-list.schema.json` schema - - a. Add your action config name to the list of `enums` under `Supported action configs names`. - - b. Attach your schema definition reference to the config name by adding a new `if-then` tuple under `allOf`. - -For example, if you added a new action handler for `action: my-action`, then: - -1. create a `./defs/my-action.schema.json` schema definition -2. add to the `action-config-list.schema.json`: - -``` -{ - // other stuff .... - "items": { - "properties": { - "action": { - "type": "string", - "description": "Supported action configs names", - "enum": [ - // other stuff .... - "my-action" // step a: add your action name here - ] - } - }, - "allOf": [ - // .... - // step b: attach your schema definition here - { - "description": "The schema definition for `action: my-action`", - "if": { - "properties": { "action": { "const": "my-action" } } - }, - "then": { - "$ref": "#/$defs/my-action" - } - } - ] - }, - // other stuff .... -} -``` diff --git a/sre-recipes/recipes/configs_based/schema/defs/README.md b/sre-recipes/recipes/configs_based/schema/defs/README.md deleted file mode 100644 index 182a349a0..000000000 --- a/sre-recipes/recipes/configs_based/schema/defs/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# JSON Schema Definitions - -This directory contains all the JSON schema definitions that will be pulled into -the root `$def` section of the main root schema at `schema.json` (in the parent -directory) for reference at SRE Recipe validation schema bundling time. - -**Requirements** - -1. All schema definitions should follow the naming convention of `ABC.schema.json` -2. The individual schema definition file should NOT define its own `definitions` - or `$defs` sections. If you need to reuse certain schema definition, make - it a new schema definition file on its own. - -For a definition file named `ABC.schema.json`, it can be referenced by -`#/$defs/abc` by both the root `schema.json` and any other definition file -under this `./defs` directory. - -### Example - -- `schema.json`: - -```json -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "schema.json", - "type": "object", - "properties": { - "first-name": { - "$ref": "#/$defs/name" - }, - "last-name": { - "$ref": "#/$defs/name" - }, - "age": { - "$ref": "#/$defs/age" - } - } -} -``` - -- `defs/name.schema.json`: - -```json -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "name.schema.json", - "type": "string", - "minLength": 1 -} -``` - -- `defs/age.schema.json`: - -```json -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "age.schema.json", - "type": "integer", - "minimum": 1 -} -``` diff --git a/sre-recipes/recipes/configs_based/schema/defs/action-config-list.schema.json b/sre-recipes/recipes/configs_based/schema/defs/action-config-list.schema.json deleted file mode 100644 index 4455f075e..000000000 --- a/sre-recipes/recipes/configs_based/schema/defs/action-config-list.schema.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "type": "array", - "description": "The main schema for defining a list of action configs", - "items": { - "properties": { - "action": { - "type": "string", - "description": "Supported action configs names", - "enum": [ - "run-shell-commands", - "loadgen-spawn", - "loadgen-stop", - "multiple-choice-quiz" - ] - } - }, - "allOf": [ - { - "description": "The schema definition for `action: run-shell-commands`", - "if": { - "properties": { "action": { "const": "run-shell-commands" } } - }, - "then": { - "$ref": "#/$defs/run-shell-commands" - } - }, - { - "description": "The schema definition for `action: loadgen-spawn`", - "if": { - "properties": { "action": { "const": "loadgen-spawn" } } - }, - "then": { - "$ref": "#/$defs/loadgen-spawn" - } - }, - { - "description": "The schema definition for `action: loadgen-stop`", - "if": { - "properties": { "action": { "const": "loadgen-stop" } } - }, - "then": { - "$ref": "#/$defs/loadgen-stop" - } - }, - { - "description": "The schema definition for `action: multiple-choice-quiz`", - "if": { - "properties": { "action": { "const": "multiple-choice-quiz" } } - }, - "then": { - "$ref": "#/$defs/multiple-choice-quiz" - } - } - ] - }, - "minItems": 1 -} diff --git a/sre-recipes/recipes/configs_based/schema/defs/loadgen-spawn.schema.json b/sre-recipes/recipes/configs_based/schema/defs/loadgen-spawn.schema.json deleted file mode 100644 index 45bda18d1..000000000 --- a/sre-recipes/recipes/configs_based/schema/defs/loadgen-spawn.schema.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "type": "object", - "description": "The config schema for generating a specific load pattern to the sandbox frontend.", - "required": ["action"], - "properties": { - "action": { - "type": "string", - "const": "loadgen-spawn", - "description": "Required identifier for loadgen-spawn action." - }, - "user_type": { - "type": "string", - "description": "Optional. The `sre_recipe_user_identifier` for locust tasks defined in `sre/loadgenerator/locust_tasks`. Default: BasicHomePageViewingUser.", - "minLength": 1 - }, - "user_count": { - "type": "integer", - "description": "Optional. The number of total users to spawn. Default: 20.", - "minimum": 1 - }, - "spawn_rate": { - "type": "integer", - "description": "Optional. The number of users per second to spawn. Default: 1.", - "minimum": 1 - }, - "stop_after": { - "type": "integer", - "description": "Optional. The number of seconds to spawn before stopping. Default: 600.", - "minimum": 1 - } - }, - "additionalProperties": false -} diff --git a/sre-recipes/recipes/configs_based/schema/defs/loadgen-stop.schema.json b/sre-recipes/recipes/configs_based/schema/defs/loadgen-stop.schema.json deleted file mode 100644 index 2ba763a3f..000000000 --- a/sre-recipes/recipes/configs_based/schema/defs/loadgen-stop.schema.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "type": "object", - "description": "The config schema for stopping any active load generation produced by SRE Recipe Load Generator.", - "required": ["action"], - "properties": { - "action": { - "type": "string", - "const": "loadgen-stop", - "description": "Required identifier for loadgen-stop action." - } - }, - "additionalProperties": false -} diff --git a/sre-recipes/recipes/configs_based/schema/defs/multiple-choice-quiz.schema.json b/sre-recipes/recipes/configs_based/schema/defs/multiple-choice-quiz.schema.json deleted file mode 100644 index dfd92cdb0..000000000 --- a/sre-recipes/recipes/configs_based/schema/defs/multiple-choice-quiz.schema.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "type": "object", - "description": "The config schema for running an interactive multiple choice quiz.", - "required": ["action", "prompt", "choices"], - "properties": { - "action": { - "type": "string", - "const": "multiple-choice-quiz", - "description": "Required identifier for multiple-choice-quiz action." - }, - "prompt": { - "type": "string", - "description": "Required. The question prompt to display.", - "minLength": 1 - }, - "choices": { - "type": "array", - "description": "Required. The list of potential answers to choose from.", - "minItems": 1, - "items": { - "type": "object", - "description": "The config schema for a specific answer choice", - "required": ["option"], - "properties": { - "option": { - "type": "string", - "description": "Required. The answer display text to show user." - }, - "accept": { - "type": "boolean", - "description": "Optional. When true, this entry will be accepted as correct." - } - }, - "additionalProperties": false - }, - "contains": { - "type": "object", - "description": "At least one answer config has `accept` defined as True.", - "required": ["accept"], - "properties": { - "accept": { - "type": "boolean", - "enum": [true] - } - } - }, - "uniqueItems": true - } - }, - "additionalProperties": false -} diff --git a/sre-recipes/recipes/configs_based/schema/defs/run-shell-commands.schema.json b/sre-recipes/recipes/configs_based/schema/defs/run-shell-commands.schema.json deleted file mode 100644 index bc81362d6..000000000 --- a/sre-recipes/recipes/configs_based/schema/defs/run-shell-commands.schema.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "type": "object", - "description": "The config schema for running a list of shell commands one at a time", - "required": ["action", "commands"], - "properties": { - "action": { - "type": "string", - "const": "run-shell-commands", - "description": "Required identifier for run-shell-commands action." - }, - "commands": { - "type": "array", - "description": "Required. A list of shell command strings", - "items": { - "type": "string", - "description": "Valid command string passed to Python `subprocess.run`", - "minLength": 1 - } - } - }, - "additionalProperties": false -} diff --git a/sre-recipes/recipes/configs_based/schema/schema.json b/sre-recipes/recipes/configs_based/schema/schema.json deleted file mode 100644 index 750292537..000000000 --- a/sre-recipes/recipes/configs_based/schema/schema.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "schema.json", - "title": "SRE Recipe Config - Schema Definitions", - "type": "object", - "description": "The base schema for an SRE Recipe", - "required": ["name", "description", "config"], - "properties": { - "name": { - "type": "string", - "description": "The name of the SRE Recipe", - "minLength": 1 - }, - "description": { - "type": "string", - "description": "The description of the SRE Recipe", - "minLength": 1 - }, - "config": { - "type": "object", - "description": "The config section for the SRE Recipe", - "required": ["break", "restore", "hint", "verify"], - "properties": { - "break": { - "description": "A list of actions to run for the `sandboxctl sre-receipes break` command", - "$ref": "#/$defs/action-config-list" - }, - "restore": { - "description": "A list of actions to run for the `sandboxctl sre-receipes restore` command", - "$ref": "#/$defs/action-config-list" - }, - "hint": { - "type": "string", - "description": "A hint string to display for the `sandboxctl sre-receipes hint` command", - "minLength": 1 - }, - "verify": { - "description": "A list of actions to run for the `sandboxctl sre-receipes verify` command", - "$ref": "#/$defs/action-config-list" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false -} diff --git a/sre-recipes/recipes/impl_based/README.md b/sre-recipes/recipes/impl_based/README.md deleted file mode 100644 index b2bfa1d68..000000000 --- a/sre-recipes/recipes/impl_based/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Implementation-Based SRE Recipe - -This directory contains configs for implementation based SRE Recipes. - -## Implementing the Recipe - -To create a implemented base SRE Recipe, create a file under `recipes/impl_based` -directory that implements a child class extending the `BaseRecipeImpl` from -`base.py`. - -For the recipe to be recognized as a recipe runnable via `sandboxctl`, include -`recipe` substring somewhere in the filename - -For example, to implement a recipe named `my_recipe` that can be invoked via -`sandboxctl sre-recipes my_recipe`, create a python implementation -named `recipes/impl_based/my_recipe.py` that implements a child class -extending the `BaseRecipeImpl` from `base.py`. - -If you are curious about how our SRE Recipe runner loads and reads your -implementation dynamically, check out the `ImplBasedRecipeRunner` in -`recipe_runner.py`. diff --git a/sre-recipes/recipes/impl_based/__init__.py b/sre-recipes/recipes/impl_based/__init__.py deleted file mode 100644 index 6913f02e3..000000000 --- a/sre-recipes/recipes/impl_based/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# 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. diff --git a/sre-recipes/recipes/impl_based/base.py b/sre-recipes/recipes/impl_based/base.py deleted file mode 100644 index bd700cd7c..000000000 --- a/sre-recipes/recipes/impl_based/base.py +++ /dev/null @@ -1,47 +0,0 @@ -# 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. - -# -*- coding: utf-8 -*- - -import abc - - -class BaseRecipeImpl(abc.ABC): - """The base abstract class for implementation based SRE Recipe.""" - - @abc.abstractmethod - def get_name(self): - """Returns the name of the recipe.""" - - @abc.abstractmethod - def get_description(self): - """Returns the descripion of the recipe.""" - - @abc.abstractmethod - def run_break(self): - """Performs SRE Recipe actions to break a sandbox service.""" - - @abc.abstractmethod - def run_restore(self): - """Performs SRE Recipe actions to restore a sandbox service.""" - - @abc.abstractmethod - def run_hint(self): - """Prints a hint about the root cause of the issue""" - - @abc.abstractmethod - def run_verify(self): - """ - Verifies that the user of the recipe found the correct impacted broken - service, as well as the root cause of the breakage.""" diff --git a/sre-recipes/recipes/impl_based/disabled/README.md b/sre-recipes/recipes/impl_based/disabled/README.md deleted file mode 100644 index 23e7d6132..000000000 --- a/sre-recipes/recipes/impl_based/disabled/README.md +++ /dev/null @@ -1,2 +0,0 @@ -Any recipe implementation in this directory is considered inactive or disabled, -thus not runnable via the `sandboxctl`. diff --git a/sre-recipes/recipes/impl_based/disabled/dummy_recipe.py b/sre-recipes/recipes/impl_based/disabled/dummy_recipe.py deleted file mode 100644 index e90237c1e..000000000 --- a/sre-recipes/recipes/impl_based/disabled/dummy_recipe.py +++ /dev/null @@ -1,41 +0,0 @@ -# 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. - -# -*- coding: utf-8 -*- -""" -This module contains the implementation of a dummy implementation based Recipe. -""" - -from .base import BaseRecipeImpl - - -class DummyRecipe(BaseRecipeImpl): - - def get_name(self): - return "A dummy recipe" - - def get_description(self): - return "A implementation based recipe for illustration purposes only" - - def run_break(self): - print("Nothing to break.") - - def run_restore(self): - print("Nothing to restore.") - - def run_hint(self): - print("No hints needed. I am a dummy recipe.") - - def run_verify(self): - print("Nothing to verify. It's just a dummy recipe") diff --git a/sre-recipes/requirements.txt b/sre-recipes/requirements.txt deleted file mode 100644 index b9a54caaf..000000000 --- a/sre-recipes/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -click>=7.1.0 -pyyaml>-5.4.1 -requests>=2.24.0 \ No newline at end of file diff --git a/sre-recipes/sandboxctl b/sre-recipes/sandboxctl deleted file mode 100755 index 8ecfc5d7b..000000000 --- a/sre-recipes/sandboxctl +++ /dev/null @@ -1,227 +0,0 @@ -#!/usr/bin/env python3 -# -# 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. - -# -*- coding: utf-8 -*- -""" -This CLI is the interface for sre recipes. It deploys and rolls back -broken services as well as verifies that the user found the correct -cause of the broken service. - -For information on how to run the CLI, run the following: -`python3 sandboxctl --help` -""" - -import logging -import os -import glob -import signal -import subprocess -import sys - -import click - -import utils -from recipe_runner import ImplBasedRecipeRunner -from recipe_runner import ConfigBasedRecipeRunner - -cli = click.Group() - - -def get_config_based_recipes(): - files = glob.glob(os.path.join(os.path.dirname( - os.path.abspath(__file__)), "recipes/configs_based/*.yaml")) - recipe_names = [os.path.basename(x).split(".")[0] for x in files] - return recipe_names - - -def get_impl_based_recipes(): - files = glob.glob(os.path.join(os.path.dirname( - os.path.abspath(__file__)), "recipes/impl_based/*recipe*.py")) - recipe_names = [os.path.basename(x).split(".")[0] for x in files] - return recipe_names - - -CONFIG_RECIPES = get_config_based_recipes() -IMPL_RECIPES = get_impl_based_recipes() - - -@cli.command() -@click.argument('action', type=click.Choice( - ['break', 'restore', 'verify', 'hint'])) -@click.argument('recipe_name', type=click.Choice( - sorted(CONFIG_RECIPES + IMPL_RECIPES))) -@click.option('--skip-loadgen', is_flag=True, help="Ignore loadgen actions in config based recipes.") -def sre_recipes(action, recipe_name, skip_loadgen): - """Performs an action on a recipe.""" - logging.basicConfig(filename='srerecipes.log', level=logging.INFO, - format='%(asctime)s %(message)s') - - try: - has_config = recipe_name in CONFIG_RECIPES - has_impl = recipe_name in IMPL_RECIPES - - recipe = None - if has_config and has_impl: - print(f"Find conflicting config & impl for {recipe_name}") - return - elif has_config: - recipe = ConfigBasedRecipeRunner(recipe_name, skip_loadgen=skip_loadgen) - elif has_impl: - recipe = ImplBasedRecipeRunner(recipe_name) - else: - # should not reach here due to 'click.Choice' above - print(f"Cannot find config or impl for {recipe_name}") - return - - if action == 'break': - logging.info(f"Breaking {recipe_name}") - recipe.run_break() - elif action == 'restore': - logging.info(f"Restoring {recipe_name}") - recipe.run_restore() - elif action == 'verify': - logging.info(f"Verifying {recipe_name}") - recipe.run_verify() - elif action == 'hint': - logging.info(f"Giving hint for {recipe_name}") - recipe.run_hint() - except Exception as e: - logging.error(e) - print(f"Failed to run SRE Recipe {recipe_name}: {e}") - exit(1) - - -@cli.command() -@click.argument('traffic_pattern', type=click.Choice(['basic', 'step'])) -def loadgen(traffic_pattern): - """Change traffic patterns for the loadgenerator service""" - #We will always switch back to cloud-ops-sandbox cluster after successful - #completion of this command, assuming it is the most common cluster to be in. - set_env_command = "kubectl set env deployment/loadgenerator "\ - f"LOCUST_TASK={traffic_pattern}" - delete_pods_command = "kubectl delete pods -l app=loadgenerator" - - if not utils.auth_cluster('loadgenerator'): - print("Failed to authenticate into load generator cluster") - return - print('Redeploying Loadgenerator...') - _, err = utils.run_shell_command(set_env_command) - if err: - print("Failed to set traffic pattern for load generator: ", err) - _, err = utils.run_shell_command(delete_pods_command) - if err: - print("Failed to redeploy updated load generator: ", err) - print(f'Loadgenerator deployed using {traffic_pattern} pattern') - ip_addr, err = utils.get_loadgen_ip() - if err: - print("Failed to get load generator IP: ", err) - elif not ip_addr: - print("Found empty load generator IP") - else: - print(f"Loadgenerator web UI: http://{ip_addr}") - - # Try switching back to cloud-ops-sandbox cluster. - # Do not error even if we fail - utils.auth_cluster('cloud-ops-sandbox') - - -@cli.command() -@click.option('--project', '-p', default=None, - help='GCP project to deploy Cloud Operations Sandbox to') -@click.option('--verbose', '-v', default=False, is_flag=True, - help='print commands as they run (set -x)') -@click.option('--skip-loadgenerator', default=False, is_flag=True, - help="Don't deploy the loadgenerator instance") -@click.option('--skip-ratingservice', default=False, is_flag=True, - help="Don't deploy the ratingservice") -@click.option('--service-wait', default=False, is_flag=True, - help='Wait indefinitely for services to be detected by Cloud Monitoring') -def create(project, *args, **kwargs): - """Create a new sandbox""" - os.chdir(os.path.abspath(sys.path[0])) - command = "../terraform/install.sh" - # add optional project argument - if project: - command += f' --project {project}' - # add flags passed in to function - for (arg, value) in kwargs.items(): - if value: - command += f' --{arg.replace("_", "-")}' - os.setpgrp() - complete = False - try: - # run install.sh in a background shell - process = subprocess.Popen(command, bufsize=0, shell=True) - process.communicate() - complete = True - finally: - # kill background process if script is terminated - if not complete: - os.killpg(0, signal.SIGTERM) - - -@cli.command() -def describe(): - """Show information about an existing sandbox""" - gcp_path = "https://console.cloud.google.com" - project_id, err = utils.get_project_id() - if err: - print("Failed to get project ID:", err) - external_ip, err = utils.get_external_ip() - if err: - print("Failed to get external ID:", err) - loadgen_ip, err = utils.get_loadgen_ip() - if err: - print("Failed to get loadgen ID:", err) - gcp_kubernetes_path = gcp_path + '/kubernetes/workload?project=' + project_id - gcp_monitoring_path = gcp_path + '/monitoring?project=' + project_id - print(f"""Cloud Operations Sandbox info for project: {project_id} - - Load generator web interface: http://{loadgen_ip} - - Hipstershop web app address: http://{external_ip} - - Google Cloud Console KBE Dashboard: {gcp_kubernetes_path} - - Google Cloud Console Monitoring Workspace {gcp_monitoring_path}""") - - -@cli.command() -def destroy(): - """Delete an existing sandbox""" - os.chdir(os.path.abspath(sys.path[0])) - destroy_command = "../terraform/destroy.sh" - utils.run_interactive_shell_command(destroy_command) - -@cli.command() -@click.option('--skip-ratingservice', default=False, is_flag=True, - help="Don't test the ratingservice") -def test(skip_ratingservice): - """Run tests to ensure environment is working as expected""" - os.chdir(os.path.abspath(sys.path[0])) - command = "../tests/run_tests.sh" - if skip_ratingservice: - command = f'SKIP_RATINGS_TEST=TRUE {command}' - os.setpgrp() - complete = False - try: - # run install.sh in a background shell - process = subprocess.Popen(command, bufsize=0, shell=True) - process.communicate() - complete = True - finally: - # kill background process if script is terminated - if not complete: - os.killpg(0, signal.SIGTERM) - -if __name__ == "__main__": - cli() diff --git a/sre-recipes/utils.py b/sre-recipes/utils.py deleted file mode 100644 index f2fa8343c..000000000 --- a/sre-recipes/utils.py +++ /dev/null @@ -1,201 +0,0 @@ -# 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. - -# -*- coding: utf-8 -*- - -import subprocess -import logging - - -def run_shell_command(command, decode_output=True): - """ - Runs the given command and returns any output and error - If `decode_output` is True, try to decode output and error message with - UTF-8 encoding, as well as removing any single quote. - """ - process = subprocess.run( - command, shell=True, capture_output=True - ) - output, error = process.stdout, process.stderr - if decode_output: - if output is not None: - output = output.decode("utf-8").replace("'", '').strip() - if error is not None: - error = error.decode("utf-8").replace("'", '').strip() - return output, error - - -def run_interactive_shell_command(command): - """ - Runs the given interactive command that waits for user input and - returns any output and error - """ - subprocess.run(command.split()) - - -def get_project_id(): - """Get the Google Cloud Project ID""" - project_id, err = run_shell_command( - "gcloud config list --format 'value(core.project)'") - if not project_id: - logging.warn(f"Could not retrieve project id.") - return project_id, err - - -def get_external_ip(): - """Get the IP Address for the external LoadBalancer""" - if not auth_cluster('cloud-ops-sandbox'): - return None, "Failed to authenticate into cloud-ops-sandbox cluster" - ip_addr, err = run_shell_command( - "kubectl -n asm-ingress get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}'") - if not ip_addr: - logging.warn(f"No external IP found.") - return ip_addr, err - - -def get_loadgen_ip(): - """Get the IP Address for the load generator""" - if not auth_cluster('loadgenerator'): - return None, "Failed to authenticate into loadgenerator cluster" - ip_addr, err = run_shell_command( - "kubectl get service loadgenerator -o jsonpath='{.status.loadBalancer.ingress[0].ip}'") - if not ip_addr: - logging.warn(f"No loadgeen IP found.") - # Try switching back to cloud-ops-sandbox cluster. - # Do not error even if we fail - auth_cluster('cloud-ops-sandbox') - return ip_addr, err - - -def get_cluster_zone(project_id, cluster_name): - """Get the zone for a cluster in a given project""" - zone, err = run_shell_command( - f"gcloud container clusters list --filter name:{cluster_name} --project {project_id} --format 'value(zone)'") - if not zone: - logging.warn( - f"No zone found for {cluster_name} in project {project_id}" - ) - return zone, err - - -def auth_cluster(cluster_name="cloud-ops-sandbox"): - """ - Authenticates cluster with kubectl commands. - - @param cluster_name: the Kubernetes cluster name - Options: - - cloud-ops-sandbox - - loadgenerator - - Return true if authentication was successful, or false otherwise. - """ - logging.info("Trying to authenticate cluster...") - # Locate project ID - project_id, err = get_project_id() - if err or not project_id: - logging.error( - f"Can't authenticate cluster. Failed too get project ID: {err}") - return False - # Get cluster zone - zone, err = get_cluster_zone(project_id, cluster_name) - if err or not zone: - logging.error(f"Can't authenticate cluster. Failed to get zone: {err}") - return False - # Run authentication command - run_shell_command( - f"gcloud container clusters get-credentials {cluster_name} --project {project_id} --zone {zone}") - logging.info("Cluster has been authenticated") - return True - - -def run_interactive_multiple_choice(prompt, choices): - """Runs an interactive multiple choice Quiz. - - Example Layout: - =============================================================== - MULTIPLE CHOICE QUIZ - =============================================================== - Question: Which service has an issue? - Choices - 0: Ad - 1: Cart - 2: Checkout - 3: Currency - 4: Email - 5: Frontend - 6: Payment - 7: Product Catalog - 8: Rating - 9: Recommendation - 10: Shipping - Enter your answer: - - The user can respond with their answer by typing the number shown before - the answer choice (e.g. 1 for Cart). - - Parameters - --------- - prompt: string - The question prompt to display. - choices: dict[] - A list of potential answers to choose from. - Each entry is a dictionary of the following fields: - - option: Required. The answer display text to show user - - accept: Optional. When true, this entry will be accepted as correct. - - If multiple entries have `accept` field set to True, it means there are - multiple correct answers. If no entries have `accept` set to True, the - function will throw ValueError. - """ - if not choices: - logging.info("Skipped. Empty multiple choice.") - return - - if not all(["option" in x for x in choices]): - logging.error( - "The 'option' field is required for all answer choice entries.") - exit(1) - - if not any([x.get("accept", False) for x in choices]): - logging.error( - "No accepted answer found in in the pool of potential answers.") - exit(1) - - # Show the question - print("===============================================================") - print(" MULTIPLE CHOICE QUIZ ") - print("===============================================================") - print(f"Question: {prompt}") - print("Choices") - correct_answers = set() - for i, choice in enumerate(choices): - display_text = choice["option"].strip() - print(f" {i}: {display_text}") - if choice.get("accept", False): - correct_answers.add(i) - - # Asks for answer - while True: - user_answer = input("Enter your answer: ").strip() - try: - user_answer = int(user_answer) - if user_answer < 0 or user_answer >= len(choices): - print("Not a valid choice") - elif user_answer in correct_answers: - print("Congratulations! You are correct.") - return - else: - print("Incorrect. Please try again.") - except ValueError: - print("Please enter the number of your selected answer.") diff --git a/terraform/00_state.tf b/terraform/00_state.tf deleted file mode 100644 index b957cc110..000000000 --- a/terraform/00_state.tf +++ /dev/null @@ -1,31 +0,0 @@ -# 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. - - -# We use gcs as our backend, so the state file will be stored -# in a storage bucket. Since the bucket must preexists, we will create -# the project and bucket outside Terraform. Also since the configuration -# of bucket can't be a variable, we create an empty config and modify it -# in the data section. - -terraform { - backend "gcs" {} -} - -data "terraform_remote_state" "state" { - backend = "gcs" - config = { - bucket = var.bucket_name - } -} diff --git a/terraform/01_provider.tf b/terraform/01_provider.tf deleted file mode 100644 index 3c70cbd35..000000000 --- a/terraform/01_provider.tf +++ /dev/null @@ -1,48 +0,0 @@ -# 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. - -# the `provider` block contains the configuration for the provider, including -# credentials and region config. It can be configured via environment variables -# or via passing a path to a credentials JSON file. - -# In this demo we're using Application Default Creds instead, see this for -# details: https://cloud.google.com/docs/authentication/production -# -# TODO: we can consider configuring it via env vars -# that were populated appropriately at runtime. -terraform { - # The module has 0.12 syntax and is not compatible with any versions below 0.12. - required_version = "~> 1.0" - - required_providers { - google = { - source = "hashicorp/google" - version = "~> 3.90.0" - } - google-beta = { - source = "hashicorp/google" - version = "~> 3.90.0" - } - random = { - source = "hashicorp/random" - version = "~> 2.0" - } - - } -} - -provider "google" { - project = var.project_id -} - diff --git a/terraform/02_project.tf b/terraform/02_project.tf deleted file mode 100644 index 0fe24efa6..000000000 --- a/terraform/02_project.tf +++ /dev/null @@ -1,130 +0,0 @@ -# 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. - -# Here we are creating a project to contain the deployed resources. A couple of -# general terraform notes: this is the first time we're seeing the `data` -# stanza. This gives a way to look stuff up and use it in other resources. Here -# we're looking up the billing account by name (hence why the README has you -# name it a certain way) so we can pass its ID on later. - -# billing account is optional to allow deploying to existing projects -data "google_billing_account" "acct" { - count = var.billing_account != null ? 1 : 0 - display_name = var.billing_account -} - -data "google_project" "project" { - project_id = var.project_id -} - -resource "google_project_service" "iam" { - project = data.google_project.project.project_id - - service = "iam.googleapis.com" - - disable_dependent_services = true -} - -resource "google_project_service" "compute" { - project = data.google_project.project.project_id - - service = "compute.googleapis.com" - - disable_dependent_services = true -} - -resource "google_project_service" "clouddebugger" { - project = data.google_project.project.project_id - - service = "clouddebugger.googleapis.com" - - disable_dependent_services = true -} - - -resource "google_project_service" "cloudtrace" { - project = data.google_project.project.project_id - - service = "cloudtrace.googleapis.com" - - disable_dependent_services = true -} - -resource "google_project_service" "cloudprofiler" { - project = data.google_project.project.project_id - - service = "cloudprofiler.googleapis.com" - - disable_dependent_services = true -} - -resource "google_project_service" "errorreporting" { - project = data.google_project.project.project_id - - service = "clouderrorreporting.googleapis.com" - - disable_dependent_services = true -} - -resource "google_project_service" "sourcerepo" { - project = data.google_project.project.project_id - - service = "sourcerepo.googleapis.com" - - disable_dependent_services = true -} - -resource "google_project_service" "gkehub" { - project = data.google_project.project.project_id - - service = "gkehub.googleapis.com" - - disable_dependent_services = true -} - -resource "google_project_service" "mesh" { - project = data.google_project.project.project_id - - service = "mesh.googleapis.com" - - disable_dependent_services = true -} - -# Enable GKE in the project we created. If you look at the docs you might see -# the `google_project_services` resource which allows you to specify a list of -# resources to enable. This seems like a good idea but there's a gotcha: to use -# that resource you have to specify a comprehensive list of services to be -# enabled for your project. Otherwise it will disable services you might be -# using elsewhere. -# -# For that reason, we use the single service option instead since it allows us -# granular control. -resource "google_project_service" "gke" { - # This could just as easily reference `random_id.project.dec` but generally - # you want to dereference the actual object you're trying to interact with. - # - # You'll see this line in every resource we create from here on out. This is - # necessary because we didn't configure the provider with a project because - # the project didn't exist yet. This could be refactored such that the project - # was created outside of terraform, the provider configured with the project, - # and then we don't have to specify this on every resource any more. - # - # Anyway, expect to see a lot more of these. I won't explain every time. - project = data.google_project.project.project_id - - # the service URI we want to enable - service = "container.googleapis.com" - - disable_dependent_services = true -} diff --git a/terraform/03_gke_cluster.tf b/terraform/03_gke_cluster.tf deleted file mode 100644 index 3869213cd..000000000 --- a/terraform/03_gke_cluster.tf +++ /dev/null @@ -1,285 +0,0 @@ -# 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. - -# Let's create the GKE cluster! This one's pretty complicated so buckle up. - -# This is another example of the random provider. Here we're using it to pick a -# zone in us-central1 at random. -resource "random_shuffle" "zone" { - # TODO: add us-central1-a and us-central1-c once GKE completely rolls out Oct 2 release - input = ["us-central1-b", "us-central1-f"] - - # Seeding the RNG is technically optional but while building this we - # found that it only ever picked `us-central-1c` unless we seeded it. Here - # we're using the ID of the project as a seed because it is unique to the - # project but will not change, thereby guaranteeing stability of the results. - seed = data.google_project.project.project_id -} - -# First we create the cluster. If you're wondering where all the sizing details -# are, they're below in the `google_container_node_pool` resource. We'll get -# back to that in a minute. -# -# One thing to note here is the name of the resource ("gke") is only used -# internally, for instance when you're referencing the resource (eg -# `google_container_cluster.gke.id`). The actual created resource won't know -# about it, and in fact you can specify the name for that in the resource -# itself. -# -# Finally, there are many, many other options available. The resource below -# replicates what the Hipster Shop README creates. If you want to see what else -# is possible, check out the docs: https://www.terraform.io/docs/providers/google/r/container_cluster.html -resource "google_container_cluster" "gke" { - provider = google-beta - project = data.google_project.project.project_id - - # Here's how you specify the name - name = var.gke_cluster_name - - # If GKE_cluster was specify during insalltion use it otherwise set the zone by grabbing the result of the random_shuffle above. - # It returns a list so we have to pull the first element off. If you're looking - # at this and thinking "huh terraform syntax looks a clunky" you are NOT WRONG - location = var.gke_location != "" ? var.gke_location : element(random_shuffle.zone.result, 0) - - # Enable Workload Identity for cluster - workload_identity_config { - workload_pool = "${data.google_project.project.project_id}.svc.id.goog" - } - - resource_labels = { - "version" = var.app_version - "mesh_id" = "proj-${data.google_project.project.number}" - } - - # Using an embedded resource to define the node pool. Another - # option would be to create the node pool as a separate resource and link it - # to this cluster. There are tradeoffs to each approach. - # - # The embedded resource is convenient but if you change it you have to tear - # down the entire cluster and rebuild it. A separate resource could be - # modified independent of the cluster without the cluster needing to be torn - # down. - # - # For this particular case we're not going to be modifying the node pool once - # it's deployed, so it makes sense to accept the tradeoff for the convenience - # of having it inline. - # - # Many of the parameters below are self-explanatory so I'll only call out - # interesting things. - node_pool { - node_config { - machine_type = "n1-standard-2" - - oauth_scopes = [ - "https://www.googleapis.com/auth/cloud-platform" - ] - - labels = { - environment = "dev", - cluster = "cloud-ops-sandbox-main" - mesh_id = "proj-${data.google_project.project.number}" - } - - # Enable Workload Identity for node pool - workload_metadata_config { - mode = "GKE_METADATA" - } - } - - initial_node_count = 4 - - autoscaling { - min_node_count = 4 - max_node_count = 10 - } - - management { - auto_repair = true - auto_upgrade = true - } - } - - # Specifies the use of "new" Cloud logging and monitoring - # https://cloud.google.com/kubernetes-engine-monitoring/ - logging_service = "logging.googleapis.com/kubernetes" - monitoring_service = "monitoring.googleapis.com/kubernetes" - - # Stores the zone of created gke cluster - provisioner "local-exec" { - command = "gcloud config set compute/zone ${google_container_cluster.gke.location}" - } - - # add a hint that the service resource must be created (i.e., the service must - # be enabled) before the cluster can be created. This will not address the - # eventual consistency problems we have with the API but it will make sure - # that we're at least trying to do things in the right order. - depends_on = [google_project_service.gke, google_project_service.gkehub, google_project_service.mesh] -} - - -# Set current project -resource "null_resource" "current_project" { - provisioner "local-exec" { - command = "gcloud config set project ${data.google_project.project.project_id}" - } -} - -# Gets the default Compute Engine Service Account of GKE -data "google_compute_default_service_account" "default" { - project = data.google_project.project.project_id - depends_on = [ - google_container_cluster.gke, - null_resource.current_project - ] -} - -# Give service account Observability permissions -resource "google_project_iam_member" "trace_role" { - project = data.google_project.project.project_id - role = "roles/cloudtrace.agent" - member = "serviceAccount:${data.google_compute_default_service_account.default.email}" - depends_on = [data.google_compute_default_service_account.default] -} - -resource "google_project_iam_member" "monitoring_role" { - project = data.google_project.project.project_id - role = "roles/monitoring.metricWriter" - member = "serviceAccount:${data.google_compute_default_service_account.default.email}" - depends_on = [data.google_compute_default_service_account.default] -} - - -resource "google_project_iam_member" "profiler_role" { - project = data.google_project.project.project_id - role = "roles/cloudprofiler.agent" - member = "serviceAccount:${data.google_compute_default_service_account.default.email}" - depends_on = [data.google_compute_default_service_account.default] -} - -resource "google_project_iam_member" "debugger_role" { - project = data.google_project.project.project_id - role = "roles/clouddebugger.agent" - member = "serviceAccount:${data.google_compute_default_service_account.default.email}" - depends_on = [data.google_compute_default_service_account.default] -} - -resource "google_project_iam_member" "logging_role" { - project = data.google_project.project.project_id - role = "roles/logging.logWriter" - member = "serviceAccount:${data.google_compute_default_service_account.default.email}" - depends_on = [data.google_compute_default_service_account.default] -} - -# Create GSA/KSA binding: let IAM auth KSAs as a svc.id.goog member name -resource "google_service_account_iam_binding" "set_gsa_binding" { - service_account_id = data.google_compute_default_service_account.default.name // google_service_account.set_gsa.name - role = "roles/iam.workloadIdentityUser" - - members = [ - "serviceAccount:${data.google_project.project.project_id}.svc.id.goog[default/default]" - ] - - depends_on = [data.google_compute_default_service_account.default] -} - -# Annotate KSA -resource "null_resource" "annotate_ksa" { - triggers = { - cluster_ep = google_container_cluster.gke.endpoint #kubernetes cluster endpoint - } - - provisioner "local-exec" { - command = <' -``` - -When this is done, you'll have a new project with a running GKE cluster, all right scopes -and APIs enabled. That's all we do right now with Terraform. -If you want to get rid of it, run `terraform destroy`. - -[Install terraform]: https://www.terraform.io/downloads.html - -Guided Tour --------------------------------------------------------------------------------- - -Terraform configs are split into separate files for each function. Detailed -comments are available in each file, but here's the short version: - -* `00_state.tf` -- configure state storage -* `01_provider.tf` -- configure the terraform provider -* `02_project.tf` -- create a GCP project, set up billing, and enable services -* `03_gke_cluster.tf` -- provision a GKE cluster per to the Hipster Shop README -* `04_ratingservice.tf` -- provision and populates Postgres DB over CloudSQL and deploy ranking service to AppEngine. Creates scheduled task to aggregate new placed ratings. -* `05_loadgen.tf` -- provision a loadgen cluster per to the Hipster Shop README - -The assumption is that a system under user control would run terraform and create resources on the user's behalf. -The user would not be aware of the underlying tool. - -Monitoring Examples --------------------------------------------------------------------------------- - -To provision monitoring examples for the Cloud Operations Sandbox, navigate -to the `monitoring` folder and run the command `terraform apply`. \ No newline at end of file diff --git a/terraform/destroy.sh b/terraform/destroy.sh deleted file mode 100755 index d8c9390a3..000000000 --- a/terraform/destroy.sh +++ /dev/null @@ -1,97 +0,0 @@ -#!/bin/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 deletes the GCP project provisioned by Cloud Operations Sandbox - -#set -euo pipefail -set -o errexit # Exit on error -#set -x - -log() { echo "$1" >&2; } - -IFS=$'\n' -acct=$(gcloud info --format="value(config.account)") - -# ensure the working dir is the script's folder -SCRIPT_DIR=$(realpath $(dirname "$0")) -cd $SCRIPT_DIR - -# create variable for telemetry purposes if SESSION is not already set -# session is defined as the current "instance" in which the user is logged-in to Cloud Shell terminal, working with Sandbox -if [[ -z "$SESSION" ]]; then export SESSION=$(python3 -c "import uuid; print(uuid.uuid4())"); fi - -# this function sends de-identified information to the Google Cloud Platform database -# on what events occur in users' Sandbox projects for development purposes -sendTelemetry() { - python3 telemetry.py --session=$SESSION --project_id=$1 --event=$2 --version=$VERSION -} - -# find the cloud operations sandbox project id -filter=$(cat <<-END - (id:cloud-ops-sandbox-* AND name='Cloud Operations Sandbox Demo') - OR - (id:stackdriver-sandbox-* AND name='Stackdriver Sandbox Demo') -END -) -found=$(gcloud projects list --filter="$filter" --format="value(projectId)") - -# find projects owned by current user -for proj in ${found[@]}; do - iam_test=$(gcloud projects get-iam-policy "$proj" \ - --flatten="bindings[].members" \ - --format="table(bindings.members)" \ - --filter="bindings.role:roles/owner" 2> /dev/null | grep $acct | cat) - if [[ -n "$iam_test" ]]; then - create_time=$(gcloud projects describe "$proj" --format="value(create_time.date(%b-%d-%Y))") - owned_projects+=("$proj | [$create_time]") - fi -done - -# prompt user for a project to delete -if [[ -z "${owned_projects}" ]]; then - log "error: no Cloud Operations Sandbox projects found" - exit 1 -else - log "which Cloud Operations Sandbox project do you want to delete?:" - select opt in ${owned_projects[@]} "cancel"; do - if [[ "${opt}" == "cancel" ]]; then - exit 0 - elif [[ -z "${opt}" ]]; then - log "invalid response" - else - PROJECT_ID=$(echo $opt | awk '{print $1}') - break - fi - done -fi - -# attempt deletion (tool will prompt user for confirmation) -log "attempting to delete $PROJECT_ID" -gcloud projects delete $PROJECT_ID - - -# if user backed out or deletion failed, stop script -found=$(gcloud projects describe ${PROJECT_ID} --flatten="lifecycleState" |grep "ACTIVE") -if [[ -n "${found}" ]]; then - log "project $PROJECT_ID not deleted" - sendTelemetry $PROJECT_ID sandbox-not-destroyed - exit 1 -fi - -sendTelemetry $PROJECT_ID sandbox-destroyed -# remove tfstate file so a new project id will be generated next time -log "removing tfstate file" -rm -f .terraform/terraform.tfstate -log "Cloud Operations Sandbox resources deleted" diff --git a/terraform/get_terraform_vars.sh b/terraform/get_terraform_vars.sh deleted file mode 100755 index 9e6df96e2..000000000 --- a/terraform/get_terraform_vars.sh +++ /dev/null @@ -1,37 +0,0 @@ -# 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. -#!/bin/bash - -project_id=$(gcloud config get-value project 2> /dev/null) -zone=$(gcloud container clusters list --filter="name:cloud-ops-sandbox" --project $project_id --format="value(zone)") -gcloud container clusters get-credentials cloud-ops-sandbox --project $project_id --zone $zone > /dev/null 2> /dev/null - -# Retrieve the cluster's external IP -TRIES=0 -external_ip=""; -while [[ -z $external_ip && "${TRIES}" -lt 20 ]]; do - external_ip=$(kubectl -n asm-ingress get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}'); - [ -z "$external_ip" ] && sleep 5; - TRIES=$((TRIES + 1)) -done; - -if [[ -z $external_ip ]]; then - echo "Error: No external IP address found." -fi - -# Retrieve account email -acct=$(gcloud info --format="value(config.account)") - -json_obj='{"external_ip": "%s", "email": "%s"}' -printf "$json_obj" "$external_ip" "$acct" diff --git a/terraform/install.sh b/terraform/install.sh deleted file mode 100755 index a2ac81fc9..000000000 --- a/terraform/install.sh +++ /dev/null @@ -1,442 +0,0 @@ -#!/bin/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 provisions Hipster Shop Cluster for Cloud Operations Sandbox using Terraform -#set -euo pipefail -set -o errexit # Exit on error -#set -o nounset # Trigger error when expanding unset variables -if [[ -n "$DEBUG" ]]; then set -x; fi - -# ensure the working dir is the script's folder -SCRIPT_DIR=$(realpath $(dirname "$0")) -cd $SCRIPT_DIR - -# create variable for telemetry purposes if SESSION is not already set -# session is defined as the current "instance" in which the user is logged-in to Cloud Shell terminal, working with Sandbox -if [[ -z "$SESSION" ]]; then export SESSION=$(python3 -c "import uuid; print(uuid.uuid4())"); fi - -log() { echo "$1" >&2; } - -# this function sends de-identified information to the Google Cloud Platform database -# on what events occur in users' Sandbox projects for development purposes -sendTelemetry() { - python3 telemetry.py --session=$SESSION --project_id=$1 --event=$2 --version=$VERSION -} - -promptForBillingAccount() { - log "Checking for billing accounts..." - found_accounts=$(gcloud beta billing accounts list --format="value(displayName)" --filter open=true --sort-by=displayName) - if [ -z "$found_accounts" ] || [[ ${#found_accounts[@]} -eq 0 ]]; then - log "error: no active billing accounts were detected. In order to create a sandboxed environment," - log "the script needs to create a new GCP project and associate it with an active billing account" - log "Follow this link to setup a billing account:" - log "https://cloud.google.com/billing/docs/how-to/manage-billing-account" - log "" - log "To list active billing accounts, run:" - log "gcloud beta billing accounts list --filter open=true" - sendTelemetry "none" no-active-billing - exit 1; - fi - - # store (name:id) info in a map - IFS_bak=$IFS - declare -A map - acc_ids=$(gcloud beta billing accounts list --format="value(displayName,name)" --filter open=true --sort-by=displayName) - IFS=$'\n' - acc_ids=($acc_ids) - for acc in ${acc_ids[@]} - do - IFS=$'\t' - acc=($acc) - IFS=$'\n' - map[${acc[0]}]=${acc[1]} - done - - if [[ $(echo "${found_accounts}" | wc -l) -gt 1 ]]; then - log "Enter the number next to the billing account you would like to use:" - IFS=$'\n' - select opt in ${found_accounts} "cancel"; do - if [[ "${opt}" == "cancel" ]]; then - exit 0 - elif [[ -z "${opt}" ]]; then - log "invalid response" - else - billing_acct=${opt} - billing_id=${map[$billing_acct]} - break - fi - done - else - billing_acct=${found_accounts} - billing_id=${map[$found_accounts]} - fi - IFS=$IFS_bak -} - -promptForProject() { - log "Checking for project list..." - acct=$(gcloud info --format="value(config.account)") - # get projects associated with the billing account - billed_projects=$(gcloud beta billing projects list --billing-account="$billing_id" --filter="project_id:cloud-ops-sandbox-*" --format="value(projectId)") - for proj in ${billed_projects[@]}; do - # check if user is owner - iam_test=$(gcloud projects get-iam-policy "$proj" \ - --flatten="bindings[].members" \ - --format="table(bindings.members)" \ - --filter="bindings.role:roles/owner" 2> /dev/null | grep $acct | cat) - if [[ -n "$iam_test" ]]; then - create_time=$(gcloud projects describe "$proj" --format="value(create_time.date(%b-%d-%Y))") - found_projects+=("$proj | [$create_time]") - fi - done - - # prompt user to choose a project - if [ -z "$found_projects" ] || [[ ${#found_projects[@]} -eq 0 ]]; then - createProject; - else - log "Enter the number next to the project you would like to use:" - IFS_bak=$IFS - IFS=$'\n' - select opt in "create a new Sandbox" ${found_projects[@]} "cancel"; do - if [[ "${opt}" == "cancel" ]]; then - exit 0 - elif [[ "${opt}" == "create a new Sandbox" ]]; then - log "create a new Sandbox!" - createProject; - break - elif [[ -z "${opt}" ]]; then - log "invalid response" - else - IFS=$' |' - opt=($opt) - project_id=${opt[0]} - break - fi - done - IFS=$IFS_bak - fi - # attach to project - gcloud config set project "$project_id" -} - -getOrCreateBucket() { - # bucket name should be globally unique - bucket_name="$project_id-bucket" - - # check if bucket already exists - gcloud config set project "$project_id" - if [[ -n "$(gsutil ls | grep gs://$bucket_name/)" ]]; then - log "Bucket $bucket already exists" - else - # create new bucket - TRIES=0 - while [[ $(gsutil mb -p "$project_id" "gs://$bucket_name") || "${TRIES}" -lt 5 ]]; do - log "Checking if bucket $bucket_name exists..." - if [[ -n "$(gsutil ls | grep gs://$bucket_name/)" ]]; then - log "Bucket $bucket_name created" - break; - else - log "Bucket creation failed. retrying..." - sleep 1 - TRIES=$((TRIES + 1)) - fi - done - fi -} - -createProject() { - # generate random id - project_id="cloud-ops-sandbox-$(od -N 4 -t uL -An /dev/urandom | tr -d " ")" - # create project - if [[ $acct == *"google.com"* ]]; - then - YELLOW=`tput setaf 3` - REVERT=`tput sgr0` - log "" - log "${YELLOW}Note: your project will be created in the /untrusted/demos/cloud-ops-sandboxes folder." - log "${YELLOW}If you don't have access to this folder, please make sure to request at:" - log "${YELLOW}go/cloud-ops-sandbox-access" - log "${REVERT}" - sendTelemetry $project_id new-sandbox-googler - select opt in "continue" "cancel"; do - if [[ "$opt" == "continue" ]]; then - break; - else - exit 0; - fi - done - folder_id="470827991545" # /cloud-ops-sandboxes - gcloud projects create "$project_id" --name="Cloud Operations Sandbox Demo" --folder="$folder_id" - else - sendTelemetry $project_id new-sandbox-non-googler - gcloud projects create "$project_id" --name="Cloud Operations Sandbox Demo" - fi; - # link billing account - gcloud beta billing projects link "$project_id" --billing-account="$billing_id" -} - -applyTerraform() { - - rm -f .terraform/terraform.tfstate - - log "Initialize terraform backend with bucket ${bucket_name}" - - if terraform init -backend-config "bucket=${bucket_name}" -lockfile=false 2> /dev/null; then - log "Credential check OK..." - else - log "" - log "Credential check failed. Please login..." - gcloud auth application-default login - terraform init -backend-config "bucket=${bucket_name}" -lockfile=false # lock-free to prevent access fail - fi - - #build Terraform apply command - terraform_command="terraform apply -auto-approve -var=\"project_id=${project_id}\" -var=\"bucket_name=${bucket_name}\" -var=\"skip_ratingservice=${skip_ratingservice:-false}\" -var=\"skip_loadgen=${skip_loadgen:-false}\"" - - #If billing account provided specify it - if [[ -n "$billing_id" ]]; then - terraform_command+=" -var=\"billing_account=${billing_acct}\"" - fi - #Check application version - #If cluster already exist leave original version - gke_location="$(gcloud container clusters list --format="value(location)" --filter name=cloud-ops-sandbox)" - if [[ -n "$gke_location" ]]; then - #use existing gke_location instead of using random one - terraform_command+=" -var=\"gke_location=${gke_location}\"" - gke_version="$(gcloud container clusters describe cloud-ops-sandbox --zone "${gke_location}" --format="value(resourceLabels.version)")" - #If cluster exist and it's older version use backward comp params - if [[ -n "$gke_version" ]]; then - app_ver=$gke_version - fi - elif [[ -n "$VERSION" ]]; then - app_ver="$(echo $VERSION | tr "." "_")" - else - app_ver="0" - fi - terraform_command+=" -var=\"app_version=${app_ver}\"" - - log "Apply Terraform automation" - eval $terraform_command -} - -authenticateCluster() { - CLUSTER_ZONE=$(gcloud container clusters list --filter="name:cloud-ops-sandbox" --project $project_id --format="value(zone)") - gcloud container clusters get-credentials cloud-ops-sandbox --zone "$CLUSTER_ZONE" - # Make alias for this kubectl context - kubectx main=. -} - -installMonitoring() { - log "Retrieving the external IP address of the application..." - TRIES=0 - external_ip=""; - while [[ -z $external_ip && "${TRIES}" -lt 20 ]]; do - external_ip=$(kubectl -n asm-ingress get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}'); - [ -z "$external_ip" ] && sleep 5; - TRIES=$((TRIES + 1)) - done; - - if [[ -z $external_ip ]]; then - log "Could not retrieve external IP... skipping monitoring configuration." - return 1 - fi - - acct=$(gcloud info --format="value(config.account)") - project_number=$(gcloud projects describe $project_id --format="value(projectNumber)") - - log "Checking to make sure necessary Istio services are ready for monitoring" - python3 monitoring/istio_service_setup.py $project_number $service_wait - log "Creating monitoring examples (dashboards, uptime checks, alerting policies, etc.)..." - pushd monitoring/ - terraform init -lockfile=false - terraform apply --auto-approve -var="project_id=${project_id}" -var="project_number=${project_number}" -var="external_ip=${external_ip}" -var="project_owner_email=${acct}" -var="zone=${CLUSTER_ZONE}" -var="skip_ratingservice=${skip_ratingservice:-false}" - popd -} - -getExternalIp() { - external_ip=""; - while [ -z $external_ip ]; do - log "Waiting for Hipster Shop endpoint..."; - external_ip=$(kubectl -n asm-ingress get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}'); - [ -z "$external_ip" ] && sleep 10; - done; - if [[ $(curl -sL -w "%{http_code}" "http://$external_ip" -o /dev/null) -eq 200 ]]; then - log "Hipster Shop app is available at http://$external_ip" - sendTelemetry $project_id hipstershop-available - else - log "error: Hipsterhop app at http://$external_ip is unreachable" - sendTelemetry $project_id hipstershop-unavailable - fi -} - -# Start generating synthetic traffic to Sandbox for a few seconds then stop -# This produces initial interesting telemetry data for users to view -loadGen() { - log "Running load generator" - - # authenticate to load generator cluster - LOADGEN_ZONE=$(gcloud container clusters list --filter="name:loadgenerator" --project $project_id --format="value(zone)") - gcloud container clusters get-credentials loadgenerator --zone "$LOADGEN_ZONE" - kubectx loadgenerator=. - - # Kicks off initial load generation via a POST request to Locust web interface - # This is because Locust currently doesn't support CLI and UI at the same time - TRIES=0 - while [[ $(curl -XPOST -d "user_count=50&spawn_rate=10" http://$loadgen_ip/swarm -o /dev/null -w "%{http_code}" --max-time 1) -ne 200 && \ - "${TRIES}" -lt 20 ]]; do - log "waiting for load generator instance..." - sleep 10 - loadgen_ip=$(kubectl get service loadgenerator -o jsonpath='{.status.loadBalancer.ingress[0].ip}'); - [ -z "$loadgen_ip" ] && sleep 10; - TRIES=$((TRIES + 1)) - done - - # Lets load generator run for a few seconds - sleep 5 - - # Ends initial load generation - if [[ $(curl http://$loadgen_ip/stop -o /dev/null -w "%{http_code}") -ne 200 ]]; then - log "Failed to stop initial load generation" - fi - # Return kubectl context to the main cluster and show this to the user - kubectx main - log $(kubectx) -} - -displaySuccessMessage() { - gcp_path="https://console.cloud.google.com" - if [[ -n "${project_id}" ]]; then - gcp_kubernetes_path="$gcp_path/kubernetes/workload?project=$project_id" - gcp_monitoring_path="$gcp_path/monitoring?project=$project_id" - fi - - if [[ -n "${loadgen_ip}" ]]; then - loadgen_addr="http://$loadgen_ip" - sendTelemetry $project_id loadgen-available - else - loadgen_addr="[not found]" - sendTelemetry $project_id loadgen-unavailable - fi - log "" - log "" - log "********************************************************************************" - log "Cloud Operations Sandbox deployed successfully!" - log "" - log " Google Cloud Console GKE Dashboard: $gcp_kubernetes_path" - log " Google Cloud Console Monitoring Workspace: $gcp_monitoring_path" - log " Hipstershop web app address: http://$external_ip" - if [[ -z "${skip_loadgen}" ]]; then - log " Load generator web interface: $loadgen_addr" - fi - log "" - log "To remove the Sandbox once finished using it, run" - log "" - log " sandboxctl destroy" - log "" - log "********************************************************************************" -} - -checkAuthentication() { - TRIES=0 - AUTH_ACCT=$(gcloud auth list --format="value(account)") - if [[ -z $AUTH_ACCT ]]; then - log "Authentication failed" - log "Please allow gcloud and Cloud Shell to access your GCP account" - fi - while [[ -z $AUTH_ACCT && "${TRIES}" -lt 300 ]]; do - AUTH_ACCT=$(gcloud auth list --format="value(account)") - sleep 1; - TRIES=$((TRIES + 1)) - done - if [[ -z $AUTH_ACCT ]]; then - exit 1 - fi -} - -parseArguments() { - while (( "$#" )); do - case "$1" in - -p|--project|--project-id) - if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then - project_id=$2 - gcloud config set project "$project_id" - shift 2 - else - log "Error: Argument for $1 is missing" >&2 - exit 1 - fi - ;; - --skip-loadgenerator) - skip_loadgen=1 - shift - ;; - --skip-ratingservice) - skip_ratingservice=1 - shift - ;; - --service-wait) - service_wait=1 - shift - ;; - -v|--verbose) - set -x - shift - ;; - -h|--help) - log "Deploy Cloud Operations Sandbox to a GCP project" - log "" - log "options:" - log "-p|--project|--project-id GCP project to deploy Cloud Operations Sandbox to" - log "-v|--verbose print commands as they run (set -x)" - log "--skip-loadgenerator Don't deploy a loadgenerator instance" - log "--skip-ratingservice Don't deploy the ratingservice" - log "--service-wait Wait indefinitely for services to be detected by Cloud Monitoring" - log "" - exit 0 - ;; - -*|--*=) # unsupported flags - log "Error: Unsupported flag $1" >&2 - exit 1 - ;; - *) # ignore positional arguments - shift - ;; - esac - done -} - -# check for command line arguments -parseArguments $*; - -# ensure gcloud and cloudshell are authenticated -checkAuthentication; - -# prompt user for missing information -if [[ -z "$project_id" ]]; then - promptForBillingAccount; - promptForProject; -fi -getOrCreateBucket; - -# deploy -applyTerraform; -authenticateCluster; -# || true to prevent errors during monitoring setup from stopping the installation script -installMonitoring || true; -getExternalIp; -if [[ -z "${skip_loadgen}" ]]; then - loadGen; -fi -displaySuccessMessage; diff --git a/terraform/istio/install_asm.sh b/terraform/istio/install_asm.sh deleted file mode 100755 index 3d7d5f291..000000000 --- a/terraform/istio/install_asm.sh +++ /dev/null @@ -1,64 +0,0 @@ -# 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. -#!/bin/bash - -# Install Istio on the single cluster for Stackdriver Sandbox - -# Download Istio - -echo "### " -echo "### Begin install ASM control plane" -echo "### " - - -ASM_VERSION=1.12 -PROJECT_ID=$(gcloud config get-value project) -CLUSTER_ZONE=$(gcloud container clusters list --filter name=cloud-ops-sandbox --format="json" | jq -r '.[0].zone') - -# Set the working directory to our current directory (/sandbox/terraform/istio) -export SCRIPTPATH=$(dirname $(realpath $0)) -cd $SCRIPTPATH -export WORK_DIR=$SCRIPTPATH - -echo "Downloading asmcli ${ASM_VERSION}..." -curl https://storage.googleapis.com/csm-artifacts/asm/asmcli_${ASM_VERSION} > asmcli -chmod +x asmcli - -echo "Installing ASM..." -./asmcli install \ - --project_id $PROJECT_ID \ - --cluster_name cloud-ops-sandbox \ - --cluster_location $CLUSTER_ZONE \ - --fleet_id $PROJECT_ID \ - --output_dir $WORK_DIR/asm_output \ - --enable_all \ - --option prometheus-and-stackdriver \ - --option legacy-default-ingressgateway \ - --ca mesh_ca \ - --enable_gcp_components \ - --managed \ - --channel regular \ - --use_managed_cni - -echo "Setting up Ingress Gateway" -kubectl create ns asm-ingress -kubectl label namespace asm-ingress istio-injection=enabled --overwrite -kubectl apply -n asm-ingress -f $WORK_DIR/asm_output/samples/gateways/istio-ingressgateway - -echo "Enabling Sidecar Injection..." -kubectl label namespace default istio-injection=enabled --overwrite - -echo "Deploying Virtual Services..." -cd $WORK_DIR -kubectl apply -f ../../istio-manifests diff --git a/terraform/loadgen/00_loadgen.tf b/terraform/loadgen/00_loadgen.tf deleted file mode 100644 index 5c0323716..000000000 --- a/terraform/loadgen/00_loadgen.tf +++ /dev/null @@ -1,150 +0,0 @@ -# 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. - -# Let's create the GKE cluster! This one's pretty complicated so buckle up. - -# This is another example of the random provider. Here we're using it to pick a -# zone at random - all different regions from where we provisioned -# the Hipster Shop. -resource "random_shuffle" "zone" { - input = ["us-west1-a", "us-west1-b", "us-west1-c", "asia-east1-a", "europe-west2-a"] - - # Seeding the RNG is technically optional but while building this we - # found that it returned the same zone every time unless we seeded it. Here - # we're using the ID of the project as a seed because it is unique to the - # project but will not change, thereby guaranteeing stability of the results. - seed = var.project_id -} - -# First we create the cluster. If you're wondering where all the sizing details -# are, they're below in the `google_container_node_pool` resource. We'll get -# back to that in a minute. -# -# One thing to note here is the name of the resource ("gke") is only used -# internally, for instance when you're referencing the resource (eg -# `google_container_cluster.gke.id`). The actual created resource won't know -# about it, and in fact you can specify the name for that in the resource -# itself. -# -# Finally, there are many, many other options available. The resource below -# replicates what the Hipster Shop README creates. If you want to see what else -# is possible, check out the docs: https://www.terraform.io/docs/providers/google/r/container_cluster.html -resource "google_container_cluster" "gke_loadgen" { - # Here's how you specify the name of the cluster - name = "loadgenerator" - - project = var.project_id - - # Set the zone by grabbing the result of the random_shuffle above. It - # returns a list so we have to pull the first element off. If you're looking - # at this and thinking "huh terraform syntax looks a clunky" you are NOT WRONG - location = element(random_shuffle.zone.result, 0) - - # Using an embedded resource to define the node pool. Another - # option would be to create the node pool as a separate resource and link it - # to this cluster. There are tradeoffs to each approach. - # - # The embedded resource is convenient but if you change it you have to tear - # down the entire cluster and rebuild it. A separate resource could be - # modified independent of the cluster without the cluster needing to be torn - # down. - # - # For this particular case we're not going to be modifying the node pool once - # it's deployed, so it makes sense to accept the tradeoff for the convenience - # of having it inline. - # - # Many of the paramaters below are self-explanatory so I'll only call out - # interesting things. - node_pool { - node_config { - machine_type = "n1-standard-2" - - oauth_scopes = [ - "https://www.googleapis.com/auth/cloud-platform" - ] - - labels = { - environment = "dev", - cluster = "loadgenerator-main" - } - } - - initial_node_count = 1 - - autoscaling { - min_node_count = 1 - max_node_count = 10 - } - - management { - auto_repair = true - auto_upgrade = true - } - } - - # Stores the zone of created loadgenerator gke cluster - provisioner "local-exec" { - command = "gcloud config set compute/zone ${element(random_shuffle.zone.result, 0)}" - } -} - - -# Set current project -resource "null_resource" "current_project" { - provisioner "local-exec" { - command = "gcloud config set project ${var.project_id}" - } -} - -# Setting kubectl context to currently deployed loadgenerator GKE cluster -resource "null_resource" "set_gke_context" { - provisioner "local-exec" { - command = "gcloud container clusters get-credentials loadgenerator --zone ${element(random_shuffle.zone.result, 0)} --project ${var.project_id}" - } - - depends_on = [ - google_container_cluster.gke_loadgen, - null_resource.current_project - ] -} - -# Populate the ConfigMap with environment variables -resource "null_resource" "set_env_vars" { - provisioner "local-exec" { - command = "kubectl create configmap address-config --from-literal=FRONTEND_ADDR=http://${var.external_ip}" - } - depends_on = [null_resource.set_gke_context] -} - -# Deploy loadgenerator into GKE cluster -resource "null_resource" "deploy_services" { - provisioner "local-exec" { - command = "kubectl apply -f ${path.module}/../../loadgenerator-manifests/loadgenerator.yaml" - } - - depends_on = [ - null_resource.set_env_vars - ] -} - -# We wait for the load generator to become available on kubernetes -resource "null_resource" "delay" { - provisioner "local-exec" { - command = "kubectl wait --for=condition=available --timeout=600s deployment/loadgenerator" - } - - triggers = { - "before" = null_resource.deploy_services.id - } -} diff --git a/terraform/loadgen/variables.tf b/terraform/loadgen/variables.tf deleted file mode 100644 index 972fe93b5..000000000 --- a/terraform/loadgen/variables.tf +++ /dev/null @@ -1,28 +0,0 @@ -# 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. - -# Creating this variable but leaving it empty means that the user will be -# prompted for a value when terraform is run - -# Currently we need the user to provide some basic information to set up the monitoring examples -# These will be gone when we merge the monitoring terraform with the provisioning terraform -variable "external_ip" { - type = string - description = "The external IP of the frontend cluster. Can be revealed by running \"kubectl get service frontend-external'\" in the Google Cloud CLI." -} - -variable "project_id" { - type = string - description = "The project id that was created by Cloud Operations Sandbox. Can be revealed by running \"gcloud config get-value project\" in the Google Cloud CLI." -} diff --git a/terraform/monitoring/00_provider.tf b/terraform/monitoring/00_provider.tf deleted file mode 100644 index a0eb4e99f..000000000 --- a/terraform/monitoring/00_provider.tf +++ /dev/null @@ -1,37 +0,0 @@ -# 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. - -# the `provider` block contains the configuration for the provider, including -# credentials and region config. It can be configured via environment variables -# or via passing a path to a credentials JSON file. - -# In this demo we're using Application Default Creds instead, see this for -# details: https://cloud.google.com/docs/authentication/production -# -# TODO: we can consider configuring it via env vars -# that were populated appropriately at runtime. - -terraform { - required_version = "~> 1.0" - required_providers { - google = { - source = "hashicorp/google" - version = "~> 3.90.0" - } - } -} - -provider "google" { - project = var.project_id -} \ No newline at end of file diff --git a/terraform/monitoring/01_uptime_checks.tf b/terraform/monitoring/01_uptime_checks.tf deleted file mode 100644 index aed13b94b..000000000 --- a/terraform/monitoring/01_uptime_checks.tf +++ /dev/null @@ -1,75 +0,0 @@ -# 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. - -# Here we create a default HTTP Uptime Check on the External IP of our -# Kubernetes cluster revealed by the Load Balancer -# Our uptime check has a period of 1 minute and times out after 10 seconds -resource "google_monitoring_uptime_check_config" "http" { - display_name = "HTTP Uptime Check" - timeout = "10s" - period = "60s" - - http_check { - path = "/" - port = "80" - } - - monitored_resource { - type = "uptime_url" - labels = { - project_id = "${var.project_id}" - host = "${var.external_ip}" - } - } -} - -# Here we place an alerting policy on the HTTP Uptime Check that alerts based on -# failed uptime checks. The alerting policy will be triggered if any uptime check location -# fails more than 2 times over a 5 minute period. The metric is viewed over a 20 minute window. -# -# Our alerting policy notifies errors via email -resource "google_monitoring_alert_policy" "alert_policy" { - display_name = "HTTP Uptime Check Alerting Policy" - combiner = "OR" - conditions { - display_name = "HTTP Uptime Check Alert" - condition_threshold { - filter = "metric.type=\"monitoring.googleapis.com/uptime_check/check_passed\" AND metric.label.check_id=\"${google_monitoring_uptime_check_config.http.uptime_check_id}\" AND resource.type=\"uptime_url\"" - duration = "300s" - comparison = "COMPARISON_GT" - aggregations { - # the alignment sets the window over which the metric is viewed - alignment_period = "1200s" - per_series_aligner = "ALIGN_NEXT_OLDER" - cross_series_reducer = "REDUCE_COUNT_FALSE" - group_by_fields = ["resource.label.*"] - } - threshold_value = "2" - trigger { - count = "1" - } - } - } - notification_channels = ["${google_monitoring_notification_channel.basic.id}"] -} - -# Here we configure the email notification channel for the HTTP uptime check -# alerting policy. The email configured is the email of the owner of the project. -resource "google_monitoring_notification_channel" "basic" { - display_name = "Google Project Owner Account Email" - type = "email" - labels = { - email_address = "${var.project_owner_email}" - } -} diff --git a/terraform/monitoring/02_dashboards.tf b/terraform/monitoring/02_dashboards.tf deleted file mode 100644 index 81807bcca..000000000 --- a/terraform/monitoring/02_dashboards.tf +++ /dev/null @@ -1,112 +0,0 @@ -# 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. - -# Creates a dashboard for the general user experience - it contains metrics -# that reflect how users are interacting with the demo application such as latency -# of requests, distribution of types of requests, and response types. The JSON object -# containing the exact details of the dashboard can be found in the 'dashboards' folder. -resource "google_monitoring_dashboard" "userexp_dashboard" { - dashboard_json = file("./dashboards/userexp_dashboard.json") -} - -# Creates a dashboard for the frontend service. The details of the charts -# in the dashboard can be found in the JSON specification file. -resource "google_monitoring_dashboard" "frontend_dashboard" { - dashboard_json = file("./dashboards/frontend_dashboard.json") -} - -# Creates a dashboard for the adservice. The details of the charts -# in the dashboard can be found in the JSON specification file. -resource "google_monitoring_dashboard" "adservice_dashboard" { - dashboard_json = file("./dashboards/adservice_dashboard.json") -} - -# Creates a dashboard for the recommendationservice. The details of the charts -# in the dashboard can be found in the JSON specification file. -resource "google_monitoring_dashboard" "recommendationservice_dashboard" { - dashboard_json = file("./dashboards/recommendationservice_dashboard.json") -} - -# Creates a dashboard for the cartservice. -resource "google_monitoring_dashboard" "cartservice_dashboard" { - dashboard_json = file("./dashboards/cartservice_dashboard.json") -} - -# Creates a dashboard for the checkoutservice. -resource "google_monitoring_dashboard" "checkoutservice_dashboard" { - dashboard_json = file("./dashboards/checkoutservice_dashboard.json") -} - -# Creates a dashboard for the currencyservice. -resource "google_monitoring_dashboard" "currencyservice_dashboard" { - dashboard_json = file("./dashboards/currencyservice_dashboard.json") -} - -# Creates a dashboard for the productcatalogservice. -resource "google_monitoring_dashboard" "productcatalogservice_dashboard" { - dashboard_json = file("./dashboards/productcatalogservice_dashboard.json") -} - -# Creates a dashboard for the ratingservice. -resource "google_monitoring_dashboard" "ratingservice_dashboard" { - count = var.skip_ratingservice ? 0 : 1 - dashboard_json = file("./dashboards/ratingservice_dashboard.json") -} - -# Create generic dashboards for three of the microservices. Since all three microservices -# will share the same charts across their dashboards, we can leverage Terraform template files -# in order to reproduce identical dashboards for each microservice. - -# Define specifics for each of the services that will receive a generic dashboard. -# We need the service name for dashboard and chart titles, and we need the service ID to use as a metadata filter. -variable "services" { - type = list(object({ - service_name = string, - service_id = string - })) - default = [ - { - service_name = "Payment Service" - service_id = "paymentservice" - }, - { - service_name = "Email Service" - service_id = "emailservice" - }, - { - service_name = "Shipping Service" - service_id = "shippingservice" - } - ] -} - -# Iterate over the services that we defined and create a dashboard template file for each one using -# the template file defined in the 'dashboards' folder. -data "template_file" "dash_json" { - template = file("./dashboards/generic_dashboard.tmpl") - count = length(var.services) - vars = { - service_name = var.services[count.index].service_name - service_id = var.services[count.index].service_id - } -} - -# Create GCP Monitoring Dashboards using the rendered template files that were created in the data -# resource above. This produces one dashboard for each microservice that we defined above. -resource "google_monitoring_dashboard" "service_dashboards" { - count = length(var.services) - dashboard_json = <=\"500\""]) - ]) - } - } -} - -# Rating service latency SLO: -# 90% of requests that return in under 175 ms in the previous 30 days - -resource "google_monitoring_slo" "rating_service_latency_slo" { - # Uses ratingservice service that is automatically detected and created when the service is deployed to App Engine - # Identify of the service is built after the following template: gae:${project_id}_servicename - count = var.skip_ratingservice ? 0 : 1 - service = "gae:${var.project_id}_ratingservice" - slo_id = "ratingservice-latency-slo" - display_name = "Rating Service Latency SLO with request base SLI (distribution cut)" - - goal = 0.9 - rolling_period_days = 30 - - request_based_sli { - distribution_cut { - - # The distribution filter retrieves latencies of user requests that returned 200 OK responses - distribution_filter = join(" AND ", [ - "metric.type=\"appengine.googleapis.com/http/server/response_latencies\"", - "resource.type=\"gae_app\"", - "resource.label.\"version_id\"=\"prod\"", - "resource.label.\"module_id\"=\"ratingservice\"", - "metric.label.\"loading\"=\"false\"", - "metric.label.\"response_code\"=\"200\"", - ]) - - range { - # By not setting a min value, it is automatically set to -infinity - # The upper bound for latency is in ms - max = 1000 - } - } - } -} - -# Rating service's data freshness SLO: -# during a day 99.9% of minutes have at least 1 successful recollect API call -resource "google_monitoring_slo" "rating_service_freshness_slo" { - # Uses ratingservice service that is automatically detected and created when the service is deployed to App Engine - # Identify of the service is built after the following template: gae:${project_id}_servicename - count = var.skip_ratingservice ? 0 : 1 - service = "gae:${var.project_id}_ratingservice" - slo_id = "ratingservice-freshness-slo" - display_name = "Rating freshness SLO with window based SLI" - - goal = 0.9 - rolling_period_days = 1 - - windows_based_sli { - window_period = "60s" - metric_sum_in_range { - time_series = join(" AND ", [ - "metric.type=\"logging.googleapis.com/user/ratingservice_recollect_requests_count\"", - "resource.type=\"gae_app\"", - join(" OR ", ["metric.label.\"status\"<\"400\"", - "metric.label.\"status\"=\"429\""]) - ]) - range { - min = 1 - max = 9999 # the maximum can be any number of requests; the unreasonably high value is placed since inf is not supported - } - } - } - - depends_on = [google_logging_metric.ratingservice_logging_metric] -} diff --git a/terraform/monitoring/05_alerting_policies.tf b/terraform/monitoring/05_alerting_policies.tf deleted file mode 100644 index 44dbca1c6..000000000 --- a/terraform/monitoring/05_alerting_policies.tf +++ /dev/null @@ -1,59 +0,0 @@ -# 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. - -# Create an alerting policy on the Availability SLO for the Istio services. -# The definition of the SLO can be found in the file '04_slos.tf'. -# Alerts on error budget burn rate. -resource "google_monitoring_alert_policy" "istio_service_availability_slo_alert" { - count = length(var.istio_services) - display_name = "${var.istio_services[count.index].service_name} Availability Alert Policy" - combiner = "AND" - conditions { - display_name = "SLO burn rate alert for availability SLO with a threshold of ${var.istio_services[count.index].availability_burn_rate}" - condition_threshold { - - # This filter alerts on burn rate over the past 60 minutes - # The service is defined by the unique Istio string that is automatically created - filter = "select_slo_burn_rate(\"projects/${var.project_id}/services/canonical-ist:proj-${var.project_number}-default-${var.istio_services[count.index].service_id}/serviceLevelObjectives/${google_monitoring_slo.istio_service_availability_slo[count.index].slo_id}\", 60m)" - threshold_value = var.istio_services[count.index].availability_burn_rate - comparison = "COMPARISON_GT" - duration = "60s" - } - } - documentation { - content = "Availability SLO burn for the ${var.istio_services[count.index].service_name} for the past 60m exceeded ${var.istio_services[count.index].availability_burn_rate}x the acceptable budget burn rate. The service is returning less OK responses than desired. Consider viewing the service logs or custom dashboard to retrieve more information or adjust the values for the SLO and error budget." - mime_type = "text/markdown" - } -} - -# Create another alerting policy, this time on the SLO for latency for the Istio service. -# Alerts on error budget burn rate. -resource "google_monitoring_alert_policy" "istio_service_latency_slo_alert" { - count = length(var.istio_services) - display_name = "${var.istio_services[count.index].service_name} Latency Alert Policy" - combiner = "AND" - conditions { - display_name = "SLO burn rate alert for latency SLO with a threshold of ${var.istio_services[count.index].latency_burn_rate}" - condition_threshold { - filter = "select_slo_burn_rate(\"projects/${var.project_id}/services/canonical-ist:proj-${var.project_number}-default-${var.istio_services[count.index].service_id}/serviceLevelObjectives/${google_monitoring_slo.istio_service_latency_slo[count.index].slo_id}\", 60m)" - threshold_value = var.istio_services[count.index].availability_burn_rate - comparison = "COMPARISON_GT" - duration = "60s" - } - } - documentation { - content = "Latency SLO burn for the ${var.istio_services[count.index].service_name} for the past 60m exceeded ${var.istio_services[count.index].latency_burn_rate}x the acceptable budget burn rate. The service is responding slower than desired. Consider viewing the service logs or custom dashboard to retrieve more information or adjust the values for the SLO and error budget." - mime_type = "text/markdown" - } -} diff --git a/terraform/monitoring/06_log_based_metric.tf b/terraform/monitoring/06_log_based_metric.tf deleted file mode 100644 index 840d937bf..000000000 --- a/terraform/monitoring/06_log_based_metric.tf +++ /dev/null @@ -1,110 +0,0 @@ -# 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. - -# Creates a log-based metric by extracting a specific log written by the Checkout Service. -# The log being used for the metric is from the Checkout Service and has the format: -# orderedItem="Vintage Typewriter", id="OLJCESPC7Z" -# -# The label and Regex extractor are used to create filters on the metric -# This resource creates only the metric -resource "google_logging_metric" "checkoutservice_logging_metric" { - name = "checkoutservice_log_metric" - filter = "resource.type=k8s_container AND resource.labels.cluster_name=cloud-ops-sandbox AND resource.labels.namespace_name=default AND resource.labels.container_name=server AND orderedItem" - metric_descriptor { - metric_kind = "DELTA" # set to DELTA for counter-based metric - value_type = "INT64" # set to INT64 for counter-based metric - unit = "1" - labels { - key = "product_name" - description = "Filters by Product Name" - } - labels { - key = "product_id" - description = "Filters by Product Id" - } - display_name = "Ordered Products Metric" - } - label_extractors = { - # Regex extractor has matching group to match the product name or product id. Example: orderedItem="Terrarium", id="L9ECAV7KIM" - # matches Terrarium for product name and L9ECAV7KIM for product id. - "product_name" = "REGEXP_EXTRACT(jsonPayload.message, \"orderedItem=\\\\\\\"([^\\\"]+)\\\\\\\"\")" - "product_id" = "REGEXP_EXTRACT(jsonPayload.message, \"id=\\\\\\\"([^\\\"]+)\\\\\\\"\")" - } -} - -# Creates a dashboard and chart for the log-based metric defined above. -# Uses the label to group by the product name -resource "google_monitoring_dashboard" "log_based_metric_dashboard" { - dashboard_json = < **Note:** the contents of this directory are automatically installed when creating a Cloud Operations Sandbox - -This directory contains documented [Terraform] for provisioning monitoring examples -for the microservices contained in the demo application provisioned by Cloud Operations Sandbox. - -Please note that in order to provision these monitoring examples a [Monitoring Workspace] -must be associated with your project. - -> **Note:** the monitoring examples created in this directory are an opinionated example. It demonstrates best-practice methods for configuring monitoring for the demo application. - -[Terraform]: https://www.terraform.io/ -[Monitoring Workspace]: https://cloud.google.com/monitoring/workspaces/create - -## File Content Breakdown -### 01_uptime_checks.tf -1. [Uptime check] on the external IP address of the cluster. This default HTTP uptime check verifies that the root path of the application returns a 200 OK response every minute from 4 different regions with a 10 second timeout period. -2. [Alerting policy] on the status of the uptime check. The policy raises an alert and notifies the notification channel via email when the uptime check returns non-200 responses more than twice over a 5 minute window. -3. Notification channel which configures the account owner's email to be set to a notification channel for alerting policy violations. - -[![Uptime check](/docs/images/monitoring/uptime-check.png)](./docs/img/monitoring/uptime-check.png) - -[Uptime check]: https://cloud.google.com/monitoring/uptime-checks -[Alerting policy]: https://cloud.google.com/monitoring/alerts - -### 02_dashboards.tf -This file contains custom dashboards for each service as well as a User Experience Dashboard which represents metrics surrounding a user's interactions with the application. The four [golden signals of monitoring] are represented within each dashboard for each service. The metrics chosen utilize a combination of native Kubernetes metrics available through Cloud Monitoring, [Istio] metrics exposed through installation of Istio, and OpenCensus custom metrics. - -[![Dashboards list](/docs/images/monitoring/dashboards-list.png)](./docs/img/monitoring/dashboards-list.png) -[![Sample dashboard](/docs/images/monitoring/sample-dashboard.png)](./docs/img/monitoring/sample-dashboard.png) - -[golden signals of monitoring]: https://landing.google.com/sre/sre-book/chapters/monitoring-distributed-systems/#:~:text=The%20four%20golden%20signals%20of,system%2C%20focus%20on%20these%20four.&text=The%20time%20it%20takes%20to%20service%20a%20request -[Istio]: https://istio.io/ - -### 03_services.tf -This file contains the service specific details for the SLOs and Alerting Policies placed on each service. Each microservice in the demo application has monitoring created for it using either a Cloud Monitoring Custom Service or an Istio Service that is automatically created by Cloud Monitoring. Istio services are only available through the installation and usage of Istio service mesh. - -Each service has the following parameters that can be fine tuned: -1. availability_goal - the goal (as a decimal) for the availability SLO (defined as the percentage of successful requests). Ex. 0.9 = 90% of requests return as successful. -2. availability_burn_rate - the [error budget burn rate] threshold for the availability SLO. If the error budget burn rate exceeds this value, then the associated alerting policy raises an alert. -3. latency_goal - the goal (as a decimal) for the latency SLO (defined as the percentage of successful requests). Ex. 0.9 = 90% of requests return in under the latency threshold. -4. latency_threshold - the upper bound (in ms) for a request to return in to be considered successful. -5. latency_burn_rate - the [error budget burn rate] threshold for the latency SLO. If the error budget burn rate exceeds this value, then the associated alerting policy raises an alert. - -[![Services list](/docs/images/monitoring/services-list.png)](./docs/img/monitoring/services-list.png) - -[error budget burn rate]: https://cloud.google.com/stackdriver/docs/solutions/slo-monitoring/alerting-on-budget-burn-rate -### 04_slos.tf -This file contains the definitions of [Service Level Objectives] (SLOs) for each service (for both custom services and Istio services). -1. Availability SLO - this SLO is defined as the ratio of the number of successful requests (200 OK response code) to the number of total requests (non-4XX response code). The metric utilized is the Istio server request count metric which allows filtering by response code. The goal for the SLO is configured for each service in the 03_services.tf file. -2. Latency SLO - this SLO is defined as the ratio of the number of successful requests (200k OK response code) that return in under the latency threshold value to the number of total successful requests. The metric utilized is the Istio server response latencies. The goal and latency threshold for the SLO is configured for each service in the 03_services.tf file. - -[![SLO details](/docs/images/monitoring/slo-details.png)](./docs/img/monitoring/slo-details.png) - -[Service Level Objectives]: https://landing.google.com/sre/sre-book/chapters/service-level-objectives -### 05_alerting_policies.tf -This file contains the definitions of alerting policies for each SLO defined in 04_slos.tf. The alerting policies are fired when the error budget burn rate is exceeded. The burn rates are configured for each service in the file 03_services.tf. More on alerting on service level objectives can be found [here]. - -[here]: https://landing.google.com/sre/workbook/chapters/alerting-on-slos/ - -### 06_log_based_metric.tf -This file contains the specification of a metric using Cloud Logging's [log-based metric feature]. The metric is defined on a custom log being written to Cloud Logging by the Checkout Service. This log-based metric can then be used for a multitude of monitoring resources, and a custom dashboard is created using this metric in its chart. - -[![Log based metric](/docs/images/monitoring/log-based-metric.png)](./docs/img/monitoring/log-based-metric.png) - -[log-based metric feature]: https://cloud.google.com/logging/docs/logs-based-metrics \ No newline at end of file diff --git a/terraform/monitoring/dashboards/ratingservice_dashboard.json b/terraform/monitoring/dashboards/ratingservice_dashboard.json deleted file mode 100644 index 1e0c2cf4e..000000000 --- a/terraform/monitoring/dashboards/ratingservice_dashboard.json +++ /dev/null @@ -1,129 +0,0 @@ -{ - "displayName": "Rating Service Dashboard", - "gridLayout": { - "columns": 2, - "widgets": [ - { - "title": "Responses Count by Code", - "xyChart": { - "chartOptions": { - "mode": "COLOR" - }, - "dataSets": [ - { - "legendTemplate": "${metric.labels.response_code}", - "minAlignmentPeriod": "60s", - "plotType": "LINE", - "timeSeriesQuery": { - "timeSeriesFilter": { - "aggregation": { - "crossSeriesReducer": "REDUCE_SUM", - "groupByFields": [ - "metric.label.\"response_code\"" - ], - "perSeriesAligner": "ALIGN_SUM" - }, - "filter": "metric.type=\"appengine.googleapis.com/http/server/response_count\" resource.type=\"gae_app\" resource.label.\"version_id\"=\"prod\" resource.label.\"module_id\"=\"ratingservice\"" - } - } - } - ], - "yAxis": { - "label": "y1Axis", - "scale": "LINEAR" - } - } - }, - { - "title": "HTTP Response Latency", - "xyChart": { - "chartOptions": { - "mode": "COLOR" - }, - "dataSets": [ - { - "minAlignmentPeriod": "60s", - "plotType": "LINE", - "timeSeriesQuery": { - "timeSeriesFilter": { - "aggregation": { - "perSeriesAligner": "ALIGN_PERCENTILE_95" - }, - "filter": "metric.type=\"appengine.googleapis.com/http/server/response_latencies\" resource.type=\"gae_app\" resource.label.\"module_id\"=\"ratingservice\" resource.label.\"version_id\"=\"prod\"" - }, - "unitOverride": "1" - } - } - ], - "timeshiftDuration": "0s", - "yAxis": { - "label": "y1Axis", - "scale": "LINEAR" - } - } - }, - { - "title": "Instance Count by State", - "xyChart": { - "chartOptions": { - "mode": "COLOR" - }, - "dataSets": [ - { - "legendTemplate": "${metric.labels.state}", - "minAlignmentPeriod": "60s", - "plotType": "LINE", - "timeSeriesQuery": { - "timeSeriesFilter": { - "aggregation": { - "crossSeriesReducer": "REDUCE_MEAN", - "groupByFields": [ - "metric.label.\"state\"" - ], - "perSeriesAligner": "ALIGN_MEAN" - }, - "filter": "metric.type=\"appengine.googleapis.com/system/instance_count\" resource.type=\"gae_app\" resource.label.\"module_id\"=\"ratingservice\" resource.label.\"version_id\"=\"prod\"" - } - } - } - ], - "timeshiftDuration": "0s", - "yAxis": { - "label": "y1Axis", - "scale": "LINEAR" - } - } - }, - { - "title": "HTTP Denied From Over Quota", - "xyChart": { - "chartOptions": { - "mode": "COLOR" - }, - "dataSets": [ - { - "minAlignmentPeriod": "60s", - "plotType": "LINE", - "timeSeriesQuery": { - "timeSeriesFilter": { - "aggregation": { - "perSeriesAligner": "ALIGN_RATE" - }, - "filter": "metric.type=\"appengine.googleapis.com/http/server/quota_denial_count\" resource.type=\"gae_app\"", - "secondaryAggregation": { - "perSeriesAligner": "ALIGN_MAX" - } - } - } - } - ], - "timeshiftDuration": "0s", - "yAxis": { - "label": "y1Axis", - "scale": "LINEAR" - } - } - } - ] - } -} \ No newline at end of file diff --git a/terraform/monitoring/istio_service_setup.py b/terraform/monitoring/istio_service_setup.py deleted file mode 100644 index eac8dd0d9..000000000 --- a/terraform/monitoring/istio_service_setup.py +++ /dev/null @@ -1,79 +0,0 @@ -# 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. - -import os -import sys -import time -import concurrent.futures - -from google.cloud import monitoring_v3 - - -def getIstioServiceName(service_name, project_number): - """ Returns the Istio service name of a certain service. """ - return "canonical-ist:proj-{}-default-{}".format(project_number, service_name) - - -def findService(client, service_name, project_number, should_timeout): - """ Checks to see if a service exists in Cloud Monitoring - Arguments: - client - the API client - service_name - the Istio service name, returned from getIstioServiceName - project_number - the Sandbox project number - should_timeout - whether to timeout after 5 minutes or wait indefinitely for the service - """ - found_service = False - full_service_name = getIstioServiceName(service_name, project_number) - service = client.service_path(project_number, full_service_name) - num_tries = 0 - while not found_service and num_tries <= 50: - try: - found_service = client.get_service(name=service) - except: # possible exceptions include GoogleAPICallError and ValueError - if should_timeout: - num_tries += 1 - time.sleep(6) - found_service = False - - -def waitForIstioServicesDetection(project_number, should_timeout): - """ Waits for Istio services to be detected in Cloud Monitoring as a prerequisite for Terraform monitoring provisioning - Arguments: - project_number - the Sandbox project number - should_timeout - whether to timeout after 1 minute or wait indefinitely for the service - """ - client = monitoring_v3.ServiceMonitoringServiceClient() - - # wait for each Istio service to be detected by Cloud Monitoring - services = ["cartservice", "productcatalogservice", "currencyservice", "recommendationservice", - "adservice", "frontend", "checkoutservice", "paymentservice", "emailservice", "shippingservice"] - with concurrent.futures.ThreadPoolExecutor(max_workers=len(services)) as executor: - for service in services: - executor.submit(findService, client, service, project_number, should_timeout) - - -if __name__ == '__main__': - project_number = '' - zone = '' - try: - project_number = sys.argv[1] - except IndexError: - exit('Missing Project Number. Usage: python3 istio_service_setup.py $project_number') - - # optional parameter to determine whether we should timeout, default = True - if len(sys.argv) == 3: - should_timeout = False - else: - should_timeout = True - waitForIstioServicesDetection(project_number, should_timeout) diff --git a/terraform/monitoring/variables.tf b/terraform/monitoring/variables.tf deleted file mode 100644 index 328bcc1eb..000000000 --- a/terraform/monitoring/variables.tf +++ /dev/null @@ -1,48 +0,0 @@ -# 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. - -# Creating this variable but leaving it empty means that the user will be -# prompted for a value when terraform is run - -# Currently we need the user to provide some basic information to set up the monitoring examples -# These will be gone when we merge the monitoring terraform with the provisioning terraform -variable "external_ip" { - type = string - description = "The external IP of the kubernetes cluster. Can be revealed by running \"kubectl -n asm-ingress get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}'\" in the Google Cloud CLI." -} - -variable "project_id" { - type = string - description = "The project id that was created by Cloud Operations Sandbox. Can be revealed by running \"gcloud config get-value project\" in the Google Cloud CLI." -} - -variable "project_number" { - type = string - description = "The project Number associated with the project id." -} - -variable "project_owner_email" { - type = string - description = "The email to receive alerts caused by violations of alerting policies." -} - -variable "zone" { - type = string - description = "The Zone of the Cloud Operations Sandbox cluster." -} - -variable "skip_ratingservice" { - default = false - description = "If true, the ratingservice and associated resources will not be deployed." -} diff --git a/terraform/ratingservice/01_project.tf b/terraform/ratingservice/01_project.tf deleted file mode 100644 index 5507861c8..000000000 --- a/terraform/ratingservice/01_project.tf +++ /dev/null @@ -1,40 +0,0 @@ -/** - * 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 - * - * 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. - */ - -resource "google_project_service" "gae" { - service = "appengine.googleapis.com" - disable_dependent_services = true - project = var.gcp_project_id -} - -resource "google_project_service" "cloudscheduler" { - service = "cloudscheduler.googleapis.com" - disable_dependent_services = true - project = var.gcp_project_id -} - -resource "google_project_service" "cloudbuild" { - service = "cloudbuild.googleapis.com" - disable_dependent_services = true - project = var.gcp_project_id -} - -resource "google_project_service" "sqladmin" { - service = "sqladmin.googleapis.com" - disable_dependent_services = true - project = var.gcp_project_id -} - diff --git a/terraform/ratingservice/02_cloudsql.tf b/terraform/ratingservice/02_cloudsql.tf deleted file mode 100644 index 63ca8e048..000000000 --- a/terraform/ratingservice/02_cloudsql.tf +++ /dev/null @@ -1,61 +0,0 @@ -/** - * 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 - * - * 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. - */ - -resource "random_string" "suffix_len_4" { - upper = false - special = false - length = 4 -} - -# provision CloudSQL -resource "random_password" "db_password" { - length = 16 - special = false -} - -resource "google_sql_database_instance" "rating_service" { - project = var.gcp_project_id - name = "ratingservice-sql-instance-${random_string.suffix_len_4.result}" - database_version = "POSTGRES_12" - deletion_protection = false - region = var.gcp_region_name - settings { - tier = "db-f1-micro" - } -} - -resource "google_sql_user" "default" { - project = var.gcp_project_id - name = "postgres" - password = random_password.db_password.result - instance = google_sql_database_instance.rating_service.name -} - -resource "google_sql_database" "rating_service" { - project = var.gcp_project_id - name = "rating-db" - instance = google_sql_database_instance.rating_service.name - - provisioner "local-exec" { - command = "${path.module}/configure_rating_db.sh ${var.gcp_project_id}" - environment = { - DB_HOST = google_sql_database_instance.rating_service.connection_name - DB_NAME = google_sql_database.rating_service.name - DB_USERNAME = google_sql_user.default.name - DB_PASSWORD = google_sql_user.default.password - } - } -} diff --git a/terraform/ratingservice/03_bucket.tf b/terraform/ratingservice/03_bucket.tf deleted file mode 100644 index e84d15d49..000000000 --- a/terraform/ratingservice/03_bucket.tf +++ /dev/null @@ -1,44 +0,0 @@ -/** - * 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 - * - * 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. - */ - -locals { - source_path = "${path.root}/../src/ratingservice" -} - -resource "google_storage_bucket" "it" { - # max name length is 63 char = 30 chars for project id + '-ratingservice-' + 4 char suffix - name = "${var.gcp_project_id}-ratingservice-${random_string.suffix_len_4.result}" - uniform_bucket_level_access = true - project = var.gcp_project_id -} - -resource "google_storage_bucket_object" "requirements" { - name = "requirements.txt" - bucket = google_storage_bucket.it.name - source = "${local.source_path}/requirements.txt" -} - -resource "google_storage_bucket_object" "main" { - name = "ratingservice/main.py" - bucket = google_storage_bucket.it.name - source = "${local.source_path}/main.py" -} - -resource "google_storage_bucket_object" "default_main" { - name = "default/main.py" - bucket = google_storage_bucket.it.name - source = "${local.source_path}/pong.py" -} diff --git a/terraform/ratingservice/04_appengine.tf b/terraform/ratingservice/04_appengine.tf deleted file mode 100644 index 183894e46..000000000 --- a/terraform/ratingservice/04_appengine.tf +++ /dev/null @@ -1,134 +0,0 @@ -/** - * 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 - * - * 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. - */ - -# provision App Engine service -locals { - max_connections = 10 - service_port = 8080 -} - -data "external" "app_engine_state" { - program = ["${path.module}/setup_app_engine.sh", var.gcp_project_id] -} - -resource "google_app_engine_application" "app" { - project = var.gcp_project_id - count = data.external.app_engine_state.result.application_exist == "false" ? 1 : 0 - location_id = var.gcp_region_name - - depends_on = [google_project_service.gae, google_project_service.cloudbuild] -} - -resource "google_app_engine_standard_app_version" "default" { - count = data.external.app_engine_state.result.default_svc_exist == "false" ? 1 : 0 - project = var.gcp_project_id - service = "default" - version_id = "v1" - runtime = "python39" - - entrypoint { - shell = "uwsgi --http-socket :8080 --wsgi-file main.py --callable app --master --processes 1 --threads 1" - } - - deployment { - files { - name = "requirements.txt" - source_url = "https://storage.googleapis.com/${google_storage_bucket.it.name}/${google_storage_bucket_object.requirements.name}" - } - files { - name = "main.py" - source_url = "https://storage.googleapis.com/${google_storage_bucket.it.name}/${google_storage_bucket_object.default_main.name}" - } - } - - noop_on_destroy = true - depends_on = [ - google_project_service.gae, - google_project_service.cloudbuild, - google_storage_bucket_object.requirements, - google_storage_bucket_object.default_main, - google_storage_bucket_object.main, - google_app_engine_application.app, - ] -} - -data "google_app_engine_default_service_account" "default" { - project = var.gcp_project_id - depends_on = [google_app_engine_standard_app_version.default] -} - -resource "google_project_iam_binding" "sqlclientrole" { - project = var.gcp_project_id - role = "roles/cloudsql.client" - members = [ - "serviceAccount:${data.google_app_engine_default_service_account.default.email}" - ] - depends_on = [data.google_app_engine_default_service_account.default, google_project_service.sqladmin] -} - -resource "google_app_engine_standard_app_version" "ratingservice" { - project = var.gcp_project_id - service = var.service_name - version_id = var.service_version - runtime = "python38" - - entrypoint { - shell = "uwsgi --http-socket :${local.service_port} --wsgi-file main.py --callable app --master --processes 1 --threads ${local.max_connections}" - } - - deployment { - files { - name = "requirements.txt" - source_url = "https://storage.googleapis.com/${google_storage_bucket.it.name}/${google_storage_bucket_object.requirements.name}" - } - files { - name = "main.py" - source_url = "https://storage.googleapis.com/${google_storage_bucket.it.name}/${google_storage_bucket_object.main.name}" - } - } - - env_variables = { - DB_HOST = google_sql_database_instance.rating_service.connection_name - DB_NAME = google_sql_database.rating_service.name - DB_USERNAME = google_sql_user.default.name - DB_PASSWORD = google_sql_user.default.password - MAX_DB_CONNECTIONS = local.max_connections - PORT = local.service_port - } - - inbound_services = ["INBOUND_SERVICE_WARMUP"] - - automatic_scaling { - standard_scheduler_settings { - min_instances = 1 - } - max_concurrent_requests = 9 - min_idle_instances = 1 - max_idle_instances = 1 - } - - delete_service_on_destroy = true - depends_on = [google_app_engine_standard_app_version.default, google_project_iam_binding.sqlclientrole] -} - -# give the default appengine service account permissions to use clouddebugger - -resource "google_project_iam_member" "gae_editor_binding" { - project = var.gcp_project_id - role = "roles/editor" - member = "serviceAccount:${var.gcp_project_id}@appspot.gserviceaccount.com" - depends_on = [google_app_engine_standard_app_version.default] -} diff --git a/terraform/ratingservice/05_cloudscheduler.tf b/terraform/ratingservice/05_cloudscheduler.tf deleted file mode 100644 index ad4a37c11..000000000 --- a/terraform/ratingservice/05_cloudscheduler.tf +++ /dev/null @@ -1,45 +0,0 @@ -/** - * 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 - * - * 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. - */ - -resource "google_cloud_scheduler_job" "recollect_job" { - project = var.gcp_project_id - name = "ratingservice-recollect-job" - schedule = "* * * * *" # each minute - description = "recollect recently posted new votes" - time_zone = "Europe/London" - region = var.gcp_region_name - attempt_deadline = "340s" - - retry_config { - min_backoff_duration = "1s" - max_retry_duration = "10s" - max_doublings = 2 - retry_count = 3 - } - - app_engine_http_target { - http_method = "POST" - - app_engine_routing { - service = var.service_name - version = var.service_version - } - - relative_uri = "/ratings:recollect" - } - - depends_on = [google_project_service.cloudscheduler, google_app_engine_standard_app_version.ratingservice] -} diff --git a/terraform/ratingservice/99_outputs.tf b/terraform/ratingservice/99_outputs.tf deleted file mode 100644 index dd0b65e9e..000000000 --- a/terraform/ratingservice/99_outputs.tf +++ /dev/null @@ -1,19 +0,0 @@ -/** - * 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 - * - * 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. - */ - -output "service_url" { - value = "https://ratingservice-dot-${length(google_app_engine_application.app) > 0 ? google_app_engine_application.app[0].default_hostname : data.external.app_engine_state.result.application_domain}" -} diff --git a/terraform/ratingservice/README.md b/terraform/ratingservice/README.md deleted file mode 100644 index b9196e768..000000000 --- a/terraform/ratingservice/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# Rating Service terraform Module - -This folder includes files for provisioning a rating microservice on App Engine Standard Edition and CloudSQL Postgres database. -The provisioning is invoked from the `/terraform/03_ratingservice.tf` as part of the Hipster Shop application setup. -Rating service provisions Cloud SQL Instance with a "rating-db" database to be used with the rating microservice that is deployed to App Engine. -The App Engine application in the provided GCP project is created only if there is none. -The App Engine application requires having a service with the name "default" in order to be able to deploy any other service. -The module deploys "default" App Engine service if such service does not exist. For this matter a simple Python application that returns "pong" on GET / request is deployed. See [/src/ratingservice/README.md](GoogleCloudPlatform/cloud-ops-sandbox/blob/main/src/ratingservice/README.md) for more details. -Since terraform does not provide means for discovering App Engine Application or its services, the "external" data provider is used to execute "setup_app_engine.sh". See its description below. -In addition, a Cloud Scheduler job is configured to call the rating microservice `/ratings:recollect` endpoint each 2 minutes. The endpoint represents a custom "recollect" method following the Google Custom Methods [guidelines](https://cloud.google.com/apis/design/custom_methods). It is done to follow the rating service TDD which requires recollection of the recently posted new votes in order to provide the up to date average rate values. - -## File content breakdown - -The files in the folder include bash scripts (*.sh), terraform (*.tf) and templates (*.tpl). - -### Terraform files - -| Filename | Description | -|---|---| -| main.tf | Describes all resources relevant to the rating service. | -| variables.tf | Describes module input variables. | -| output.tf | Describes rating service URL output variable. | - -The module provision additional Google APIs that in use by the rating service: `sql-component.googleapis.com` and `sqladmin.googleapis.com` to provision and configure the Postgres DB and `cloudscheduler.googleapis.com` to provision Cloud Scheduler task. - -### Bash scripts - -| Filename | Description | -|---|---| -| configure_rating_db.sh | Creates a DB schema in the Postgres DB and populates the DB with random generated data. In order to perform these operations from the local host, it temporarly adds the public IP of the host to the list of allowed IP of the CloudSQL instance. | -| setup_app_engine.sh | Retrieves configuration of the App Engine application of the Google Cloud project. It is used to optimize provisioning of the App Engine application and its default service in the `main.tf`. | - -Each script accepts a single parameter which is the Google Cloud project id. See the scripts for additional documentation. - -### Deploy rating service without terraform - -The terraform module uses Google provider to deploy the rating service to the App Engine application. Another method would be using Cloud SDK e.g. `gcloud app deploy`. -For this a manifest file `app.yaml` has to be generated and then deployed with the service [source files](https://github.com/GoogleCloudPlatform/cloud-ops-sandbox/tree/main/src/ratingservice). -The app.yaml.tpl can be used to generate the file. diff --git a/terraform/ratingservice/app.yaml.tpl b/terraform/ratingservice/app.yaml.tpl deleted file mode 100644 index b87b1fc79..000000000 --- a/terraform/ratingservice/app.yaml.tpl +++ /dev/null @@ -1,15 +0,0 @@ -runtime: python38 -env: standard -service: ${service_name} -entrypoint: uwsgi --http-socket :8080 --wsgi-file main.py --callable app --master --processes 1 --threads ${max_connections} -env_variables: - DB_HOST: '${db_host}' - DB_NAME: '${db_name}' - DB_USERNAME: '${db_username}' - DB_PASSWORD: '${db_password}' - MAX_DB_CONNECTIONS: ${max_connections} -inbound_services: -- warmup -auto_scaling: - min_instances: 1 - max_concurrent_requests: 9 \ No newline at end of file diff --git a/terraform/ratingservice/configure_rating_db.sh b/terraform/ratingservice/configure_rating_db.sh deleted file mode 100755 index 5bec73b88..000000000 --- a/terraform/ratingservice/configure_rating_db.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/bin/bash -# -# 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 -# -# 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. - -#-------------------------------------------------------------------------- -# Environment variables: -# DB_HOST - Cloud SQL instance connection name -# DB_NAME - Postgres DB name -# DB_USERNAME - DB user name -# DB_PASSWORD - DB user password -#-------------------------------------------------------------------------- - -project_id=$1 -# -# open SQL proxy session to connect to CloudSQL instance -# -echo "Launching Cloud SQL Proxy in background..." -cloud_sql_proxy -instances=$DB_HOST=tcp:5432 -verbose=false &>/dev/null & -cloud_proxy_pid=$! - -# wait until proxy connects or 5 attempts fail -tries=0 -while [[ "${tries}" -lt 5 ]]; do - echo "Waiting for establishing connection to db..." - status_str=$(PGPASSWORD=$DB_PASSWORD psql "host=127.0.0.1 sslmode=disable dbname=$DB_NAME user=$DB_USERNAME" -q -c '\conninfo' 2>/dev/null) - if [[ -n "$status_str" ]]; then - echo "Connection established" - break - else - sleep 2 - tries=$((tries + 1)) - fi -done - -# -# configure db schema and populate rating entities -# -echo "Creating table [ratings]..." -PGPASSWORD=$DB_PASSWORD psql "host=127.0.0.1 sslmode=disable dbname=$DB_NAME user=$DB_USERNAME" <> generated_data.csv -jq -r '.products[].id' ../src/productcatalogservice/products.json | while read line ; do echo "$line,$(( $RANDOM % 5 + 1)),1" >> generated_data.csv; done -echo "Populating ratings to DB..." -cat generated_data.csv | PGPASSWORD=$DB_PASSWORD psql "host=127.0.0.1 sslmode=disable dbname=$DB_NAME user=$DB_USERNAME" -c "COPY ratings FROM STDIN DELIMITER ',' CSV HEADER;" -rm generated_data.csv - -# -# close SQL proxy session -# -kill $cloud_proxy_pid; wait $cloud_proxy_pid 2>/dev/null -echo "Cloud SQL Proxy background process is killed." diff --git a/terraform/ratingservice/setup_app_engine.sh b/terraform/ratingservice/setup_app_engine.sh deleted file mode 100755 index abc0f359c..000000000 --- a/terraform/ratingservice/setup_app_engine.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash -# -# 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 -# -# 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. - -# -# Print the following Json to STDOUT: -# { -# "application_exist": , // "true" or "false" showing whether App Engine application was already created -# "application_domain": , // describes application hostname if application_exist==true -# "default_svc_exist": // "true" or "false" showing whether App Engine has default service -# } -# -# NOTE: Json has string values because Terraform data "external" does not know to parse non-string values - -project_id=$1 - -ae_domain=$(gcloud app describe --project=$project_id --format="value(defaultHostname)" 2>/dev/null) -service_list=$(gcloud app services list --project=$project_id --filter="SERVICE=default" --format="value(SERVICE)" 2>/dev/null) - -if [[ -n "$ae_domain" ]]; then - default_service=false - [[ -n "$service_list" ]] && default_service=true - echo "{ \"application_exist\": \"true\", \"default_svc_exist\": \"$default_service\", \"application_domain\": \"$ae_domain\" }" | jq . -else - echo "{ \"application_exist\": \"false\", \"default_svc_exist\": \"false\" }" | jq . -fi - - diff --git a/terraform/ratingservice/variables.tf b/terraform/ratingservice/variables.tf deleted file mode 100644 index ec5c56d5a..000000000 --- a/terraform/ratingservice/variables.tf +++ /dev/null @@ -1,36 +0,0 @@ -/** - * 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 - * - * 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. - */ - -variable "gcp_project_id" { - type = string - description = "GCP project id where rating service should be provisioned." -} - -variable "gcp_region_name" { - type = string - default = "us-east1" - description = "GCP region name where CloudSQL instance and App Engine application should be deployed." -} -variable "service_name" { - type = string - default = "ratingservice" - description = "App Engine service name" -} -variable "service_version" { - type = string - default = "prod" - description = "App Engine service version" -} diff --git a/terraform/telemetry.py b/terraform/telemetry.py deleted file mode 100644 index 81a1c9fcb..000000000 --- a/terraform/telemetry.py +++ /dev/null @@ -1,100 +0,0 @@ -# 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. - -# File usage: -# python3 telemetry.py --session=$SESSION --project_id=$PROJECT_ID --event=$EVENT --version=$VERSION - -import sys -import json -import hashlib -import click -import time -import re - -from google.cloud import pubsub_v1 - -# This function hashes the project_id in order to preserve user privacy -# The telemetry system should not have access to the user's actual project_id -def obfuscate_project_id(project_id): - m = hashlib.sha256() - m.update(project_id.encode('utf-8')) - hashed = m.hexdigest() - return hashed - -# formats JSON object and re-forms project argument -def get_telemetry_msg(session, project_id, event, version): - datetime=time.time() # Unix timestamp - project=obfuscate_project_id(project_id) - - # send in json format - data = { - "session": session, - "project": project, - "event": event, - "datetime": datetime, - "version": version - } - msg = json.dumps(data) - return msg - -# returns True if arguments are valid (correct format and type) -# returns False along with an error message if not -def validate_args(session, project_id, event, version): - args_exp = { - "version": r"^(v\d.\d.\d|develop)$", - "project_id": r"^cloud-ops-sandbox-(\d){6,12}$", - "v4uuid": r"^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}$" - } - - # check types - if (not isinstance(event, str) or not isinstance(version, str) or - not isinstance(project_id, str) or not isinstance(session, str)): - return False, "An argument passed to telemetry was an invalid type." - - # check format - if (re.fullmatch(args_exp["version"], version) is None): return False, ("Version argument " + version + " was an invalid format.") - if (re.fullmatch(args_exp["project_id"], project_id) is None): return False, ("Project id argument " + project_id + " was an invalid format.") - if (re.fullmatch(args_exp["v4uuid"], session) is None): return False, ("Session argument " + session + " was an invalid format.") - - return True, "" - -# IF TESTING THIS FUNCTION, USE TOPIC ID = "telemetry" -# IF USING THIS FUNCTION IN PRODUCTION, USE TOPIC ID = "telemetry_prod" -@click.command() -@click.option('--session', help='Current session (unique across projects).') -@click.option('--project_id', help='Sandbox project id in Google Cloud Platform.') -@click.option('--event', help='The event that occurred.') -@click.option('--version', help='Release version of Sandbox.') -def send_telemetry_message(session, project_id, event, version): - # validate data - valid, err_msg = validate_args(session, project_id, event, version) - if (not valid): - print("Failed to send telemetry.") - print(err_msg) - return - - # send data as a bytestring - msg = get_telemetry_msg(session, project_id, event, version) - bytes = msg.encode("utf-8") - - # connect to pubsub and send message - project_id = "stackdriver-sandbox-230822" - topic_id = "telemetry_prod" - publisher = pubsub_v1.PublisherClient() - topic_path = publisher.topic_path(project_id, topic_id) - - publisher.publish(topic_path, data=bytes) - -if __name__ == "__main__": - send_telemetry_message() diff --git a/terraform/variables.tf b/terraform/variables.tf deleted file mode 100644 index 9a478e113..000000000 --- a/terraform/variables.tf +++ /dev/null @@ -1,69 +0,0 @@ -/** - * 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. - */ - -# Creating this variable but leaving it empty means that the user will be -# prompted for a value when terraform is run -variable "billing_account" { - default = null - type = string - description = "The name of your billing account. Case-sensitive." -} - -variable "project_id" { - type = string - description = "The id of your project. Case-sensitive." -} - -variable "bucket_name" { - type = string - description = "The name of your bucket to store the state file. Case-sensitive." -} - -#AppEngine -variable "appengine_region" { - default = "us-east1" - description = "App Engine defult GCP region." -} - -variable "app_version" { - default = 0 - type = string - description = "Cloud Operations Sandbox's Version. If wasn't set will be 0." -} - -#GKE Services Cluster -variable "gke_cluster_name" { - default = "cloud-ops-sandbox" - description = "GKE GKE Hipster shop cluster name." -} - -variable "gke_location" { - default = "" - type = string - description = "GKE Cloud Operations Sandbox's Cluster location." - -} - -variable "skip_ratingservice" { - default = false - description = "If true, the ratingservice and associated resources will not be deployed." -} - -#Loadgen -variable "skip_loadgen" { - default = false - description = "If true, the load generator will not be deployed." -} diff --git a/tests/README.md b/tests/README.md deleted file mode 100644 index 961e3911e..000000000 --- a/tests/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Tests for the Stackdriver Sandbox - -## This directory is currently under construction - -To run the integration test for monitoring examples, please ensure that you have already created the monitoring examples via running a `terraform apply` command in the `terraform/monitoring` directory. - -1. In order to run the tests first install all necessary components for python 3 -```bash -pip3 install -r requirements.txt -``` - -2. Run the tests -```bash -python3 monitoring_integration_test.py -``` \ No newline at end of file diff --git a/tests/cartservice/.gitignore b/tests/cartservice/.gitignore deleted file mode 100644 index 61aadf7b7..000000000 --- a/tests/cartservice/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/bin/* -/obj/* -/.vs/* \ No newline at end of file diff --git a/tests/cartservice/CartServiceTests.cs b/tests/cartservice/CartServiceTests.cs deleted file mode 100644 index 555719395..000000000 --- a/tests/cartservice/CartServiceTests.cs +++ /dev/null @@ -1,142 +0,0 @@ -// 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.Core; -using Hipstershop; -using Xunit; -using Grpc.Net.Client; -using static Hipstershop.CartService; - -namespace cartservice -{ - public class E2ETests - { - private static string serverHostName = "localhost"; - private static int port = 7070; - - private static string TargetUrl; - - static E2ETests() - { - // This switch must be set before creating the GrpcChannel/HttpClient. - AppContext.SetSwitch( - "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); - AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2Support", true); - - TargetUrl = $"http://{serverHostName}:{port}"; - } - - [Fact] - public async Task GetItem_NoAddItemBefore_EmptyCartReturned() - { - string userId = Guid.NewGuid().ToString(); - - // Create a GRPC communication channel between the client and the server - using (var channel = GrpcChannel.ForAddress(TargetUrl)) - { - var client = new CartServiceClient(channel); - - var request = new GetCartRequest - { - UserId = userId, - }; - var cart = await client.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() - { - string userId = Guid.NewGuid().ToString(); - - // Create a GRPC communication channel between the client and the server - using (var channel = GrpcChannel.ForAddress(TargetUrl)) - { - 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() - { - string userId = Guid.NewGuid().ToString(); - - // Create a GRPC communication channel between the client and the server - using (var channel = GrpcChannel.ForAddress(TargetUrl)) - { - // 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); - } - } - } -} diff --git a/tests/cartservice/Protos/Cart.proto b/tests/cartservice/Protos/Cart.proto deleted file mode 100644 index 116d1719a..000000000 --- a/tests/cartservice/Protos/Cart.proto +++ /dev/null @@ -1,51 +0,0 @@ -// 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 {} - diff --git a/tests/cartservice/cartservice.tests.csproj b/tests/cartservice/cartservice.tests.csproj deleted file mode 100644 index 1fd17a76b..000000000 --- a/tests/cartservice/cartservice.tests.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - net5.0 - false - - - - - - - - - - - - - - - - - - Always - - - - diff --git a/tests/cartservice/run-tests.sh b/tests/cartservice/run-tests.sh deleted file mode 100755 index 8ea0edfc8..000000000 --- a/tests/cartservice/run-tests.sh +++ /dev/null @@ -1,17 +0,0 @@ -# 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. -set -eu -o pipefail - -dotnet restore -dotnet test \ No newline at end of file diff --git a/tests/cartservice/tests.yaml b/tests/cartservice/tests.yaml deleted file mode 100644 index 2e7a498b8..000000000 --- a/tests/cartservice/tests.yaml +++ /dev/null @@ -1,26 +0,0 @@ -# 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. -# -# test by running -# docker-compose -f tests.yaml run --rm unittests -# -version: '3' -services: - unittests: - image: mcr.microsoft.com/dotnet/core/sdk:3.1.300-alpine - volumes: - - .:/code - command: - - /bin/bash - - /run-tests.sh \ No newline at end of file diff --git a/tests/monitoring_integration_test.py b/tests/monitoring_integration_test.py deleted file mode 100644 index 12a4b98f0..000000000 --- a/tests/monitoring_integration_test.py +++ /dev/null @@ -1,377 +0,0 @@ -# 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 __future__ import print_function - -import argparse -import os -import pprint -import unittest -import tabulate -import subprocess -import sys -import json -import time - -from collections import namedtuple - -from google.cloud import monitoring_v3 -from google.cloud import logging_v2 -from google.cloud.monitoring_dashboard import v1 -from googleapiclient import discovery -from oauth2client.client import GoogleCredentials - -project_name = 'projects/' -project_id = '' -zone = '-' - -def getProjectId(): - """Retrieves the project id from the script arguments. - Returns: - str -- the project name - Exits when project id is not set - """ - try: - project_id = sys.argv[1] - except: - exit('Missing Project ID. Usage: python3 monitoring_integration_test.py $PROJECT_ID $PROJECT_NUMBER') - - return project_id - -def getProjectNumber(): - """Retrieves the project number from the script arguments. - Returns: - str -- the project number - Exits when project number is not set - """ - try: - project_num = sys.argv[2] - except: - exit('Missing Project Number. Usage: python3 monitoring_integration_test.py $PROJECT_ID $PROJECT_NUMBER') - - return project_num - -ServiceName = namedtuple("ServiceName", "short long") -_services = [ - ServiceName(short='adservice', long='Ad Service'), - ServiceName(short='cartservice', long='Cart Service'), - ServiceName(short='checkoutservice', long='Checkout Service'), - ServiceName(short='currencyservice', long='Currency Service'), - ServiceName(short='emailservice', long='Email Service'), - ServiceName(short='frontend', long='Frontend Service'), - ServiceName(short='paymentservice', long='Payment Service'), - ServiceName(short='productcatalogservice', long='Product Catalog Service'), - ServiceName(short='recommendationservice', long='Recommendation Service'), - ServiceName(short='shippingservice', long='Shipping Service'), -] - - -class TestUptimeCheck(unittest.TestCase): - - external_ip = '' - - @classmethod - def setUpClass(cls): - """ Retrieve the external IP of the cluster """ - with open('out.txt', 'w+') as fout: - out = subprocess.run(["kubectl", "-n", "asm-ingress", "get", "service", "istio-ingressgateway", - "-o", "jsonpath='{.status.loadBalancer.ingress[0].ip}'"], stdout=fout) - fout.seek(0) - cls.external_ip = fout.read().replace('\'', '') - - def testNumberOfUptimeChecks(self): - """" Test that ensures there is an uptime check created """ - client = monitoring_v3.UptimeCheckServiceClient() - configs = client.list_uptime_check_configs(project_name) - config_list = [] - for config in configs: - config_list.append(config) - - self.assertTrue(len(config_list) >= 1) - - def testUptimeCheckName(self): - """ Verifies the configured IP address of the uptime check matches the external IP - address of the cluster """ - client = monitoring_v3.UptimeCheckServiceClient() - configs = client.list_uptime_check_configs(project_name) - config_list = [] - for config in configs: - config_list.append(config) - - config = config_list[0] - self.assertEqual( - config.monitored_resource.labels["host"], self.external_ip) - - def testUptimeCheckAlertingPolicy(self): - """ Test that an alerting policy was created. """ - client = monitoring_v3.AlertPolicyServiceClient() - policies = client.list_alert_policies(project_name) - found_uptime_alert = False - for policy in policies: - if policy.display_name == 'HTTP Uptime Check Alerting Policy': - found_uptime_alert = True - - self.assertTrue(found_uptime_alert) - - def testUptimeCheckAlertingPolicyNotificationChannel(self): - """ Test that a notification channel was created. """ - client = monitoring_v3.NotificationChannelServiceClient() - channels = client.list_notification_channels(project_name) - channel_list = [] - for channel in channels: - channel_list.append(channel) - - self.assertTrue(len(channel_list) >= 1) - - -class TestMonitoringDashboard(unittest.TestCase): - """ - Ensure Dashboards are set up for all Hipstershop Services, - Plust a User Experience Dashboard and a Log Based Metric Dashboard - """ - - def testDashboardsExist(self): - """ - Test to ensure dashboards were set up - """ - expected_dashboards = [f"{service.long} Dashboard" for service in _services] - expected_dashboards += ['User Experience Dashboard'] - - client = v1.DashboardsServiceClient() - found_dashboards = client.list_dashboards(project_name) - found_dashboard_names = [dash.display_name for dash in found_dashboards] - for expected_dash in expected_dashboards: - self.assertIn(expected_dash, found_dashboard_names, f"{expected_dash} not found") - print(f"✅ {expected_dash} created") - -class TestLogBasedMetric(unittest.TestCase): - - def testCheckoutServiceLogMetric(self): - """ Test that the log based metric for the Checkout Service gets created. """ - client = logging_v2.Client() - metric = client.metric("checkoutservice_log_metric") - self.assertTrue(metric.exists()) - -class TestServiceSlo(unittest.TestCase): - """ - Check to make sure Istio services and SLOs are created properly - """ - def setUp(self): - self.client = monitoring_v3.ServiceMonitoringServiceClient() - self.project_id = getProjectId() - - def getIstioService(self, service_name): - project_num = getProjectNumber() - return 'canonical-ist:proj-' + project_num + '-default-' + service_name - - def _get_metric_data(self, filter_, aggregation, period_seconds=1200): - """ - Helper function to query metric data for a service - - Args: - service_name (str): the name of the service to query - period_seconds: the number of seconds back to read metrics for - Returns: - a list of results from the API - """ - client = monitoring_v3.MetricServiceClient() - now = time.time() - now_seconds = int(now) - now_nanos = int((now - now_seconds) * 10 ** 9) - interval = { - "end_time": {"seconds": now_seconds, "nanos": now_nanos}, - "start_time": {"seconds": (now_seconds - period_seconds), "nanos": now_nanos}, - } - results = client.list_time_series( - name=project_name, - filter_=filter_, - interval=interval, - view=monitoring_v3.types.ListTimeSeriesRequest.TimeSeriesView.FULL, - aggregation=aggregation, - ) - return results - - def get_service_availability(self, service_name, period_seconds=120): - """ - Calculates the availability ratio for a service - - Args: - service_name (str): the name of the service to query - period_seconds: the number of seconds back to read metrics for - Returns: - the availability % as a float - """ - filter_ = f'metric.type = "istio.io/service/server/request_count" AND resource.labels.canonical_service_name = "{service_name}"' - aggregation = { - "alignment_period": {"seconds": period_seconds}, - "per_series_aligner": monitoring_v3.types.Aggregation.Aligner.ALIGN_MEAN, - "cross_series_reducer": monitoring_v3.types.Aggregation.Reducer.REDUCE_MEAN, - "group_by_fields": ["metric.labels.response_code"], - } - results = self._get_metric_data(filter_, aggregation, period_seconds) - # count up the percentage of successful calls - # 200s are successes, 500s are errors. 300-400s are excluded, as they are caused by client-side errors - success_total, fail_total = 0, 0 - for response in results: - # throws IndexError if data not found - status_code = int(response.metric.labels['response_code']) - request_count = response.points[0].value.double_value - if status_code < 300: - success_total += request_count - elif status_code >= 500: - fail_total += request_count - # throws zero division error if request data is zero - ratio = success_total/(fail_total+success_total) - return ratio - - def get_service_latency(self, service_name, period_seconds=120): - """ - Calculates the latency data for a service - - Args: - service_name (str): the name of the service to query - period_seconds (int): the number of seconds back to read metrics for - Returns: - the calculated average latency of the service in miliseconds as a float - """ - filter_ = f'metric.type = "istio.io/service/server/response_latencies" AND resource.labels.canonical_service_name = "{service_name}"' - aggregation = { - "alignment_period": {"seconds": period_seconds}, - "per_series_aligner": monitoring_v3.types.Aggregation.Aligner.ALIGN_DELTA, - "cross_series_reducer": monitoring_v3.types.Aggregation.Reducer.REDUCE_MEAN, - } - results = self._get_metric_data(filter_, aggregation, period_seconds) - results = list(results) - # throws IndexError if data not found - latency = results[0].points[0].value.double_value - return latency - - def _get_slo(self, slo_id, service_name): - """ - Finds and returns a SLO object with the specified id, and service name - - Args: - slo_id (str): the name of the SLO to query - service_name (str): the name of the related service - Returns: - SLO object - """ - istio_service_name = self.getIstioService(service_name) - slo_name_full = self.client.service_level_objective_path( - self.project_id, istio_service_name, slo_id) - slo = self.client.get_service_level_objective(slo_name_full) - return slo - - def test_services_created(self): - """ - Ensure that hipstersop Istio services have been picked up by Cloud Monitoring - """ - services = [service.short for service in _services] - for service_name in services: - istio_service_name = self.getIstioService(service_name) - full_name = self.client.service_path(self.project_id, istio_service_name) - result = self.client.get_service(full_name) - self.assertEqual(result.display_name, service_name, f"{service_name} not found") - print(f"✅ {service_name} canonical service created") - - def test_slos_created(self): - """ - Ensure that SLOs have been added to Istio services - """ - services = [service.short for service in _services] - for service_name in services: - istio_service_name = self.getIstioService(service_name) - for slo_type in ['latency', 'availability']: - slo_id = f"{service_name}-{slo_type}-slo" - slo_name_full = self.client.service_level_objective_path( - self.project_id, istio_service_name, slo_id) - result = self.client.get_service_level_objective(slo_name_full) - self.assertIsNotNone(result, f"{service_name} {slo_type} SLO not found") - print(f"✅ {service_name} {slo_type} SLO created") - - # SLO tests aren't reliable enough to run on CI tests, but can be useful for manual testing - @unittest.skip("unreliable for CI") - def test_availability_slos_passing(self): - """ - Ensure that availability is at expected levels to pass the SLO - """ - services = [service.short for service in _services] - for service_name in services: - # get SLO - slo_id = f"{service_name}-availability-slo" - slo = self._get_slo(slo_id, service_name) - # get metric data - availability = self.get_service_availability(service_name) - self.assertIsNotNone(availability, f"{service_name} availability data not found") - SLO_status_text = f"({int(availability * 100)}% availibility, SLO={int(slo.goal * 100)}%)" - self.assertGreater(availability, slo.goal, f"{service_name} failed availability SLO {SLO_status_text}") - print(f"✅ {service_name} Availability SLO passed: {SLO_status_text}") - - # SLO tests aren't reliable enough to run on CI tests, but can be useful for manual testing - @unittest.skip("unreliable for CI") - def test_latency_slos_passing(self): - """ - Ensure that service latency is at expected levels to pass the SLO - """ - services = [service.short for service in _services] - for service_name in services: - # get SLO - slo_id = f"{service_name}-latency-slo" - slo = self._get_slo(slo_id, service_name) - max_latency = slo.service_level_indicator.request_based.distribution_cut.range.max - # get metric data - latency = self.get_service_latency(service_name) - self.assertIsNotNone(latency, f"{service_name} latency data not found") - SLO_status_text = f"({latency:.2f}ms latency, SLO={max_latency:.2f}ms)" - self.assertLess(latency, max_latency, f"{service_name} failed latency SLO {SLO_status_text}") - print(f"✅ {service_name} Latency SLO passed: {SLO_status_text}") - -class TestSloAlertPolicy(unittest.TestCase): - """ - Ensure SLO Alert Policies are set up for each Hipstershop service - """ - def setUp(self): - self.client = monitoring_v3.AlertPolicyServiceClient() - - def testAlertsExist(self): - found_policies = self.client.list_alert_policies(project_name) - found_policy_names = [policy.display_name for policy in found_policies] - services = [service.long for service in _services] - for service_name in services: - latency_alert_name = f"{service_name} Latency Alert Policy" - self.assertIn(latency_alert_name, found_policy_names, f"{latency_alert_name} not found") - availability_alert_name = f"{service_name} Availability Alert Policy" - self.assertIn(availability_alert_name, found_policy_names, f"{availability_alert_name} not found") - print(f"✅ {service_name} Alerts created") - -class TestServiceLogs(unittest.TestCase): - """ - Make sure logs are sent to Cloud Logging and readable for each service - """ - def setUp(self): - self.client = logging_v2.Client() - - def testLogsExist(self): - services = [service.short for service in _services] - for service_name in services: - log_filter = f'labels."k8s-pod/service_istio_io/canonical-name"="{service_name}"' - results = self.client.list_entries(filter_=log_filter) - first_result = next(results, None) - self.assertIsNotNone(first_result, f"{service_name} logs not found") - print(f"✅ {service_name} logs found") - -if __name__ == '__main__': - project_id = getProjectId() - project_name = project_name + project_id - unittest.main(argv=['first-arg-is-ignored']) diff --git a/tests/provisioning/Dockerfile b/tests/provisioning/Dockerfile deleted file mode 100644 index 52c8af11f..000000000 --- a/tests/provisioning/Dockerfile +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env python3 -# 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. - -# set base image (host OS) -FROM google/cloud-sdk:latest - -# set the working directory in the container -WORKDIR /code - -# copy the dependencies file to the working directory -COPY . . - -# install dependencies -RUN pip3 install -r requirements.txt - -# command to run on container start -CMD [ "python3", "test_runner.py" ] diff --git a/tests/provisioning/README.md b/tests/provisioning/README.md deleted file mode 100644 index 9e69341d0..000000000 --- a/tests/provisioning/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Tests for Cloud Ops Sandbox Provisioning - -This test is integrated into the Github CI system. If you want to run it manually, please follow the steps below and **make sure you are running on the Cloud Shell**. - -1. Build docker -```bash -docker build -t $image_name . -``` - -2. Run docker -```bash -docker run --rm -e GOOGLE_CLOUD_PROJECT=$project_id -e ZONE=$gke_zone -e LOADGEN_ZONE=$loadgen_zone $image_name -``` diff --git a/tests/provisioning/loadgen_test.py b/tests/provisioning/loadgen_test.py deleted file mode 100644 index eabac057a..000000000 --- a/tests/provisioning/loadgen_test.py +++ /dev/null @@ -1,227 +0,0 @@ -#!/usr/bin/env python3 -# 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. - -import json -import os -import subprocess -import time -import unittest -from shlex import split - -import requests -from google.cloud.container_v1.services import cluster_manager -from parameterized import parameterized - - -class TestLoadGenerator(unittest.TestCase): - @classmethod - def setUpClass(cls): - """Get the location of GKE cluster for later queries""" - cls.name = 'projects/{0}/locations/{1}/clusters/loadgenerator'.format( - get_project_id(), get_cluster_zone()) - # authenticate container cluster - command = ('gcloud config set project {0}'.format(get_project_id())) - subprocess.run(split(command)) - # set kubectl context to loadgenerator - command = ( - 'gcloud container clusters get-credentials loadgenerator --zone {0}'.format(get_cluster_zone())) - subprocess.run(split(command)) - # obtain the context name - command = ('kubectl config current-context') - result = subprocess.run( - split(command), encoding='utf-8', capture_output=True) - cls.context = result.stdout - # obtain the public url - command = ( - "kubectl get service loadgenerator --context=%s -o jsonpath='{.status.loadBalancer.ingress[0].ip}'" % TestLoadGenerator.context) - result = subprocess.run( - split(command), encoding='utf-8', capture_output=True) - loadgen_ip = result.stdout.replace('\n', '') - cls.url = 'http://{0}'.format(loadgen_ip) - cls.api_url = 'http://{0}:81'.format(loadgen_ip) - - def testNodeMachineType(self): - """Test if the machine type for the nodes is as specified""" - client = cluster_manager.ClusterManagerClient() - cluster_info = client.get_cluster(name=TestLoadGenerator.name) - machine_type = cluster_info.node_config.machine_type - self.assertEqual(machine_type, 'n1-standard-2') - - def testNumberOfNode(self): - """Test if the number of nodes in the node pool is as specified""" - client = cluster_manager.ClusterManagerClient() - cluster_info = client.get_cluster(name=TestLoadGenerator.name) - node_count = cluster_info.current_node_count - self.assertTrue(node_count == 1) - - def testReachOfLoadgen(self): - """Test if querying load generator returns 2xx""" - r = requests.get(TestLoadGenerator.url) - self.assertTrue(r.ok) - - def testDifferentZone(self): - """Test if load generator cluster is in a different zone from the Hipster Shop cluster""" - self.assertTrue(get_cluster_zone() != os.environ['ZONE']) - - @parameterized.expand([(None,), ('basic',), ('step',)]) - def testStartSwarm(self, pattern): - """ - Test if the load generation works properly when started - Run for each loadgenerator pattern - Start with `None` to check the default case (no explicit pattern) - """ - if pattern: - # reset deployment to use new pattern - set_env_command = "kubectl set env deployment/loadgenerator " \ - f"LOCUST_TASK={pattern}" - delete_pods_command = "kubectl delete pods -l app=loadgenerator" - wait_command = "kubectl wait --for=condition=available" \ - " --timeout=500s deployment/loadgenerator" - subprocess.run(split(set_env_command)) - subprocess.run(split(delete_pods_command)) - subprocess.run(split(wait_command)) - # enable swarm - form_data = {'user_count': 1, 'spawn_rate': 1} - requests.post(f"{TestLoadGenerator.url}/swarm", form_data) - # wait for valid request in case of startup errors - success, tries = False, 0 - while not success and tries < 10: - tries += 1 - time.sleep(2) - response = requests.get(f"{TestLoadGenerator.url}/stats/requests") - if response.ok: - stats = json.loads(response.text) - success = (stats['total_rps'] > 0) - # assert expected values from response - self.assertTrue(response.ok) - self.assertEqual(stats['state'], 'running') - self.assertEqual(stats['errors'], []) - self.assertTrue(stats['user_count'] > 0) - self.assertTrue(stats['total_rps'] > 0) - - def testApiPing(self): - """Test if querying load generator's SRE Recipe API /ping endpoint returns 2xx""" - r = requests.get(f"{TestLoadGenerator.api_url}/api/ping") - self.assertTrue(r.ok) - resp = json.loads(r.text) - self.assertEqual(resp['msg'], "pong") - - @parameterized.expand([(10, None,), (None, 1,), ('foo', 1,), (1, 1.15,)]) - def testApiSpawnErrorOnInvalidRequiredRequestParameter(self, user_count, spawn_rate): - """ - Test if querying load generator's SRE Recipe API /spawn endpoint returns - error for invalid form data format for required parameters. - - Specifically, we expect both user_count and spawn_rate to be required, - non-zero, valid integers. - """ - form_data = {} - if user_count: - form_data["user_count"] = user_count - if spawn_rate: - form_data["spawn_rate"] = spawn_rate - - r = requests.post( - f"{TestLoadGenerator.api_url}/api/spawn/BasicPurchasingUser", form_data) - self.assertFalse(r.ok) - self.assertEqual(r.status_code, 400) - resp = json.loads(r.text) - self.assertTrue(len(resp.get("err", "")) > 0) - - @parameterized.expand([('foo',), (1.15,)]) - def testApiSpawnErrorOnInvalidOptionalRequestParameter(self, stop_after): - """ - Test if querying load generator's SRE Recipe API /spawn endpoint returns - error for invalid form data format for optional parameters. - - Specifically, we expect the stop_after to be valid integers. - """ - form_data = { - "user_count": 10, - "spawn_rate": 1, - "stop_after": stop_after - } - r = requests.post( - f"{TestLoadGenerator.api_url}/api/spawn/BasicPurchasingUser", form_data) - self.assertFalse(r.ok) - self.assertEqual(r.status_code, 400) - resp = json.loads(r.text) - self.assertTrue(len(resp.get("err", "")) > 0) - - def testApiSpawnErrorOnUserNotFound(self): - """ - Test if querying load generator's SRE Recipe API /spawn endpoint returns - error for unknown user class - """ - r = requests.post( - f"{TestLoadGenerator.api_url}/api/spawn/NotExistUser", {'user_count': 1, 'spawn_rate': 1}) - self.assertFalse(r.ok) - self.assertEqual(r.status_code, 404) - resp = json.loads(r.text) - self.assertEqual( - resp['err'], "Cannot find SRE Recipe Load for: NotExistUser") - - def testApiSpawnEndToEnd(self): - """ - Test if starting load using load generator's SRE Recipe API /spawn - endpoint actually generated load, with timeout, correctly. - - We do not separate them into different tests for now, due to possible - race conditions between concurrent execution of tests - """ - - # spawn some users and auto stop after 20 seconds for cleanup - form_data = {'user_count': 10, 'spawn_rate': 5, "stop_after": 20} - r = requests.post( - f"{TestLoadGenerator.api_url}/api/spawn/BasicPurchasingUser", form_data) - self.assertTrue(r.ok) - resp = json.loads(r.text) - self.assertEqual( - resp['msg'], "Spawn Request Received: spawning 10 users at 5 users/second") - - tries = 0 - all_users_spawned = False - has_rps = False - while tries < 10 and not (all_users_spawned and has_rps): - time.sleep(1) - resp = requests.get(f"{TestLoadGenerator.api_url}/stats/requests") - self.assertTrue(resp.ok) - stats = json.loads(resp.text) - if stats["user_count"] == 10: - all_users_spawned = True - if stats["total_rps"] > 0: - has_rps = True - tries += 1 - self.assertTrue(all_users_spawned and has_rps) - - # wait 20 more seconds and check if users are being stopped - # This give us a plenty of buffer for auto stop conditions - time.sleep(20) - resp = requests.get(f"{TestLoadGenerator.api_url}/stats/requests") - self.assertTrue(resp.ok) - stats = json.loads(resp.text) - self.assertLess(stats["user_count"], 10) - - -def get_project_id(): - return os.environ['GOOGLE_CLOUD_PROJECT'] - - -def get_cluster_zone(): - return os.environ['LOADGEN_ZONE'] - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/provisioning/provision_test.py b/tests/provisioning/provision_test.py deleted file mode 100644 index 48c2563c6..000000000 --- a/tests/provisioning/provision_test.py +++ /dev/null @@ -1,106 +0,0 @@ -# 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 __future__ import print_function - -import os -import unittest -import subprocess -from shlex import split -import json -import urllib.request - -from google.cloud.container_v1 import ClusterManagerClient -from google.cloud import error_reporting -from google.api_core import exceptions - -class TestGKECluster(unittest.TestCase): - @classmethod - def setUpClass(cls): - """ Get the location of GKE cluster for later queries """ - cls.name = 'projects/{0}/locations/{1}/clusters/cloud-ops-sandbox'.format(getProjectId(), getClusterZone()) - # authenticate container cluster - command=('gcloud config set project {0}'.format(getProjectId())) - subprocess.run(split(command)) - # set kubectl context - command=('gcloud container clusters get-credentials cloud-ops-sandbox --zone {0}'.format(getClusterZone())) - subprocess.run(split(command)) - # obtain the context name - command=('kubectl config current-context') - result = subprocess.run(split(command), encoding='utf-8', capture_output=True) - cls.context = result.stdout - - def testNodeMachineType(self): - """ Test if the machine type for the nodes is as specified """ - client = ClusterManagerClient() - cluster_info = client.get_cluster(name=TestGKECluster.name) - machine_type = cluster_info.node_config.machine_type - self.assertEqual(machine_type, 'n1-standard-2') - - def testNumberOfNode(self): - """ Test if the number of nodes in the node pool is between 2 and 10, - as specified by autoscaling rules """ - client = ClusterManagerClient() - cluster_info = client.get_cluster(name=TestGKECluster.name) - node_count = cluster_info.current_node_count - self.assertIn(node_count, [2,3,4,5,6,7,8,9,10]) - - def testStatusOfServices(self): - """ Test if all the service deployments are ready """ - command = ("kubectl get deployment --context=%s --all-namespaces -o json" % TestGKECluster.context) - result = subprocess.run(split(command), encoding='utf-8', capture_output=True) - services = json.loads(result.stdout) - for service in services['items']: - self.assertTrue(int(service['status']['readyReplicas']) >= 1) - - def testReachOfHipsterShop(self): - """ Test if querying hipster shop returns 200 """ - command = ("kubectl -n asm-ingress get service istio-ingressgateway --context=%s -o jsonpath='{.status.loadBalancer.ingress[0].ip}'" % TestGKECluster.context) - result = subprocess.run(split(command), encoding='utf-8', capture_output=True) - external_ip = result.stdout.replace('\n', '') - url = 'http://{0}'.format(external_ip) - self.assertTrue(urllib.request.urlopen(url).getcode() == 200) - -class TestProjectResources(unittest.TestCase): - def testAPIEnabled(self): - """ Test if all APIs requested are enabled """ - api_requested = ['iam.googleapis.com', 'compute.googleapis.com', 'clouddebugger.googleapis.com', - 'cloudtrace.googleapis.com', 'clouderrorreporting.googleapis.com', 'sourcerepo.googleapis.com', - 'container.googleapis.com'] - command = ('gcloud services list --format="value(config.name)"') - result = subprocess.run(split(command), encoding='utf-8', capture_output=True) - api_enabled = result.stdout.strip().split('\n') - for api in api_requested: - self.assertTrue(api in api_enabled) - - def testErrorReporting(self): - """ Test if we can report error using Error Reporting API """ - client = error_reporting.Client(project=getProjectId()) - try: - client.report("Testing reachability!") - except exceptions.NotFound as e: - # Error Reporting API is not enabled, so we can't report errors - raise e - except Exception as e: - # unexpected error - raise e - -def getProjectId(): - return os.environ['GOOGLE_CLOUD_PROJECT'] - -def getClusterZone(): - return os.environ['ZONE'] - -if __name__ == '__main__': - unittest.main() diff --git a/tests/provisioning/requirements.txt b/tests/provisioning/requirements.txt deleted file mode 100644 index 66aed956a..000000000 --- a/tests/provisioning/requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ -google-cloud-container==2.10.8 -google-cloud-error-reporting==0.34.0 -google-api-core==1.31.5 -requests==2.24.0 -parameterized==0.7.4 -google-cloud-logging==1.15.1 diff --git a/tests/provisioning/test_runner.py b/tests/provisioning/test_runner.py deleted file mode 100755 index 771dc0466..000000000 --- a/tests/provisioning/test_runner.py +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env python3 -# 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. - -import unittest - -test_suite = unittest.TestLoader().discover(pattern='*_test.py', start_dir='.') -result = unittest.TextTestRunner(verbosity=2, failfast=True).run(test_suite) -if result.wasSuccessful(): - exit(0) -else: - exit(1) diff --git a/tests/ratingservice/main_test.py b/tests/ratingservice/main_test.py deleted file mode 100644 index 138779df4..000000000 --- a/tests/ratingservice/main_test.py +++ /dev/null @@ -1,166 +0,0 @@ -# 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. - -import decimal -import json -import os -import sys -import time -import unittest - -import requests -from requests.exceptions import RequestException -from urllib3.exceptions import ReadTimeoutError - - -class TestEndpoints(unittest.TestCase): - @classmethod - def composeUrl(cls, resource, eid=""): - if not eid: - return "{0}/{1}".format(cls.service_url, resource) - else: - return "{0}/{1}/{2}".format(cls.service_url, resource, eid) - - @classmethod - def setUpClass(cls): - cls.TIMEOUT = 5.0 - - cls.service_url = "" - if len(sys.argv) > 1: - cls.service_url = sys.argv[1].rstrip("/") - - cls.products = [] - path = os.getcwd().rstrip("/") + "/src/productcatalogservice/products.json" - if len(sys.argv) > 2: - path = sys.argv[2] - try: - with open(path) as f: - data = json.load(f) - for product in data["products"]: - cls.products.append(product["id"]) - except Exception: - print("failed to load product ids from ", path) - cls.products = [] - - def setUp(self): - if not TestEndpoints.service_url: - self.fail("Rating service URL is not set for the test") - if not TestEndpoints.products: - self.fail("Test data about products is missing") - - self.session = requests.Session() - # adapter = HTTPAdapter(max_retries=3) - # self.session.mount('https://', adapter) - - def tearDown(self): - self.session.close() - - def sendRequest(self, method, url, **kwargs): - headers = { - "Accept": "application/json", - "Accept-Encoding": "", - "User-Agent": None, - } - lastError = None - retries = 3 - while retries > 0: - try: - if method == "GET": - kwargs.setdefault("allow_redirects", True) - return self.session.request( - method, - url, - timeout=TestEndpoints.TIMEOUT, - headers=headers, - **kwargs - ) - except (RequestException, ReadTimeoutError) as err: - lastError = err - time.sleep(1) - retries -= 1 - raise lastError - - def testGetAllRatings(self): - """test getting all ratings""" - url = TestEndpoints.composeUrl("ratings") - res = self.sendRequest("GET", url) - self.assertEqual(res.status_code, 200) - ratings = res.json().get("ratings") - self.assertTrue(type(ratings) == list) - ids = [r["id"] for r in ratings] - self.assertEqual(set(ids), set(TestEndpoints.products)) - - def testGetProductRating(self): - """test getting ratings for a shop product""" - # use products[0] in "get product rating" test - test_product_id = TestEndpoints.products[0] - url = TestEndpoints.composeUrl("rating", test_product_id) - res = self.sendRequest("GET", url) - self.assertEqual(res.status_code, 200) - - def testGetRatingNotExist(self): - """test getting rating for non-exist product""" - url = TestEndpoints.composeUrl("rating", "random") - res = self.sendRequest("GET", url) - self.assertEqual(res.status_code, 404) - - def testPostNewRating(self): - """test posting new rating to a product""" - # use products[1] in "post new vote" test - test_product_id = TestEndpoints.products[1] - url = TestEndpoints.composeUrl("rating") - res = self.sendRequest("POST", url, json={"rating": 5, "id": test_product_id}) - self.assertEqual(res.status_code, 200) - - def testNewRatingCalculation(self): - """test rating calculation after recollection""" - # use products[2] to avoid counting new vote from testRate() test - test_product_id = TestEndpoints.products[2] - new_rating_vote = 5 - url_get = TestEndpoints.composeUrl("rating", test_product_id) - url_post = TestEndpoints.composeUrl("rating") - url_recollect = TestEndpoints.composeUrl("ratings:recollect") - - # get current rating / post new vote / recollect / get updated rating - result1 = self.sendRequest("GET", url_get) - self.assertEqual(result1.status_code, 200) - result2 = self.sendRequest( - "POST", url_post, json={"rating": new_rating_vote, "id": test_product_id} - ) - self.assertEqual(result2.status_code, 200) - result2 = self.sendRequest("POST", url_recollect) - self.assertEqual(result2.status_code, 200) - result2 = self.sendRequest("GET", url_get) - self.assertEqual(result2.status_code, 200) - - data = result1.json() - prev_vote = data["votes"] - prev_rating = decimal.Decimal(data["rating"]) - data = result2.json() - new_vote = data["votes"] - new_rating = decimal.Decimal(data["rating"]) - self.assertEqual(new_vote, prev_vote + 1) - expected_rating = prev_rating + ( - (new_rating_vote - prev_rating) / (prev_vote + 1) - ) - # compare expected result rounded to 4 decimal places - QUANTIZE_VALUE = decimal.Decimal("0.0001") - self.assertEqual( - new_rating.quantize(QUANTIZE_VALUE), - expected_rating.quantize(QUANTIZE_VALUE), - ) - - -if __name__ == "__main__": - unittest.main(argv=["first-arg-is-ignored"]) diff --git a/tests/ratingservice/requirements.txt b/tests/ratingservice/requirements.txt deleted file mode 100644 index 522e1a40b..000000000 --- a/tests/ratingservice/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests>=2.23.0 diff --git a/tests/recipes/test_recommendation_crash_recipe.sh b/tests/recipes/test_recommendation_crash_recipe.sh deleted file mode 100755 index 23dabeee0..000000000 --- a/tests/recipes/test_recommendation_crash_recipe.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash -# 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. - -# add sandboxctl to path -SCRIPT_DIR=$(dirname $(realpath -s $0)) -SRE_RECIPES_DIR=$(realpath $SCRIPT_DIR/../../sre-recipes) -export PATH=$PATH:$SRE_RECIPES_DIR - -set -e -echo "Testing Recommendation Crash SRE Recipe" - -HTTP_ADDR=$(sandboxctl describe | grep "Hipstershop web app address" | awk '{ print $NF }') -echo "Hipstershop endpoint: $HTTP_ADDR" - -echo "- testing request before changes..." -curl --show-error --fail $HTTP_ADDR/product/OLJCESPC7Z | grep Typewriter - -echo "- breaking sandbox..." -sandboxctl sre-recipes break recipe3 -sleep 10 -kubectl wait --for=condition=ready --timeout=120s pods --all - -echo "- expecting to see 500 error..." -curl -I --no-fail $HTTP_ADDR/product/OLJCESPC7Z | grep "500 Internal Server Error" - -echo "- checking for expected recomendationservice log..." -sleep 30 -kubectl logs -l app=recommendationservice | grep "invalid literal for int() with base 10: '5.0'" - -echo "- restoring sandbox" -sandboxctl sre-recipes restore recipe3 -sleep 10 -restored_pod=$(kubectl get pods --sort-by=.status.startTime -o jsonpath="{.items[-1].metadata.name}") -kubectl wait --for=condition=ready --timeout=120s pod $restored_pod - -echo "- testing restored website..." -curl --show-error --fail $HTTP_ADDR/product/OLJCESPC7Z | grep Typewriter - -echo "✓ Tests Passed" diff --git a/tests/recipes/validate_recipe_configs.py b/tests/recipes/validate_recipe_configs.py deleted file mode 100644 index ab588abc6..000000000 --- a/tests/recipes/validate_recipe_configs.py +++ /dev/null @@ -1,62 +0,0 @@ -# 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. - -# -*- coding: utf-8 -*- - -import os -import json -import yaml -import glob -import jsonschema - -RECIPES_ROOT = os.path.join(os.path.dirname( - os.path.abspath(__file__)), "../../sre-recipes/recipes/configs_based") -SCHEMA_ROOT = RECIPES_ROOT + "/schema" - -print("Loading base schema...") -with open(SCHEMA_ROOT + "/schema.json", "r") as file: - schema = json.load(file) - -print("Bundling additional schema definitions...") -for def_path in glob.glob(SCHEMA_ROOT + "/defs/*.schema.json"): - def_name = os.path.basename(def_path).split(".")[0] - with open(def_path, "r") as def_file: - def_schema = json.load(def_file) - if "$defs" not in schema: - schema["$defs"] = {} - schema["$defs"][def_name] = def_schema - -print("Running validations on all SRE recipe configs...") -has_error = False -for recipe_path in glob.glob(RECIPES_ROOT + "/*.yaml"): - recipe_name = os.path.basename(recipe_path).split(".")[0] - print("Validating:", recipe_name) - with open(recipe_path, "r") as recipe_file: - try: - recipe_config = yaml.load( - recipe_file.read(), Loader=yaml.FullLoader) - except Exception as e: - print("Invalid or empty YAML:", e) - has_error = True - continue - try: - jsonschema.validate(recipe_config, schema) - print("Valid!") - except Exception as e: - print("Invalid!", e) - has_error = True - -if has_error: - print("ERROR. At least one SRE Recipe config is invalid.") - exit(1) diff --git a/tests/requirements.txt b/tests/requirements.txt deleted file mode 100644 index 685b370a2..000000000 --- a/tests/requirements.txt +++ /dev/null @@ -1,8 +0,0 @@ -google-cloud-monitoring==1.0.0 -google-cloud-monitoring-dashboards==1.0.0 -tabulate>=0.8.7 -google-api-python-client==1.10.0 -oauth2client>=4.1.3 -jsonschema>=3.2.0 -pyyaml>-5.4.1 -google-cloud-logging==3.0.0 diff --git a/tests/run_tests.sh b/tests/run_tests.sh deleted file mode 100755 index fd31553a4..000000000 --- a/tests/run_tests.sh +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/bash -# Copyright 2022 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. - -# Run all tests to ensure environment is working as expected - -set -o errexit # Exit on error -#set -o nounset # Trigger error when expanding unset variables -if [[ -n "$DEBUG" ]]; then set -x; fi - -# ensure the working dir is the script's folder -SCRIPT_DIR=$(realpath $(dirname "$0")) -cd $SCRIPT_DIR - -# set environment variables -export PROJECT_ID=$(gcloud config get-value project) -export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)") -export ZONE=$(gcloud container clusters list --filter="name:cloud-ops-sandbox" --project ${PROJECT_ID} --format="value(zone)") -export LOADGEN_ZONE=$(gcloud container clusters list --filter="name:loadgenerator" --project ${PROJECT_ID} --format="value(zone)") - -# run monitoring integration tests -echo "running monitoring integration tests.." -python3 -m venv --system-site-packages monitor-venv -source monitor-venv/bin/activate -python3 -m pip install -r $SCRIPT_DIR/requirements.txt -python3 $SCRIPT_DIR/monitoring_integration_test.py ${PROJECT_ID} ${PROJECT_NUMBER} -deactivate - -# run provisioning test -echo "running provisioning tests.." -python3 -m venv --system-site-packages provision-venv -source provision-venv/bin/activate -python3 -m pip install -r $SCRIPT_DIR/provisioning/requirements.txt -pushd $SCRIPT_DIR/provisioning - python3 ./test_runner.py -popd -deactivate - -# run rating service tests -if [[ -z "$SKIP_RATINGS_TEST" ]]; then - echo "running ratingservice tests.." - pushd $SCRIPT_DIR/.. - RATING_SERVICE_URL="https://ratingservice-dot-$(gcloud app describe --format='value(defaultHostname)' --project=${PROJECT_ID})" - python3 -m venv --system-site-packages ratings-venv - source ratings-venv/bin/activate - python3 -m pip install -r $SCRIPT_DIR/ratingservice/requirements.txt - python3 $SCRIPT_DIR/ratingservice/main_test.py $RATING_SERVICE_URL - deactivate - popd -else - echo "rating test skipped" -fi - -# run sre recipes tests -echo "running SRE recipes tests.." -$SCRIPT_DIR/recipes/test_recommendation_crash_recipe.sh - -echo "✅ All tests pass"