Deploy an example transactional workflows application in a microservices architecture on Google Cloud


This document describes how to deploy an example application using Cloud Run, Pub/Sub, Workflows, and Firestore in Datastore mode (Datastore). It's intended for application developers who want to implement transactional workflows in a microservices based application.

This document is part of a series that is composed of the following:

This example application that you deploy in this tutorial implements microservices for two architectural patterns:

  • A choreography-based saga
  • A synchronous orchestration

The application contains a web client. You can experiment with both of these patterns from the Google Cloud CLI and from the web client.

Objectives

  • Deploy server-side components for the choreography-based saga architecture
  • Deploy server-side components for the synchronous orchestration architecture
  • Test the server-side components with the curl command
  • Deploy a web application and execute workflows through it

Costs

In this document, you use the following billable components of Google Cloud:

To generate a cost estimate based on your projected usage, use the pricing calculator. New Google Cloud users might be eligible for a free trial.

When you finish the tasks that are described in this document, you can avoid continued billing by deleting the resources that you created. For more information, see Clean up.

Before you begin

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  2. Make sure that billing is enabled for your Google Cloud project.

  3. Enable the Cloud Services, Cloud Run, Workflows, Cloud Build, and Cloud Scheduler APIs.

    Enable the APIs

Clone the source code

In this section, you set your project ID and clone the source code in Cloud Shell.

  1. In Cloud Shell, set your project ID:

    PROJECT_ID=PROJECT_ID
    

    Replace PROJECT_ID with the project ID of the Google Cloud project that you created earlier.

  2. Set the project ID:

    gcloud config set project $PROJECT_ID
    
  3. Clone the tutorial repository:

    cd $HOME
    git clone https://github.com/GoogleCloudPlatform/transactional-microservice-examples
    

Deploy server-side components for choreography-based saga architectures

In this section, you deploy server-side components of the example application. The application implements choreography-based saga architectures such as microservices on Cloud Run, event publishing schedules on Cloud Scheduler, and Pub/Sub topics.

Build and deploy container images

  1. In Cloud Shell, build a container image for the Order service named order-async and deploy it on Cloud Run:

    cd $HOME/transactional-microservice-examples/services/order-async
    gcloud builds submit --tag gcr.io/$PROJECT_ID/order-service-async
    gcloud run deploy order-service-async \
      --image gcr.io/$PROJECT_ID/order-service-async \
      --platform=managed --region=us-central1 \
      --no-allow-unauthenticated
    
  2. Build a container image for the Customer service named customer-async and deploy it on Cloud Run:

    cd $HOME/transactional-microservice-examples/services/customer-async
    gcloud builds submit --tag gcr.io/$PROJECT_ID/customer-service-async
    gcloud run deploy customer-service-async \
      --image gcr.io/$PROJECT_ID/customer-service-async \
      --platform=managed --region=us-central1 \
      --no-allow-unauthenticated
    
  3. Build a container image for the event-publisher service and deploy it on Cloud Run:

    cd $HOME/transactional-microservice-examples/services/event-publisher
    gcloud builds submit --tag gcr.io/$PROJECT_ID/event-publisher
    gcloud run deploy event-publisher \
      --image gcr.io/$PROJECT_ID/event-publisher \
      --platform=managed --region=us-central1 \
      --no-allow-unauthenticated \
      --set-env-vars "PROJECT_ID=$PROJECT_ID"
    

Create an index for Datastore

In this section, you create an index for Datastore. This index is used by the event-publisher service to select the events that must be published.

  1. In Google Cloud console, on the Datastore menu, select Datastore mode .

  2. Click Choose where to store your data and select us-east1 as the location. Then, click Create database.

  3. Create an index for Datastore:

    cd $HOME/transactional-microservice-examples/services/event-publisher
    gcloud datastore indexes create index.yaml --quiet
    
  4. In Google Cloud console, on the Datastore menu, select Indexes and wait for the status of the index to change from Indexing to Serving. This process might take a few minutes.

