Skip to main content Link Menu Expand (external link) Document Search Copy Copied

Assignment 6 - Using Azure Cosmos DB as a state store

Table of contents

This assignment is about using Azure Cosmos DB as a state store for the TrafficControlService instead of keeping the sate in memory. You will use the Azure Cosmos DB state store component provided by Dapr. This is the third step to reach the final state of the application for this challenge. It is represented by the diagram below.

Azure Container Apps Challenge - Third Deployment

Step 1: Create an Azure Cosmos DB

  1. Open a terminal window.

  2. Azure Cosmos DB account for SQL API is a globally distributed multi-model database service. This account needs to be globally unique. Use the following command to generate a unique name:

    • Linux/Unix shell:

        UNIQUE_IDENTIFIER=$(LC_ALL=C tr -dc a-z0-9 </dev/urandom | head -c 5)
        COSMOS_DB="cosno-dapr-workshop-java-$UNIQUE_IDENTIFIER"
        echo $COSMOS_DB
      
    • Powershell:

        $ACCEPTED_CHAR = [Char[]]'abcdefghijklmnopqrstuvwxyz0123456789'
        $UNIQUE_IDENTIFIER = (Get-Random -Count 5 -InputObject $ACCEPTED_CHAR) -join ''
        $COSMOS_DB = "cosno-dapr-workshop-java-$UNIQUE_IDENTIFIER"
        $COSMOS_DB
      
  3. Create a Cosmos DB account for SQL API:

     az cosmosdb create --name $COSMOS_DB --resource-group rg-dapr-workshop-java --locations regionName=eastus failoverPriority=0 isZoneRedundant=False
    

    The name of the Cosmos DB account must be unique across all Azure Cosmos DB accounts in the world. If you get an error that the name is already taken, try a different name. In the following steps, please update the name of the Cosmos DB account accordingly.

  4. Create a SQL API database:

     az cosmosdb sql database create --account-name $COSMOS_DB --resource-group rg-dapr-workshop-java --name dapr-workshop-java-database
    
  5. Create a SQL API container:

     az cosmosdb sql container create --account-name $COSMOS_DB --resource-group rg-dapr-workshop-java --database-name dapr-workshop-java-database --name vehicle-state --partition-key-path /partitionKey --throughput 400
    

    The partition key path is /partitionKey as mentionned in Dapr documentation.

  6. Get the Cosmos DB account URL and note it down. You will need it in the next step and to deploy it to Azure.

     az cosmosdb show --name $COSMOS_DB --resource-group rg-dapr-workshop-java --query documentEndpoint -o tsv
    
  7. Get the master key and note it down. You will need it in the next step and to deploy it to Azure.

     az cosmosdb keys list --name $COSMOS_DB --resource-group rg-dapr-workshop-java --type keys --query primaryMasterKey -o tsv
    

Step 2: Deploy Azure Cosmos DB state store component to ACA

  1. Open the file dapr/aca-azure-cosmosdb-statestore.yaml in your code editor and look at the content of the file.

  2. Copy or Move this file dapr/aca-azure-cosmosdb-statestore.yaml to dapr/components folder.

  3. Replace the following placeholders in this file dapr/components/aca-azure-cosmosdb-statestore.yaml with the values you noted down in the previous step:

    • <YOUR_COSMOSDB_ACCOUNT_URL> with the Cosmos DB account URL
    • <YOUR_COSMOSDB_MASTER_KEY> with the master key
  4. Go to the root folder of the repository.

  5. Enter the following command to deploy the statestore Dapr component:

     az containerapp env dapr-component set \
       --name cae-dapr-workshop-java \
       --resource-group rg-dapr-workshop-java \
       --dapr-component-name statestore \
       --yaml ./dapr/components/aca-azure-cosmosdb-statestore.yaml
    

Step 3: Add the Azure Cosmos DB state store to the TrafficControlService

  1. Open the TrafficControlService project in your code editor and navigate to the DaprVehicleStateRepository class. This class use the Dapr client to store and retrieve the state of a vehicle. Inspect the implementation of this class.

  2. Navigate to the TrafficControlConfiguration class to swith from the InMemoryVehicleStateRepository to the DaprVehicleStateRepository.

  3. Update @Bean method to instantiate DaprVehicleStateRepository instead of InMemoryVehicleStateRepository:

     @Bean
     public VehicleStateRepository vehicleStateRepository(final DaprClient daprClient) {
         return new DaprVehicleStateRepository(daprClient);
     }
    
  4. Uncomment following @Bean method if not already done:

     //    @Bean
     //    public DaprClient daprClient() {
     //        return new DaprClientBuilder()
     //                .withObjectSerializer(new JsonObjectSerializer())
     //                .build();
     //    }
    
  5. Check all your code-changes are correct by building the code. Execute the following command in the terminal window:

     mvn package
    

Step 4: Build and redeploy traffic control service

In this step, you will rebuild and redeploy the TrafficControlService to use the Azure Cosmos DB state store instead of keeping the state in memory.

  1. Delete the image from local docker:

     docker rmi traffic-control-service:1.0-SNAPSHOT
    
  2. In the root folder of TrafficControlService, run the following command to build and push the image:

     mvn spring-boot:build-image
     docker tag traffic-control-service:1.0-SNAPSHOT "$CONTAINER_REGISTRY.azurecr.io/traffic-control-service:2.0"
     docker push "$CONTAINER_REGISTRY.azurecr.io/traffic-control-service:2.0"
    

    Where $CONTAINER_REGISTRY is the name of your Azure Container Registry.

  3. Update TrafficControlService container with the new image:

     az containerapp update \
       --name ca-traffic-control-service \
       --resource-group rg-dapr-workshop-java \
       --image "$CONTAINER_REGISTRY.azurecr.io/traffic-control-service:2.0"
    

    Where $CONTAINER_REGISTRY is the name of your Azure Container Registry.

Step 5 - Run the simulation

  1. Set the following environment variable:

    • Linux/Unix shell:

      export TRAFFIC_CONTROL_SERVICE_BASE_URL=https://$TRAFFIC_CONTROL_SERVICE_FQDN
      
    • Powershell:

      $env:TRAFFIC_CONTROL_SERVICE_BASE_URL = "https://$TRAFFIC_CONTROL_SERVICE_FQDN"
      
  2. In the root folder of the simulation (Simulation), start the simulation:

     mvn spring-boot:run
    

Step 6 - Test the microservices running in ACA

You can access the log of the container apps from the Azure Portal or directly in a terminal window. To access the logs in the portal, you need to go to your resource group rg-dapr-workshop-java and select the container app for which you need the log. Then select Log stream in Monitoring section.

To access the logs from the terminal, follow the instructions below for each microservice.

The logs can take a few minutes to appear in the Log Analytics Workspace. If the logs are not updated, open the log stream in the Azure Portal.

Traffic Control Service

  1. Run the following command to identify the running revision of traffic control service container apps:

    • Linux/Unix shell:

      TRAFFIC_CONTROL_SERVICE_REVISION=$(az containerapp revision list -n ca-traffic-control-service -g rg-dapr-workshop-java --query "[0].name" -o tsv)
      echo $TRAFFIC_CONTROL_SERVICE_REVISION
      
    • Powershell:

      $TRAFFIC_CONTROL_SERVICE_REVISION = az containerapp revision list -n ca-traffic-control-service -g rg-dapr-workshop-java --query "[0].name" -o tsv
      $TRAFFIC_CONTROL_SERVICE_REVISION
      
  2. Run the following command to get the last 10 lines of traffic control service logs from Log Analytics Workspace:

     az monitor log-analytics query \
       --workspace $LOG_ANALYTICS_WORKSPACE_CUSTOMER_ID \
       --analytics-query "ContainerAppConsoleLogs_CL | where RevisionName_s == '$TRAFFIC_CONTROL_SERVICE_REVISION' | project TimeGenerated, Log_s | sort by TimeGenerated desc | take 10" \
       --out table
    

Fine Collection Service

  1. Run the following command to identify the running revision of fine collection service container apps:

    • Linux/Unix shell:

      FINE_COLLECTION_SERVICE_REVISION=$(az containerapp revision list -n ca-fine-collection-service -g rg-dapr-workshop-java --query "[0].name" -o tsv)
      echo $FINE_COLLECTION_SERVICE_REVISION
      
    • Powershell:

      $FINE_COLLECTION_SERVICE_REVISION = az containerapp revision list -n ca-fine-collection-service -g rg-dapr-workshop-java --query "[0].name" -o tsv
      $FINE_COLLECTION_SERVICE_REVISION
      
  2. Run the following command to get the last 10 lines of fine collection service logs from Log Analytics Workspace:

     az monitor log-analytics query \
       --workspace $LOG_ANALYTICS_WORKSPACE_CUSTOMER_ID \
       --analytics-query "ContainerAppConsoleLogs_CL | where RevisionName_s == '$FINE_COLLECTION_SERVICE_REVISION' | project TimeGenerated, Log_s | sort by TimeGenerated desc | take 10" \
       --out table
    

Vehicle Registration Service

  1. Run the following command to identify the running revision of vehicle registration service container apps:

    • Linux/Unix shell:

      VEHICLE_REGISTRATION_SERVICE_REVISION=$(az containerapp revision list -n ca-vehicle-registration-service -g rg-dapr-workshop-java --query "[0].name" -o tsv)
      echo $VEHICLE_REGISTRATION_SERVICE_REVISION
      
    • Powershell:

      $VEHICLE_REGISTRATION_SERVICE_REVISION = az containerapp revision list -n ca-vehicle-registration-service -g rg-dapr-workshop-java --query "[0].name" -o tsv
      $VEHICLE_REGISTRATION_SERVICE_REVISION
      
  2. Run the following command to get the last 10 lines of vehicle registration service logs from Log Analytics Workspace:

     az monitor log-analytics query \
       --workspace $LOG_ANALYTICS_WORKSPACE_CUSTOMER_ID \
       --analytics-query "ContainerAppConsoleLogs_CL | where RevisionName_s == '$VEHICLE_REGISTRATION_SERVICE_REVISION' | project TimeGenerated, Log_s | sort by TimeGenerated desc | take 10" \
       --out table
    

Check Application Map of Application Insights in Azure Portal to see the connection between the TrafficControlService and the aca-azure-cosmosdb-statestore. Check in Azure Portal the data in Cosmos DB.

< Assignment 5 - Service invocation Assignment 7 - Key Vault as a secret store >