Create a service account to invoke microservices on Cloud Run

  • In Cloud Shell, create the cloud-run-invoker service account:

    SERVICE_ACCOUNT_NAME="cloud-run-invoker"
    SERVICE_ACCOUNT_EMAIL=${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com
    gcloud iam service-accounts create $SERVICE_ACCOUNT_NAME \
      --display-name "Cloud Run Invoker"
    

    You use this service account later in this tutorial to invoke the REST APIs for the microservices that run on Cloud Run.

Define a schedule to call the event publisher service

In this section, you define a schedule to invoke the event publisher named event-publisher at one-minute intervals.

  1. In Cloud Shell, assign the run.invoker role to the event publisher service.

    SERVICE_NAME="event-publisher"
    gcloud run services add-iam-policy-binding $SERVICE_NAME \
      --member=serviceAccount:$SERVICE_ACCOUNT_EMAIL \
      --role=roles/run.invoker \
      --platform=managed --region=us-central1
    
  2. Define a schedule to call the Event publisher service named event-publisher at one minute intervals by using the cloud-run-invoker service account:

    SERVICE_NAME="event-publisher"
    SERVICE_URL=$(gcloud run services list --platform managed \
      --format="table[no-heading](URL)"
      --filter="SERVICE:${SERVICE_NAME}")
    SERVICE_URL="${SERVICE_URL}/api/v1/event/publish"
    gcloud scheduler jobs create http event-publisher-scheduler \
      --schedule='* * * * *' \
      --http-method=GET \
      --uri=$SERVICE_URL \
      --oidc-service-account-email=$SERVICE_ACCOUNT_EMAIL \
      --oidc-token-audience=$SERVICE_URL \
      --location=us-central1
    

Create Pub/Sub topics

  • In Cloud Shell, create the following Pub/Sub topics:

    gcloud pubsub topics create order-service-event
    gcloud pubsub topics create customer-service-event
    

The order-service-event topic is used by the Order service and the event-publisher service to publish events from the Order service. The customer-service-event topic is used to publish events from the Customer service.

Define a topic to send event notifications to microservices

In this section, you define the push-subscription topic to deliver messages in Pub/Sub topics to microservices.

  1. In Cloud Shell, assign the iam.serviceAccountTokenCreator role to the project Pub/Sub service account:

    PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format "value(projectNumber)")
    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member=serviceAccount:service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com \
      --role=roles/iam.serviceAccountTokenCreator
    

    This command lets the service account create an access token to invoke microservices on Cloud Run.

  2. Assign the run.invoker role to the customer-service-async service:

    SERVICE_NAME="customer-service-async"
    gcloud run services add-iam-policy-binding $SERVICE_NAME \
      --member=serviceAccount:$SERVICE_ACCOUNT_EMAIL \
      --role=roles/run.invoker \
      --platform=managed --region=us-central1
    
  3. Create a push-subscription topic:

    SERVICE_URL=$(gcloud run services list --platform managed \
      --format="table[no-heading](URL)" --filter="SERVICE:${SERVICE_NAME}")
    SERVICE_URL="${SERVICE_URL}/api/v1/customer/pubsub"
    gcloud pubsub subscriptions create push-order-to-customer \
      --topic order-service-event \
      --push-endpoint=$SERVICE_URL \
      --push-auth-service-account=$SERVICE_ACCOUNT_EMAIL
    

    This topic delivers messages in the order-service-event topic to the Customer service using the cloud-run-invoker service account.

  4. Assign the run.invoker role to the order-service-async service:

    SERVICE_NAME="order-service-async"
    gcloud run services add-iam-policy-binding $SERVICE_NAME \
      --member=serviceAccount:$SERVICE_ACCOUNT_EMAIL \
      --role=roles/run.invoker \
      --platform=managed --region=us-central1
    
  5. Create a push-subscription topic:

    SERVICE_URL=$(gcloud run services list --platform managed \
      --format="table[no-heading](URL)" --filter="SERVICE:${SERVICE_NAME}")
    SERVICE_URL="${SERVICE_URL}/api/v1/order/pubsub"
    gcloud pubsub subscriptions create push-customer-to-order \
      --topic customer-service-event \
      --push-endpoint=$SERVICE_URL \
      --push-auth-service-account=$SERVICE_ACCOUNT_EMAIL
    

    The push-subscription topic delivers messages in the customer-service-event topic to the Order service by using the cloud-run-invoker service account.

Deploy server-side components for a synchronous orchestration architecture

In this section, you deploy the server-side components for the example application. These components implement a synchronous orchestration architecture on Cloud Run, as well as a workflow which is executed with Workflows.

Build and deploy container images

In this section, you build container images for microservices and deploy them on Cloud Run.

  1. In Cloud Shell, build a container image for the Order service named order-sync and deploy it on Cloud Run:

    cd $HOME/transactional-microservice-examples/services/order-sync
    gcloud builds submit --tag gcr.io/$PROJECT_ID/order-service-sync
    gcloud run deploy order-service-sync \
      --image gcr.io/$PROJECT_ID/order-service-sync \
      --platform=managed --region=us-central1 \
      --no-allow-unauthenticated
    
  2. Build a container image for the Customer service named customer-sync and deploy it on Cloud Run:

    cd $HOME/transactional-microservice-examples/services/customer-sync
    gcloud builds submit --tag gcr.io/$PROJECT_ID/customer-service-sync
    gcloud run deploy customer-service-sync \
      --image gcr.io/$PROJECT_ID/customer-service-sync \
      --platform=managed --region=us-central1 \
      --no-allow-unauthenticated
    
  3. Build a container image for the Order processor service named order-processor and deploy it on Cloud Run:

    cd $HOME/transactional-microservice-examples/services/order-processor
    gcloud builds submit --tag gcr.io/$PROJECT_ID/order-processor-service
    gcloud run deploy order-processor-service \
      --image gcr.io/$PROJECT_ID/order-processor-service \
      --platform=managed --region=us-central1 \
      --no-allow-unauthenticated \
      --set-env-vars "PROJECT_ID=$PROJECT_ID"
    

Create a service account to invoke microservices on Cloud Run

In this section, you reuse the cloud-run-invoker service account that you created in Create a service account to invoke microservices on Cloud Run.

Deploy a workflow to process an order

  1. In Cloud Shell, assign the run.invoker and run.viewer roles to the cloud-run-invoker service account for the order-service-sync service.

    SERVICE_NAME="order-service-sync"
    gcloud run services add-iam-policy-binding $SERVICE_NAME \
      --member=serviceAccount:$SERVICE_ACCOUNT_EMAIL \
      --role=roles/run.invoker \
      --platform=managed --region=us-central1
    gcloud run services add-iam-policy-binding $SERVICE_NAME \
      --member=serviceAccount:$SERVICE_ACCOUNT_EMAIL \
      --role=roles/run.viewer \
      --platform=managed --region=us-central1
    
  2. Assign run.invoker and run.viewer roles to the cloud-run-invoker service account for the customer-service-sync service:

    SERVICE_NAME="customer-service-sync"
    gcloud run services add-iam-policy-binding $SERVICE_NAME \
      --member=serviceAccount:$SERVICE_ACCOUNT_EMAIL \
      --role=roles/run.invoker \
      --platform=managed --region=us-central1
    gcloud run services add-iam-policy-binding $SERVICE_NAME \
      --member=serviceAccount:$SERVICE_ACCOUNT_EMAIL \
      --role=roles/run.viewer \
      --platform=managed --region=us-central1
    
  3. Use the cloud-run-invoker service account to deploy a workflow:

    SERVICE_NAME="order-service-sync"
    ORDER_SERVICE_URL=$(gcloud run services list --platform managed \
      --format="table[no-heading](URL)" --filter="SERVICE:${SERVICE_NAME}")
    
    SERVICE_NAME="customer-service-sync"
    CUSTOMER_SERVICE_URL=$(gcloud run services list --platform managed \
      --format="table[no-heading](URL)" --filter="SERVICE:${SERVICE_NAME}")
    
    cd $HOME/transactional-microservice-examples/services/order-processor
    cp order_workflow.yaml.template order_workflow.yaml
    sed -i "s#ORDER-SERVICE-URL#${ORDER_SERVICE_URL}#" order_workflow.yaml
    sed -i "s#CUSTOMER-SERVICE-URL#${CUSTOMER_SERVICE_URL}#" order_workflow.yaml
    
    gcloud beta workflows deploy order_workflow \
      --source=order_workflow.yaml \
      --service-account=$SERVICE_ACCOUNT_EMAIL
    

Test choreography-based saga architecture components

In this section, you test components deployed on the choreography-based saga architecture using the curl command.

  • In Cloud Shell, set environment variables that point to URLs of API endpoints for the customer-service-async and order-service-async microservices:

    SERVICE_NAME="customer-service-async"
    CUSTOMER_SERVICE_URL=$(gcloud run services list --platform managed \
      --format="table[no-heading](URL)" --filter="SERVICE:${SERVICE_NAME}")
    
    SERVICE_NAME="order-service-async"
    ORDER_SERVICE_URL=$(gcloud run services list --platform managed \
      --format="table[no-heading](URL)" --filter="SERVICE:${SERVICE_NAME}")
    

Create a customer entry

  • In Cloud Shell, create a customer ID named customer01 by sending an API request to the Customer service named customer-service-async:

    curl -X POST -H "Authorization: Bearer $(gcloud auth print-identity-token)" \
      -H "Content-Type: application/json" \
      -d '{"customer_id":"customer01", "limit":10000}' \
      -s ${CUSTOMER_SERVICE_URL}/api/v1/customer/limit | jq .
    

    The output is similar to the following:

    {
      "credit": 0,
      "customer_id": "customer01",
      "limit": 10000
    }
    

Submit an order

In this section, you submit an order and trigger an order ID assignment for it.

  1. In Cloud Shell, submit an order by sending an API request to the Order service named order-service-async:

    curl -X POST -H "Authorization: Bearer $(gcloud auth print-identity-token)" \
      -H "Content-Type: application/json" \
      -d '{"customer_id":"customer01", "number":10}' \
      -s ${ORDER_SERVICE_URL}/api/v1/order/create | jq .
    

    In this case, you order 10 items by specifying the following: "number": 10

    The output is similar to the following:

    {
      "customer_id": "customer01",
      "number": 10,
      "order_id": "720d1305-b6fd-4f57-aaf4-fd2ca5bdfe1e",
      "status": "pending"
    }
    

    The "order_id" flag in the output shows the unique order ID which is assigned to the order. Copy this ID because you use it in the next step.

  2. Set the order ID in an environment variable:

    ORDER_ID=ORDER_ID
    

    Replace ORDER_ID with the "order_id" flag that you copied in the previous step.

Check an order status

In this section, you check how an order status changes.

  1. In Cloud Shell, get the status of the order by sending an API request to the Order service named order-service-async:

    curl -X POST -H "Authorization: Bearer $(gcloud auth print-identity-token)" \
      -H "Content-Type: application/json" \
      -d "{\"customer_id\":\"customer01\", \"order_id\":\"$ORDER_ID\"}" \
      -s ${ORDER_SERVICE_URL}/api/v1/order/get | jq .
    

    The output resembles the following:

    {
      "customer_id": "customer01",
      "number": 10,
      "order_id": "720d1305-b6fd-4f57-aaf4-fd2ca5bdfe1e",
      "status": "pending"
    }
    

    The "status" flag in the output shows the status of the order. If the transactional process is still running, the status is "pending". In this case, wait a few minutes and check the status again by running the same command. When the transactional process is complete, the status shows as "accepted".

  2. Get customer information for the customer01 customer ID:

    curl -X POST -H "Authorization: Bearer $(gcloud auth print-identity-token)" \
      -H "Content-Type: application/json" \
      -d '{"customer_id":"customer01"}' \
      -s ${CUSTOMER_SERVICE_URL}/api/v1/customer/get | jq .
    

    The output resembles the following:

    {
      "credit": 1000,
      "customer_id": "customer01",
      "limit": 10000
    }
    

    The "credit" flag shows the current credit usage of the customer. It increases by 1,000 because the business logic for this transaction is to increase the credit by 100 for one item.

    You can repeat the order process by repeating the steps in Submit an order. If you order 100 items by specifying "number": 100, the final status of the order is "rejected" because the credit usage goes over the limit.

Test synchronous orchestration architecture components

In this section, you test the deployed components of the synchronous orchestration architecture using the curl command.

  • In Cloud Shell, set the environment variables that point to URLs for the API endpoints of the customer-service-sync, order-service-sync, and order-processor-service microservices:

    SERVICE_NAME="customer-service-sync"
    CUSTOMER_SERVICE_URL=$(gcloud run services list --platform managed \
      --format="table[no-heading](URL)" --filter="SERVICE:${SERVICE_NAME}")
    
    SERVICE_NAME="order-service-sync"
    ORDER_SERVICE_URL=$(gcloud run services list --platform managed \
      --format="table[no-heading](URL)" --filter="SERVICE:${SERVICE_NAME}")
    
    SERVICE_NAME="order-processor-service"
    ORDER_PROCESSOR_URL=$(gcloud run services list --platform managed \
      --format="table[no-heading](URL)" --filter="SERVICE:${SERVICE_NAME}")
    

Create a customer entry

  • In Cloud Shell send an API request to the Customer service named customer-service-sync to create a customer ID named customer02:

    curl -X POST -H "Authorization: Bearer $(gcloud auth print-identity-token)" \
      -H "Content-Type: application/json" \
      -d '{"customer_id":"customer02", "limit":10000}' \
      -s ${CUSTOMER_SERVICE_URL}/api/v1/customer/limit | jq .
    

    The output resembles the following:

    {
      "credit": 0,
      "customer_id": "customer02",
      "limit": 10000
    }
    

Submit an order

In this section, you submit an order and check the result.

  1. In Cloud Shell, submit an order by sending an API request to Order service order-processor-service:

    curl -X POST -H "Authorization: Bearer $(gcloud auth print-identity-token)" \
      -H "Content-Type: application/json" \
      -d '{"customer_id":"customer02", "number":10}' \
      -s ${ORDER_PROCESSOR_URL}/api/v1/order/process | jq .
    

    In this case, you order 10 items by specifying "number": 10.

    The output is similar to the following:

    {
      "customer_id": "customer02",
      "number": 10,
      "order_id": "fb6d5087-dd99-4d5a-84c2-0e381016b9d3",
      "status": "accepted"
    }
    

    Because the transactional workflow is conducted in a synchronous way, the client immediately sees the result. In this case, the final status is the following: "accepted"

  2. Get the customer information with the customer ID of customer02:

    curl -X POST -H "Authorization: Bearer $(gcloud auth print-identity-token)" \
      -H "Content-Type: application/json" \
      -d '{"customer_id":"customer02"}' \
      -s ${CUSTOMER_SERVICE_URL}/api/v1/customer/get | jq .
    

    The output is similar to the following:

    {
      "credit": 1000,
      "customer_id": "customer02",
      "limit": 10000
    }
    

    The credit usage of the customer increases by 1,000. To repeat the order process, repeat these steps. If you order 100 items by specifying the value "number": 100, the client immediately gets the result "rejected" because the credit usage goes over the limit.

Optional: Deploy a web application

In this section, as an optional extension to the tutorial, you deploy an example web application that executes the transactional workflow on top of microservices that you deployed in the previous section. You use Firebase Hosting to deploy a web application that interacts with backend microservices running on Cloud Run.

Firebase Hosting has built-in Cloud Run integration, which lets you host the web application and backend microservices services in the same domain. In other types of deployment, you may have Cross-Origin Resource Sharing (CORS) issues. For more information, see Authenticating end users.

Web application integration.

Firebase Hosting integration does the following:

  • Hosts static assets for the web application.
  • Redirects access to APIs to the following backend services on Cloud Run:
    • /customer-service-sync/* to customer-service-sync
    • /customer-service-async/* to customer-service-async
    • /order-service-sync/* to order-service-sync
    • /order-service-async/* to order-service-async
    • /order-processor-service/* to order-processor-service
  • Returns static assets of the web application.

Set up Firebase

In this section, you set up Firebase to host the web application on Firebase Hosting.

  1. In Cloud Shell, update Node.js to the latest LTS version to use Firebase CLI:

    nvm install lts/gallium
    
  2. Add Firebase resources to the existing Google Cloud project:

    firebase projects:addfirebase $PROJECT_ID
    
  3. Add a default project alias for Firebase CLI:

    jq -n --arg project_id $PROJECT_ID \
      '{"projects": {"default":$project_id}}' > \
      $HOME/transactional-microservice-examples/frontend/.firebaserc
    

Deploy the web application

In this section, you deploy the web application on Firebase Hosting.

  1. In Cloud Shell, build the web frontend application:

    cd $HOME/transactional-microservice-examples/frontend
    yarn install && yarn build
    
  2. Deploy the web application on Firebase Hosting:

    firebase deploy
    

Use the web application

  • Enter the hosting URL that you copied in the previous section into your browser. You see the homepage for the web application.

Initialize the web application with an identity token

In this section, you initialize the web application with your identity token and proceed to the Shopping page.

  1. In Cloud Shell, print the identity token:

    gcloud auth print-identity-token
    
  2. Copy the output of the previous command and paste it into the text box.

  3. Click Proceed. You are redirected to the Shopping page if the identity token is valid.

Add items to a cart

  • In the web application, click Add to cart to add items to a cart.

Check items in a cart

  • In the web application, click the cart icon on the navigation bar to go to the Checkout page. You see items in the cart.

Submit an order using the asynchronous service

  1. In the web application, click the shopping cart icon on the navigation bar to go to the Checkout page.
  2. Click Submit order (Async). You are redirected to the Order history page if the order is successfully submitted.

Submit an order using the synchronous service

  1. In the web application, click the shopping cart icon on the navigation bar to go to the Checkout page.
  2. Click Submit order (Sync). You will be redirected to the Order history page if the order is successfully submitted.

Check the order history

  • In the web application, click Orders on the navigation bar to go to the Order history page.

Update the status of an incomplete order

  1. In the web application, click Orders on the navigation bar to go to the Order history page.
  2. Click the refresh icon for an individual order. The icon is shown only if the order is processed asynchronously and the status is pending.

Check a customer's current budget

  • In the web application, click the customer name (customer-number) on the navigation bar to go to their profile page.

Navigation to customer profile.

Reset the state in the web application

  • In your browser, reload the web application. States like the items in the cart, the order history, and the customer information are reset, and you are redirected to the homepage.

Clean up

To avoid incurring charges to your Google Cloud account for the resources used in this tutorial, either delete the project that contains the resources, or keep the project and delete the individual resources.

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Delete individual resources

In this section, you delete the individual resources that you use in this tutorial.

Deactivate Firebase Hosting

  • In Cloud Shell, run the following command to stop serving Firebase Hosting traffic:

     firebase hosting:disable -f
    

Delete services on Cloud Run

  • In Cloud Shell, delete services on Cloud Run:

    gcloud run services delete order-service-async \
      --platform=managed --region=us-central1 --quiet
    
    gcloud run services delete customer-service-async \
      --platform=managed --region=us-central1 --quiet
    
    gcloud run services delete order-service-sync \
      --platform=managed --region=us-central1 --quiet
    
    gcloud run services delete customer-service-sync \
      --platform=managed --region=us-central1 --quiet
    
    gcloud run services delete order-processor-service \
      --platform=managed --region=us-central1 --quiet
    
    gcloud run services delete event-publisher \
      --platform=managed --region=us-central1 --quiet
    

Delete container images used by Cloud Run

  • In Cloud Shell, delete the container images that you created for this tutorial:

    gcloud container images delete \
      gcr.io/$PROJECT_ID/order-service-async --force-delete-tags --quiet
    gcloud container images delete \
      gcr.io/$PROJECT_ID/customer-service-async --force-delete-tags --quiet
    gcloud container images delete \
      gcr.io/$PROJECT_ID/event-publisher --force-delete-tags --quiet
    gcloud container images delete \
      gcr.io/$PROJECT_ID/order-service-sync --force-delete-tags --quiet
    gcloud container images delete \
      gcr.io/$PROJECT_ID/customer-service-sync --force-delete-tags --quiet
    gcloud container images delete \
      gcr.io/$PROJECT_ID/order-processor-service --force-delete-tags --quiet
    

Delete the workflow

  • In Cloud Shell, delete the workflow:

    gcloud beta workflows delete order_workflow --quiet
    

Delete Pub/Sub subscriptions and topics

  1. In Cloud Shell, delete the Pub/Sub subscriptions:

    gcloud pubsub subscriptions delete push-customer-to-order --quiet
    gcloud pubsub subscriptions delete push-order-to-customer --quiet
    
  2. Delete the Pub/Sub topics:

    gcloud pubsub topics delete order-service-event --quiet
    gcloud pubsub topics delete customer-service-event --quiet
    

Delete records from Datastore

  1. In the Google Cloud console, on the Datastore menu, open Entities.
  2. Check all entities in the Customer field.
  3. Click Delete and then click Confirm to delete entities permanently.
  4. Repeat steps 2 and 3 in this procedure for the following fields:.
    1. Event
    2. Order
    3. ProcessedEvent

Delete the job on Cloud Scheduler

  • In Cloud Shell, delete the job that's running on Cloud Scheduler:

    gcloud scheduler jobs delete event-publisher-scheduler --quiet \
      --location=us-central1
    

Delete the service account

  • In Cloud Shell, delete the service account:

    gcloud iam service-accounts delete $SERVICE_ACCOUNT_EMAIL --quiet
    

Delete tutorial assets

  • In Cloud Shell, delete the assets that you use for this tutorial:

    cd $HOME
    rm -rf transactional-microservice-examples
    

What's next