From f51bdeed3da3e79c2037ed7f1f987367a7da1ca1 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Thu, 6 Mar 2025 19:11:12 -0800 Subject: [PATCH 01/38] Add HOME so the script can be run in any folder --- tools/create-azure-resource.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/create-azure-resource.sh b/tools/create-azure-resource.sh index d16c409..de348e7 100755 --- a/tools/create-azure-resource.sh +++ b/tools/create-azure-resource.sh @@ -1,7 +1,9 @@ #!/usr/bin/env bash -source ./azure-resource.profile -source ./funcs.sh +export HOME=/workspaces/java-on-aca + +source ./tools/azure-resource.profile +source ./tools/funcs.sh # Resource Group From 74c31367e6ab10260e8454487f266999ac23af4b Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Fri, 7 Mar 2025 15:17:19 -0800 Subject: [PATCH 02/38] Updated azure-resource.profile and create-azure-resource.sh with new instructions and variable definitions --- tools/azure-resource.profile | 4 ++-- tools/create-azure-resource.sh | 22 +++++++++------------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/tools/azure-resource.profile b/tools/azure-resource.profile index 57c7d35..6c365f2 100644 --- a/tools/azure-resource.profile +++ b/tools/azure-resource.profile @@ -1,4 +1,3 @@ - # Set all the variables with <> and keep the others unchanged # This part is for lab 2 & Lab 3 @@ -6,8 +5,9 @@ # Pay attention to this, use command 'openssl rand -hex 3' to generate a unique id and put value here, don't put command here UNIQUEID= +# To extract the subscription ID, use the following Azure CLI command: +# az account show --query id --output tsv SUBSCRIPTION= -LOCATION= APPNAME=petclinic RESOURCE_GROUP=rg-$APPNAME-$UNIQUEID diff --git a/tools/create-azure-resource.sh b/tools/create-azure-resource.sh index de348e7..e323fd0 100755 --- a/tools/create-azure-resource.sh +++ b/tools/create-azure-resource.sh @@ -7,27 +7,27 @@ source ./tools/funcs.sh # Resource Group +# Random regions for MySQL server +LOCATION=$(random_element australiaeast brazilsouth eastasia eastus2 japaneast southindia swedencentral westus) + az group create -g $RESOURCE_GROUP -l $LOCATION -o table az configure --default group=$RESOURCE_GROUP # MySQL server -# Random regions for MySQL server -SQL_LOCATION=$(random_element australiaeast brazilsouth eastasia eastus2 japaneast southindia swedencentral westus) - SQL_ID=$(az mysql flexible-server show --resource-group $RESOURCE_GROUP --name $MYSQL_SERVER_NAME -o tsv --query id 2>/dev/null) if [[ -n $SQL_ID ]]; then echo -e "${GREEN}INFO:${NC} MySQL server $MYSQL_SERVER_NAME already exists" else - echo -e "${YELLOW}INFO:${NC} Creating MySQL server $MYSQL_SERVER_NAME in region $SQL_LOCATION ..." + echo -e "${YELLOW}INFO:${NC} Creating MySQL server $MYSQL_SERVER_NAME in region $LOCATION ..." az mysql flexible-server create \ --admin-user $MYSQL_ADMIN_USERNAME \ --admin-password $MYSQL_ADMIN_PASSWORD \ --name $MYSQL_SERVER_NAME \ --resource-group $RESOURCE_GROUP \ - --location $SQL_LOCATION \ + --location $LOCATION \ --public-access none \ --yes \ --output table @@ -51,18 +51,16 @@ fi # Azure OpenAI Service -AI_LOCATION=$(random_element australiaeast brazilsouth eastus2 japaneast southindia swedencentral westus) - AI_ID=$(az cognitiveservices account show --resource-group $RESOURCE_GROUP --name $OPEN_AI_SERVICE_NAME -o tsv --query id 2>/dev/null) if [[ -n $ACR_ID ]]; then echo -e "${GREEN}INFO:${NC} OpenAI instance $OPEN_AI_SERVICE_NAME already exists" else - echo -e "${YELLOW}INFO:${NC} Creating OpenAI instance $OPEN_AI_SERVICE_NAME in region $AI_LOCATION ..." + echo -e "${YELLOW}INFO:${NC} Creating OpenAI instance $OPEN_AI_SERVICE_NAME in region $LOCATION ..." az cognitiveservices account create \ --resource-group $RESOURCE_GROUP \ --name $OPEN_AI_SERVICE_NAME \ - --location $AI_LOCATION \ + --location $LOCATION \ --kind OpenAI \ --sku s0 \ --custom-domain $OPEN_AI_SERVICE_NAME \ @@ -124,18 +122,16 @@ fi # Azure Managed Grafana -GRAFANA_LOCATION=$(random_element australiaeast brazilsouth centralindia eastasia eastus2 japaneast swedencentral westus) - GRAFANA_ID=$(az grafana show --name $GRAFANA_NAME --resource-group $RESOURCE_GROUP -o tsv --query id 2>/dev/null) if [[ -n $GRAFANA_ID ]]; then echo -e "${GREEN}INFO:${NC} Grafana instance $GRAFANA_NAME already exists" else - echo -e "${YELLOW}INFO:${NC} Creating Grafana instance $GRAFANA_NAME in region $GRAFANA_LOCATION ..." + echo -e "${YELLOW}INFO:${NC} Creating Grafana instance $GRAFANA_NAME in region $LOCATION ..." az deployment group create \ --resource-group $RESOURCE_GROUP \ --template-file ../infra/bicep/modules/grafana/grafana-dashboard.bicep \ - --parameters grafanaName=$GRAFANA_NAME location=$GRAFANA_LOCATION \ + --parameters grafanaName=$GRAFANA_NAME location=$LOCATION \ --output table fi From 8d42816da47801790c69aaa0e37f19948c39af43 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Sat, 8 Mar 2025 10:26:45 -0800 Subject: [PATCH 03/38] Add bash scripts for lab-2 --- tools/azd-extension/java-on-ai-azd.json | 20 ++++++ .../azd-extension/lab-2/collect-user-info.sh | 9 +++ tools/azd-extension/lab-2/create-aca-env.sh | 67 +++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 tools/azd-extension/java-on-ai-azd.json create mode 100644 tools/azd-extension/lab-2/collect-user-info.sh create mode 100644 tools/azd-extension/lab-2/create-aca-env.sh diff --git a/tools/azd-extension/java-on-ai-azd.json b/tools/azd-extension/java-on-ai-azd.json new file mode 100644 index 0000000..a85352b --- /dev/null +++ b/tools/azd-extension/java-on-ai-azd.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://aka.ms/azd-extension-schema", + "name": "java-on-ai-extension", + "version": "1.1.0", + "description": "Java on AI AZD extension with bash", + "publisher": "Pete Tian", + "commands": [ + { + "name": "hello", + "description": "My first AZD command", + "entryPoint": "./scripts/hello.sh" + }, + { + "name": "goodbye", + "description": "My second AZD command", + "entryPoint": "./scripts/goodbye.sh" + } + ] + } + \ No newline at end of file diff --git a/tools/azd-extension/lab-2/collect-user-info.sh b/tools/azd-extension/lab-2/collect-user-info.sh new file mode 100644 index 0000000..03f22ae --- /dev/null +++ b/tools/azd-extension/lab-2/collect-user-info.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Before performing any additional actions, store user info as an environment variable that +# can be used in subsequent steps. + +export USER_NAME=$(az account show --query user.name --output tsv) +echo "Current user:" $USER_NAME + +export AAD_USER_ID=$(az ad signed-in-user show --query id --output tsv) +echo "Object ID:" $AAD_USER_ID diff --git a/tools/azd-extension/lab-2/create-aca-env.sh b/tools/azd-extension/lab-2/create-aca-env.sh new file mode 100644 index 0000000..69a6ad6 --- /dev/null +++ b/tools/azd-extension/lab-2/create-aca-env.sh @@ -0,0 +1,67 @@ +#!/bin/bash +# This script creates an Azure Container Apps environment with a dedicated plan and a virtual network. +# It also creates a resource group and a virtual network with a subnet for the Azure Container Apps environment. +# The script uses the Azure CLI to create the resources and requires the user to be logged in to their Azure account. +# The script also requires the user to have the Azure CLI installed and configured on their machine. +# The script uses the `az` command to create the resources and requires the user to have the necessary permissions to create resources in their Azure account. +# The script uses the `openssl` command to generate a random unique ID for the resource group and virtual network names. +# The script uses the `az configure` command to set the default resource group for the Azure CLI commands. + +#source ../../azure-resource.profile + +UNIQUEID=$(openssl rand -hex 3) +APPNAME=petclinic +# RESOURCE_GROUP=rg-$APPNAME-$UNIQUEID +# LOCATION= + +if ! az group exists --name RESOURCE_GROUP; then + echo "Creating resource group [$RESOURCE_GROUP] in region [$LOCATION]..." + az group create -g $RESOURCE_GROUP -l $LOCATION +else + echo "Provisioning in resource group [$RESOURCE_GROUP]..." +fi + +az configure --default group=$RESOURCE_GROUP + +# +# Create VNET for Azure Container Apps Environment +# +VIRTUAL_NETWORK_NAME=vnet-$APPNAME-$UNIQUEID +az network vnet create \ + --resource-group $RESOURCE_GROUP \ + --name $VIRTUAL_NETWORK_NAME \ + --location $LOCATION \ + --address-prefix 10.1.0.0/16 + +ACA_SUBNET_CIDR=10.1.0.0/27 +az network vnet subnet create \ + --resource-group $RESOURCE_GROUP \ + --vnet-name $VIRTUAL_NETWORK_NAME \ + --address-prefixes $ACA_SUBNET_CIDR \ + --name aca-subnet \ + --delegations Microsoft.App/environments + +SUBNET_ID="$(az network vnet subnet show --resource-group $RESOURCE_GROUP --vnet-name $VIRTUAL_NETWORK_NAME --name aca-subnet --query "id" -o tsv)" +echo "Subnet ID: [$SUBNET_ID]" + +# +# Creating the service on an Azure Container Apps Dedicated plan using the workload profiles option. +# This plan gives you more advanced features than the alternative Azure Container Apps Consumption plan type +# +ACA_ENVIRONMENT=acalab-env-$APPNAME-$UNIQUEID + +# winty is to accomodate git bash on Windows +# Otherwise, SUBNET_ID will be appended with local drive path +# NO_PATHCOW is for git bash on Windows +export MSYS_NO_PATHCONV=1 + +az containerapp env create \ + -n $ACA_ENVIRONMENT \ + -g $RESOURCE_GROUP \ + --location $LOCATION \ + --enable-workload-profiles true \ + --infrastructure-subnet-resource-id "$SUBNET_ID" \ + --logs-destination none + +ACA_ENVIRONMENT_ID=$(az containerapp env show -n $ACA_ENVIRONMENT -g $RESOURCE_GROUP --query id -o tsv) + From b406e13abcab64199fec1e598f42a423ea03e9e9 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Sat, 8 Mar 2025 19:57:10 -0800 Subject: [PATCH 04/38] add create.mysql.sh --- tools/azd-extension/lab-2/create-mysql.sh | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 tools/azd-extension/lab-2/create-mysql.sh diff --git a/tools/azd-extension/lab-2/create-mysql.sh b/tools/azd-extension/lab-2/create-mysql.sh new file mode 100644 index 0000000..c2518b3 --- /dev/null +++ b/tools/azd-extension/lab-2/create-mysql.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +UNIQUEID=$(openssl rand -hex 3) +APPNAME=petclinic + +RESOURCE_GROUP=$(az group list --query "[?contains(name, 'petclinic')].{Name:name}[0]" -o tsv) + +# This script creates an Azure MySQL server and an Azure Container Registry (ACR) in a specified resource group. +MYSQL_SERVER_NAME=mysql-$APPNAME-$UNIQUEID +MYSQL_ADMIN_USERNAME=sqladmin +MYSQL_ADMIN_PASSWORD="5qVYxsoyaV9qJN" +DATABASE_NAME=petclinic + +az mysql flexible-server create \ + --admin-user "$MYSQL_ADMIN_USERNAME" \ + --admin-password "$MYSQL_ADMIN_PASSWORD" \ + --name "$MYSQL_SERVER_NAME" \ + --resource-group "$RESOURCE_GROUP" \ + --public-access none \ + --yes +az mysql flexible-server db create \ + --server-name $MYSQL_SERVER_NAME \ + --resource-group $RESOURCE_GROUP \ + -d $DATABASE_NAME + +# +# Allow public access to the MySQL server +# +az mysql flexible-server firewall-rule create \ + --rule-name allAzureIPs \ + --name $MYSQL_SERVER_NAME \ + --resource-group $RESOURCE_GROUP \ + --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0 From 6212a3006e16a98c88afdc7cf7f1fc5581e796ec Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Sat, 8 Mar 2025 20:56:35 -0800 Subject: [PATCH 05/38] Remove the dependencies of external parameters --- tools/azd-extension/lab-2/create-aca-env.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/azd-extension/lab-2/create-aca-env.sh b/tools/azd-extension/lab-2/create-aca-env.sh index 69a6ad6..f6d357a 100644 --- a/tools/azd-extension/lab-2/create-aca-env.sh +++ b/tools/azd-extension/lab-2/create-aca-env.sh @@ -11,13 +11,15 @@ UNIQUEID=$(openssl rand -hex 3) APPNAME=petclinic -# RESOURCE_GROUP=rg-$APPNAME-$UNIQUEID -# LOCATION= +RESOURCE_GROUP=$(az group list --query "[?contains(name, 'petclinic')].{Name:name}[0]" -o tsv) -if ! az group exists --name RESOURCE_GROUP; then +if [ -z "$RESOURCE_GROUP" ]; then + RESOURCE_GROUP=rg-$APPNAME-$UNIQUEID + LOCATION=$(random_element australiaeast brazilsouth eastasia eastus2 japaneast southindia swedencentral westus) echo "Creating resource group [$RESOURCE_GROUP] in region [$LOCATION]..." az group create -g $RESOURCE_GROUP -l $LOCATION else + LOCATION=$(az group show --name $RESOURCE_GROUP --query "location" -o tsv) echo "Provisioning in resource group [$RESOURCE_GROUP]..." fi From 6aeeeba149811d38c6205ee492fbdbaca8ab91b6 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Sat, 8 Mar 2025 21:34:37 -0800 Subject: [PATCH 06/38] new module creation --- .../lab-2/create-java-components.sh | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 tools/azd-extension/lab-2/create-java-components.sh diff --git a/tools/azd-extension/lab-2/create-java-components.sh b/tools/azd-extension/lab-2/create-java-components.sh new file mode 100644 index 0000000..d61f58d --- /dev/null +++ b/tools/azd-extension/lab-2/create-java-components.sh @@ -0,0 +1,64 @@ +#!/bin/bash +# +# Configure the config, discovery, and admin applications. These are available as built-in components of Azure Container Apps. + +APPNAME=petclinic +RESOURCE_GROUP=$(az group list --query "[?contains(name, 'petclinic')].{Name:name}[0]" -o tsv) +echo "Resource group: $RESOURCE_GROUP" +if [ -z "$RESOURCE_GROUP" ]; then + echo "Error: Resource group not found." + exit 1 +fi + +LOCATION=$(az group show --name $RESOURCE_GROUP --query "location" -o tsv) + +# Create the Spring Cloud Config Server Java component. You’ll need to pass the Git repo information you defined back +# in the Config repo step to correctly load your configuration information. +GIT_URI="https://github.com/Azure-Samples/java-on-aca.git" +SEARCH_PATH="config" +LABEL=main + +# Check if ACA environment name containing string "acalab-env" exists +ACA_ENVIRONMENT=$(az containerapp env list --resource-group $RESOURCE_GROUP --query "[?contains(name, 'acalab-env')].{Name:name}[0]" -o tsv) + +if [ -z "$ACA_ENVIRONMENT" ]; then + echo "Error: ACA environment containing 'acalab-env' not found." + exit 1 +fi + +JAVA_CONFIG_COMP_NAME=configserver +az containerapp env java-component config-server-for-spring create \ + --environment $ACA_ENVIRONMENT \ + --resource-group $RESOURCE_GROUP \ + --name $JAVA_CONFIG_COMP_NAME \ + --set-configuration spring.cloud.config.server.git.uri=$GIT_URI spring.cloud.config.server.git.search-paths=$SEARCH_PATH spring.cloud.config.server.git.default-label=$LABEL + +# Check the Spring Cloud Config Server Java component to confirm that it was successfully created. +CONFIG_SERVER_EXISTS=$(az containerapp env java-component config-server-for-spring show \ + --environment $ACA_ENVIRONMENT \ + --resource-group $RESOURCE_GROUP \ + --name $JAVA_CONFIG_COMP_NAME --query "name" -o tsv) + +if [ -z "$CONFIG_SERVER_EXISTS" ]; then + echo "Error: Config server was not successfully created." + exit 1 +fi + +# Create the Spring Cloud Eureka Server Java component. This will create a standard Eureka endpoint within +# the Container Apps environment. The Spring Petclinic workload will use this for discovery services. +JAVA_EUREKA_COMP_NAME=eureka +az containerapp env java-component eureka-server-for-spring create \ + --environment $ACA_ENVIRONMENT \ + --resource-group $RESOURCE_GROUP \ + --name $JAVA_EUREKA_COMP_NAME \ + --set-configuration eureka.server.response-cache-update-interval-ms=10000 + +# Create a new Spring Boot Admin application and bind it to the Eureka Server +JAVA_SBA_COMP_NAME=springbootadmin +az containerapp env java-component admin-for-spring create \ + --environment $ACA_ENVIRONMENT \ + --resource-group $RESOURCE_GROUP \ + --name $JAVA_SBA_COMP_NAME \ + --bind $JAVA_EUREKA_COMP_NAME \ + --min-replicas 1 \ + --max-replicas 1 From c2fe6488ecc9c9692a7a7a21824761269c1b197d Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Sat, 8 Mar 2025 21:56:44 -0800 Subject: [PATCH 07/38] create new module --- .../lab-2/create-container-registry.sh | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 tools/azd-extension/lab-2/create-container-registry.sh diff --git a/tools/azd-extension/lab-2/create-container-registry.sh b/tools/azd-extension/lab-2/create-container-registry.sh new file mode 100644 index 0000000..1c27947 --- /dev/null +++ b/tools/azd-extension/lab-2/create-container-registry.sh @@ -0,0 +1,56 @@ +#!/bin/bash +# +# Before deploying applications to the Azure Container Apps environment, you’ll need an Azure Container Registry instance that allows you to build and save your application container images. +# You’ll also need to allow your Container Apps environment to pull images from this new container registry. +# +# To give the Container Apps environment secure access to the container registry, we’ll create a user managed identity and assign it the required privileges to use the images stored in your Azure Container Registry. + +APPNAME=petclinic +RESOURCE_GROUP=$(az group list --query "[?contains(name, 'petclinic')].{Name:name}[0]" -o tsv) +echo "Resource group: $RESOURCE_GROUP" +if [ -z "$RESOURCE_GROUP" ]; then + echo "Error: Resource group not found." + exit 1 +fi + +# Check if a container registry containing the string $APPNAME already exists +EXISTING_ACR=$(az acr list --resource-group $RESOURCE_GROUP --query "[?contains(name, '$APPNAME')].{Name:name}[0]" -o tsv) + +UNIQUEID=$(openssl rand -hex 3) +if [ -n "$EXISTING_ACR" ]; then + echo "Container registry [$EXISTING_ACR] already exists. Skipping creation." + MYACR=$EXISTING_ACR +else + MYACR=acr$APPNAME$UNIQUEID + az acr create \ + -n $MYACR \ + -g $RESOURCE_GROUP \ + --sku Basic \ + --admin-enabled true +fi + +# Check if ACA environment name containing string "acalab-env" exists +ACA_ENVIRONMENT=$(az containerapp env list --resource-group $RESOURCE_GROUP --query "[?contains(name, 'acalab-env')].{Name:name}[0]" -o tsv) + +if [ -z "$ACA_ENVIRONMENT" ]; then + echo "Error: ACA environment containing 'acalab-env' not found." + exit 1 +fi + +# Disable path conversion for MSYS (Git Bash) +export MSYS_NO_PATHCONV=1 + +# Create the identity that your container apps will use. +APPS_IDENTITY=uid-petclinic-$UNIQUEID +az identity create --resource-group $RESOURCE_GROUP --name $APPS_IDENTITY --output json + +APPS_IDENTITY_ID=$(az identity show --resource-group $RESOURCE_GROUP --name $APPS_IDENTITY --query id --output tsv) +APPS_IDENTITY_SP_ID=$(az identity show --resource-group $RESOURCE_GROUP --name $APPS_IDENTITY --query principalId --output tsv) + +echo "Assign the user identity to your Azure Container Apps environment." +az containerapp env identity assign -g $RESOURCE_GROUP -n $ACA_ENVIRONMENT --user-assigned $APPS_IDENTITY_ID + +# Grant the identity with the necessary privileges to pull images from the container registry. +ACR_ID=$(az acr show -n $MYACR -g $RESOURCE_GROUP --query id -o tsv) +az role assignment create --assignee $APPS_IDENTITY_SP_ID --scope $ACR_ID --role acrpull + From 324975107b740dd739e3068e7b93eea9bbafabce Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Mon, 10 Mar 2025 10:46:24 -0700 Subject: [PATCH 08/38] Remove unused variable --- tools/azd-extension/lab-2/create-java-components.sh | 2 -- tools/azd-extension/lab-2/deploy-component-apps.sh | 6 ++++++ 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 tools/azd-extension/lab-2/deploy-component-apps.sh diff --git a/tools/azd-extension/lab-2/create-java-components.sh b/tools/azd-extension/lab-2/create-java-components.sh index d61f58d..3817937 100644 --- a/tools/azd-extension/lab-2/create-java-components.sh +++ b/tools/azd-extension/lab-2/create-java-components.sh @@ -10,8 +10,6 @@ if [ -z "$RESOURCE_GROUP" ]; then exit 1 fi -LOCATION=$(az group show --name $RESOURCE_GROUP --query "location" -o tsv) - # Create the Spring Cloud Config Server Java component. You’ll need to pass the Git repo information you defined back # in the Config repo step to correctly load your configuration information. GIT_URI="https://github.com/Azure-Samples/java-on-aca.git" diff --git a/tools/azd-extension/lab-2/deploy-component-apps.sh b/tools/azd-extension/lab-2/deploy-component-apps.sh new file mode 100644 index 0000000..f82f56e --- /dev/null +++ b/tools/azd-extension/lab-2/deploy-component-apps.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +# Get the application code from public upstream repo, and then build the applications. +cd ../../../spring-petclinic-microservices +git submodule update --init +mvn clean package -DskipTests \ No newline at end of file From 29df2688aae6a59279c00f4660ba95bdbb28097f Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Mon, 10 Mar 2025 11:50:10 -0700 Subject: [PATCH 09/38] Update azd json with steps in lab2 --- tools/azd-extension/java-on-ai-azd.json | 34 ++++++++++++++++++++----- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/tools/azd-extension/java-on-ai-azd.json b/tools/azd-extension/java-on-ai-azd.json index a85352b..f5b0a2d 100644 --- a/tools/azd-extension/java-on-ai-azd.json +++ b/tools/azd-extension/java-on-ai-azd.json @@ -6,15 +6,35 @@ "publisher": "Pete Tian", "commands": [ { - "name": "hello", - "description": "My first AZD command", - "entryPoint": "./scripts/hello.sh" + "name": "collecte user information", + "description": "Before performing any additional actions, you’ll need to store your user info as an environment variable that you can use in subsequent steps.", + "entryPoint": "./lab2/collect-user-info.sh" }, { - "name": "goodbye", - "description": "My second AZD command", - "entryPoint": "./scripts/goodbye.sh" - } + "name": "Create an Azure Container Apps environment", + "description": "With your user information stored in environment variables, you’re ready to begin the first step in the deployment: creating an Azure Container Apps instance.", + "entryPoint": "./lab-2/create-aca-env.sh" + }, + { + "name": "Create an Azure Database for MySQL instance", + "description": " create an Azure Database for MySQL - Flexible Server–hosted database.", + "entryPoint": "./lab-2/create-mysql.sh" + }, + { + "name": "Set up a configuration repository", + "description": "set up the application configuration settings that allow your Spring Boot application to connect with the database.", + "entryPoint": "./lab-2/create-container-registry.sh" + }, + { + "name": "Create the Java components", + "description": "configure the config, discovery, and admin applications.", + "entryPoint": "./lab-2/create-java-components.sh" + }, + { + "name": "Deploy the component applications to Azure Container Apps", + "description": "deploy the workload’s component applications to Azure.", + "entryPoint": "./lab-2/deploy-component-apps.sh" + } ] } \ No newline at end of file From fa60784a0751e40866a7e69f28f5e522b293f058 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Mon, 10 Mar 2025 14:57:41 -0700 Subject: [PATCH 10/38] create docker images for microservices --- .../lab-2/deploy-component-apps.sh | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tools/azd-extension/lab-2/deploy-component-apps.sh b/tools/azd-extension/lab-2/deploy-component-apps.sh index f82f56e..342935c 100644 --- a/tools/azd-extension/lab-2/deploy-component-apps.sh +++ b/tools/azd-extension/lab-2/deploy-component-apps.sh @@ -3,4 +3,20 @@ # Get the application code from public upstream repo, and then build the applications. cd ../../../spring-petclinic-microservices git submodule update --init -mvn clean package -DskipTests \ No newline at end of file +mvn clean package -DskipTests + +# Build the Docker image using the Dockerfile + +DOCKERFILE="../tools/Dockerfile" +if [ ! -f $DOCKERFILE ]; then + echo "Dockerfile not found at $DOCKERFILE" + exit 1 +fi + +docker build -t petclinic-admin-server:latest -f $DOCKERFILE ./spring-petclinic-admin-server +docker build -t petclinic-api-gateway:latest -f $DOCKERFILE ./spring-petclinic-api-gateway +docker build -t petclinic-config-server:latest -f $DOCKERFILE ./spring-petclinic-config-server +docker build -t petclinic-customers-service:latest -f $DOCKERFILE ./spring-petclinic-customers-service +docker build -t petclinic-discovery-server:latest -f $DOCKERFILE ./spring-petclinic-discovery-server +docker build -t petclinic-vets-service:latest -f $DOCKERFILE ./spring-petclinic-vets-service +docker build -t petclinic-visits-service:latest -f $DOCKERFILE ./spring-petclinic-visits-service From 7afe1835a0c5b3dcf3474a3e677343bbeb24b801 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Mon, 10 Mar 2025 19:01:25 -0700 Subject: [PATCH 11/38] refactory --- tools/azd-extension/lab-2/create-aca-env.sh | 28 +++++++++++++++------ 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/tools/azd-extension/lab-2/create-aca-env.sh b/tools/azd-extension/lab-2/create-aca-env.sh index f6d357a..450b682 100644 --- a/tools/azd-extension/lab-2/create-aca-env.sh +++ b/tools/azd-extension/lab-2/create-aca-env.sh @@ -7,11 +7,9 @@ # The script uses the `openssl` command to generate a random unique ID for the resource group and virtual network names. # The script uses the `az configure` command to set the default resource group for the Azure CLI commands. -#source ../../azure-resource.profile - UNIQUEID=$(openssl rand -hex 3) -APPNAME=petclinic -RESOURCE_GROUP=$(az group list --query "[?contains(name, 'petclinic')].{Name:name}[0]" -o tsv) +export APPNAME=petclinic +export RESOURCE_GROUP=$(az group list --query "[?contains(name, 'petclinic')].{Name:name}[0]" -o tsv) if [ -z "$RESOURCE_GROUP" ]; then RESOURCE_GROUP=rg-$APPNAME-$UNIQUEID @@ -50,9 +48,9 @@ echo "Subnet ID: [$SUBNET_ID]" # Creating the service on an Azure Container Apps Dedicated plan using the workload profiles option. # This plan gives you more advanced features than the alternative Azure Container Apps Consumption plan type # -ACA_ENVIRONMENT=acalab-env-$APPNAME-$UNIQUEID +export ACA_ENVIRONMENT=acalab-env-$APPNAME-$UNIQUEID -# winty is to accomodate git bash on Windows +# winty is to accommodate git bash on Windows # Otherwise, SUBNET_ID will be appended with local drive path # NO_PATHCOW is for git bash on Windows export MSYS_NO_PATHCONV=1 @@ -65,5 +63,21 @@ az containerapp env create \ --infrastructure-subnet-resource-id "$SUBNET_ID" \ --logs-destination none -ACA_ENVIRONMENT_ID=$(az containerapp env show -n $ACA_ENVIRONMENT -g $RESOURCE_GROUP --query id -o tsv) +export ACA_ENVIRONMENT_ID=$(az containerapp env show -n $ACA_ENVIRONMENT -g $RESOURCE_GROUP --query id -o tsv) + +# Write variables to the azure-resource.profile +{ + echo "RESOURCE_GROUP=$RESOURCE_GROUP" + echo "UNIQUEID=$UNIQUEID" + echo "APPNAME=$APPNAME" + echo "ACA_ENVIRONMENT=$ACA_ENVIRONMENT" + echo "ACA_ENVIRONMENT_ID=$ACA_ENVIRONMENT_ID" +} > ./azure-resource.profile +# Verify that the variables.sh file is created properly +if [ -f ./azure-resource.profile ]; then + echo "azure-resource.profile file created successfully." +else + echo "Error: azure-resource.profile file not created." + exit 1 +fi From 5cf4a91ab983efcd0378b034edde5f7e06c03929 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Mon, 10 Mar 2025 19:11:41 -0700 Subject: [PATCH 12/38] Refactory --- tools/azd-extension/lab-2/create-mysql.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tools/azd-extension/lab-2/create-mysql.sh b/tools/azd-extension/lab-2/create-mysql.sh index c2518b3..c40fadd 100644 --- a/tools/azd-extension/lab-2/create-mysql.sh +++ b/tools/azd-extension/lab-2/create-mysql.sh @@ -1,9 +1,6 @@ #!/bin/bash -UNIQUEID=$(openssl rand -hex 3) -APPNAME=petclinic - -RESOURCE_GROUP=$(az group list --query "[?contains(name, 'petclinic')].{Name:name}[0]" -o tsv) +source ./azure-resource.profile # This script creates an Azure MySQL server and an Azure Container Registry (ACR) in a specified resource group. MYSQL_SERVER_NAME=mysql-$APPNAME-$UNIQUEID From ae3fac9104b1acafe35cf1a4e21ee9525c6f41ca Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Tue, 11 Mar 2025 13:07:39 -0700 Subject: [PATCH 13/38] Refactor: move azure-resource.profile to ../config sharing with other labs --- tools/azd-extension/java-on-ai-azd.json | 31 ++++++++++----------- tools/azd-extension/lab-2/create-aca-env.sh | 12 ++++++-- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/tools/azd-extension/java-on-ai-azd.json b/tools/azd-extension/java-on-ai-azd.json index f5b0a2d..3c714ba 100644 --- a/tools/azd-extension/java-on-ai-azd.json +++ b/tools/azd-extension/java-on-ai-azd.json @@ -5,36 +5,35 @@ "description": "Java on AI AZD extension with bash", "publisher": "Pete Tian", "commands": [ - { - "name": "collecte user information", - "description": "Before performing any additional actions, you’ll need to store your user info as an environment variable that you can use in subsequent steps.", - "entryPoint": "./lab2/collect-user-info.sh" - }, - { - "name": "Create an Azure Container Apps environment", - "description": "With your user information stored in environment variables, you’re ready to begin the first step in the deployment: creating an Azure Container Apps instance.", - "entryPoint": "./lab-2/create-aca-env.sh" - }, + { + "name": "collecte user information", + "description": "Before performing any additional actions, you’ll need to store your user info as an environment variable that you can use in subsequent steps.", + "entryPoint": "./lab2/collect-user-info.sh" + }, + { + "name": "Create an Azure Container Apps environment", + "description": "With your user information stored in environment variables, you’re ready to begin the first step in the deployment: creating an Azure Container Apps instance.", + "entryPoint": "./lab-2/create-aca-env.sh" + }, { "name": "Create an Azure Database for MySQL instance", - "description": " create an Azure Database for MySQL - Flexible Server–hosted database.", + "description": "Create an Azure Database for MySQL - Flexible Server–hosted database.", "entryPoint": "./lab-2/create-mysql.sh" }, { "name": "Set up a configuration repository", - "description": "set up the application configuration settings that allow your Spring Boot application to connect with the database.", + "description": "Set up the application configuration settings that allow your Spring Boot application to connect with the database.", "entryPoint": "./lab-2/create-container-registry.sh" }, { "name": "Create the Java components", - "description": "configure the config, discovery, and admin applications.", + "description": "Configure the config, discovery, and admin applications.", "entryPoint": "./lab-2/create-java-components.sh" }, { "name": "Deploy the component applications to Azure Container Apps", - "description": "deploy the workload’s component applications to Azure.", + "description": "Deploy the workload’s component applications to Azure.", "entryPoint": "./lab-2/deploy-component-apps.sh" } ] - } - \ No newline at end of file +} \ No newline at end of file diff --git a/tools/azd-extension/lab-2/create-aca-env.sh b/tools/azd-extension/lab-2/create-aca-env.sh index 450b682..5516315 100644 --- a/tools/azd-extension/lab-2/create-aca-env.sh +++ b/tools/azd-extension/lab-2/create-aca-env.sh @@ -50,6 +50,12 @@ echo "Subnet ID: [$SUBNET_ID]" # export ACA_ENVIRONMENT=acalab-env-$APPNAME-$UNIQUEID +# If folder ../config does not exist, create it +if [ ! -d "../config" ]; then + mkdir -p ../config +fi +AZURE_CONFIG_FILE="../config/azure-resource.profile" + # winty is to accommodate git bash on Windows # Otherwise, SUBNET_ID will be appended with local drive path # NO_PATHCOW is for git bash on Windows @@ -72,10 +78,10 @@ export ACA_ENVIRONMENT_ID=$(az containerapp env show -n $ACA_ENVIRONMENT -g $RES echo "APPNAME=$APPNAME" echo "ACA_ENVIRONMENT=$ACA_ENVIRONMENT" echo "ACA_ENVIRONMENT_ID=$ACA_ENVIRONMENT_ID" -} > ./azure-resource.profile +} > $AZURE_CONFIG_FILE -# Verify that the variables.sh file is created properly -if [ -f ./azure-resource.profile ]; then +# Verify that the azure-resource.profile file is created properly +if [ -f $AZURE_CONFIG_FILE ]; then echo "azure-resource.profile file created successfully." else echo "Error: azure-resource.profile file not created." From 4f8ab79515466c7521d5e4493b18c712a21e9a8e Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Tue, 11 Mar 2025 13:32:02 -0700 Subject: [PATCH 14/38] Refactor: source the config file created by the previous step. Add application config yaml --- tools/azd-extension/lab-2/create-mysql.sh | 32 +++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/tools/azd-extension/lab-2/create-mysql.sh b/tools/azd-extension/lab-2/create-mysql.sh index c40fadd..56e2fae 100644 --- a/tools/azd-extension/lab-2/create-mysql.sh +++ b/tools/azd-extension/lab-2/create-mysql.sh @@ -1,11 +1,14 @@ #!/bin/bash -source ./azure-resource.profile +AZURE_CONFIG_FILE="../config/azure-resource.profile" +source $AZURE_CONFIG_FILE + +APPLICATION_CONFIG_FILE="../config/application-mysql.yml" # This script creates an Azure MySQL server and an Azure Container Registry (ACR) in a specified resource group. MYSQL_SERVER_NAME=mysql-$APPNAME-$UNIQUEID MYSQL_ADMIN_USERNAME=sqladmin -MYSQL_ADMIN_PASSWORD="5qVYxsoyaV9qJN" +MYSQL_ADMIN_PASSWORD=$(openssl rand -hex 12) DATABASE_NAME=petclinic az mysql flexible-server create \ @@ -28,3 +31,28 @@ az mysql flexible-server firewall-rule create \ --name $MYSQL_SERVER_NAME \ --resource-group $RESOURCE_GROUP \ --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0 + +# Set up a configuration repository +# set up the application configuration settings that allow Spring Boot applications to connect with the database. +echo " +spring: + datasource: + url: jdbc:mysql://${MYSQL_SERVER_NAME}.mysql.database.azure.com:3306/petclinic?useSSL=true + username: ${MYSQL_ADMIN_USERNAME} + password: ${MYSQL_ADMIN_PASSWORD} + sql: + init: + schema-locations: classpath*:db/mysql/schema.sql + data-locations: classpath*:db/mysql/data.sql + mode: ALWAYS +" > $APPLICATION_CONFIG_FILE + +export GIT_URI="https://github.com/Azure-Samples/java-on-aca.git" +export SEARCH_PATH="config" +export LABEL=main + +{ + echo "GIT_URI=https://github.com/Azure-Samples/java-on-aca.git" + echo "SEARCH_PATH=config" + echo "LABEL=main" +} >> $AZURE_CONFIG_FILE From 188d693b9e38be274f9c50899b22d86cb8577b6d Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Tue, 11 Mar 2025 14:03:36 -0700 Subject: [PATCH 15/38] Refactor --- .../lab-2/create-java-components.sh | 21 ++++--------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/tools/azd-extension/lab-2/create-java-components.sh b/tools/azd-extension/lab-2/create-java-components.sh index 3817937..8e7a9b9 100644 --- a/tools/azd-extension/lab-2/create-java-components.sh +++ b/tools/azd-extension/lab-2/create-java-components.sh @@ -2,25 +2,12 @@ # # Configure the config, discovery, and admin applications. These are available as built-in components of Azure Container Apps. -APPNAME=petclinic -RESOURCE_GROUP=$(az group list --query "[?contains(name, 'petclinic')].{Name:name}[0]" -o tsv) -echo "Resource group: $RESOURCE_GROUP" -if [ -z "$RESOURCE_GROUP" ]; then - echo "Error: Resource group not found." - exit 1 -fi - -# Create the Spring Cloud Config Server Java component. You’ll need to pass the Git repo information you defined back -# in the Config repo step to correctly load your configuration information. -GIT_URI="https://github.com/Azure-Samples/java-on-aca.git" -SEARCH_PATH="config" -LABEL=main - -# Check if ACA environment name containing string "acalab-env" exists -ACA_ENVIRONMENT=$(az containerapp env list --resource-group $RESOURCE_GROUP --query "[?contains(name, 'acalab-env')].{Name:name}[0]" -o tsv) +AZURE_CONFIG_FILE="../config/azure-resource.profile" +source $AZURE_CONFIG_FILE +# Check if ACA environment name exists if [ -z "$ACA_ENVIRONMENT" ]; then - echo "Error: ACA environment containing 'acalab-env' not found." + echo "Error: ACA environment not found." exit 1 fi From 94ff0ef8bd8e1370662e88c5abb318729c36fbb8 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Tue, 11 Mar 2025 14:19:15 -0700 Subject: [PATCH 16/38] Refactor: use common config file --- .../lab-2/create-container-registry.sh | 58 ++++++++++++------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/tools/azd-extension/lab-2/create-container-registry.sh b/tools/azd-extension/lab-2/create-container-registry.sh index 1c27947..b318169 100644 --- a/tools/azd-extension/lab-2/create-container-registry.sh +++ b/tools/azd-extension/lab-2/create-container-registry.sh @@ -1,27 +1,31 @@ #!/bin/bash # -# Before deploying applications to the Azure Container Apps environment, you’ll need an Azure Container Registry instance that allows you to build and save your application container images. -# You’ll also need to allow your Container Apps environment to pull images from this new container registry. +# Before deploying applications to the Azure Container Apps environment, an Azure Container Registry instance is needed that allows to build and save application container images. +# Allow the Container Apps environment to pull images from this new container registry. # -# To give the Container Apps environment secure access to the container registry, we’ll create a user managed identity and assign it the required privileges to use the images stored in your Azure Container Registry. +# This script creates an Azure Container Registry (ACR) and a user managed identity for the Azure Container Apps environment. +# The script also assigns the user managed identity to the ACR and grants it the necessary permissions to pull images from the registry. +# The script uses the Azure CLI to create the ACR and user managed identity, and to assign the identity to the ACR. +# The script also checks if the ACR and user managed identity already exist, and skips their creation if they do. +# The script also exports the ACR and user managed identity names and IDs as environment variables, and appends them to the Azure configuration file. +# The script also checks if the Azure Container Apps environment name exists, and exits with an error message if it does not. +# The script also disables path conversion for MSYS (Git Bash) to avoid issues with file paths. + + +AZURE_CONFIG_FILE="../config/azure-resource.profile" +source $AZURE_CONFIG_FILE APPNAME=petclinic -RESOURCE_GROUP=$(az group list --query "[?contains(name, 'petclinic')].{Name:name}[0]" -o tsv) -echo "Resource group: $RESOURCE_GROUP" -if [ -z "$RESOURCE_GROUP" ]; then - echo "Error: Resource group not found." - exit 1 -fi # Check if a container registry containing the string $APPNAME already exists -EXISTING_ACR=$(az acr list --resource-group $RESOURCE_GROUP --query "[?contains(name, '$APPNAME')].{Name:name}[0]" -o tsv) +MYACR=$(az acr list --resource-group $RESOURCE_GROUP --query "[?contains(name, '$APPNAME')].{Name:name}[0]" -o tsv) -UNIQUEID=$(openssl rand -hex 3) -if [ -n "$EXISTING_ACR" ]; then - echo "Container registry [$EXISTING_ACR] already exists. Skipping creation." - MYACR=$EXISTING_ACR +CR_UNIQUEID=$(openssl rand -hex 3) +if [ -n "$MYACR" ]; then + echo "Container registry [$MYACR] already exists. Skipping creation." else - MYACR=acr$APPNAME$UNIQUEID + MYACR=acr$APPNAME$CR_UNIQUEID + echo "Creating new container registry [$MYACR]..." az acr create \ -n $MYACR \ -g $RESOURCE_GROUP \ @@ -30,18 +34,16 @@ else fi # Check if ACA environment name containing string "acalab-env" exists -ACA_ENVIRONMENT=$(az containerapp env list --resource-group $RESOURCE_GROUP --query "[?contains(name, 'acalab-env')].{Name:name}[0]" -o tsv) - if [ -z "$ACA_ENVIRONMENT" ]; then - echo "Error: ACA environment containing 'acalab-env' not found." + echo "Error: ACA environment [$ACA_ENVIRONMENT] not found." exit 1 fi # Disable path conversion for MSYS (Git Bash) export MSYS_NO_PATHCONV=1 -# Create the identity that your container apps will use. -APPS_IDENTITY=uid-petclinic-$UNIQUEID +# Create the identity that the container apps will use. +export APPS_IDENTITY=uid-petclinic-$CR_UNIQUEID az identity create --resource-group $RESOURCE_GROUP --name $APPS_IDENTITY --output json APPS_IDENTITY_ID=$(az identity show --resource-group $RESOURCE_GROUP --name $APPS_IDENTITY --query id --output tsv) @@ -51,6 +53,20 @@ echo "Assign the user identity to your Azure Container Apps environment." az containerapp env identity assign -g $RESOURCE_GROUP -n $ACA_ENVIRONMENT --user-assigned $APPS_IDENTITY_ID # Grant the identity with the necessary privileges to pull images from the container registry. -ACR_ID=$(az acr show -n $MYACR -g $RESOURCE_GROUP --query id -o tsv) +export ACR_ID=$(az acr show -n $MYACR -g $RESOURCE_GROUP --query id -o tsv) az role assignment create --assignee $APPS_IDENTITY_SP_ID --scope $ACR_ID --role acrpull +# Export the variables +export MYACR +export APPS_IDENTITY +export APPS_IDENTITY_ID +export APPS_IDENTITY_SP_ID + +# Append the variables to the AZURE_CONFIG_FILE +{ + echo "MYACR=$MYACR" + echo "APPS_IDENTITY=$APPS_IDENTITY" + echo "APPS_IDENTITY_ID=$APPS_IDENTITY_ID" + echo "APPS_IDENTITY_SP_ID=$APPS_IDENTITY_SP_ID" + echo "ACR_ID=$ACR_ID" +} >> $AZURE_CONFIG_FILE \ No newline at end of file From 27b345a90bad3d4789a6fa85903e9d17e915ece8 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Tue, 11 Mar 2025 17:32:44 -0700 Subject: [PATCH 17/38] Write created components to config file --- .../azd-extension/lab-2/create-java-components.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tools/azd-extension/lab-2/create-java-components.sh b/tools/azd-extension/lab-2/create-java-components.sh index 8e7a9b9..cf51836 100644 --- a/tools/azd-extension/lab-2/create-java-components.sh +++ b/tools/azd-extension/lab-2/create-java-components.sh @@ -47,3 +47,17 @@ az containerapp env java-component admin-for-spring create \ --bind $JAVA_EUREKA_COMP_NAME \ --min-replicas 1 \ --max-replicas 1 + +# Append the JAVA_EUREKA_COMP_NAME and JAVA_SBA_COMP_NAME to the AZURE_CONFIG_FILE +{ + echo "JAVA_EUREKA_COMP_NAME=$JAVA_EUREKA_COMP_NAME" + echo "JAVA_SBA_COMP_NAME=$JAVA_SBA_COMP_NAME" +} >> $AZURE_CONFIG_FILE + +# Verify that the variables are appended to the azure-resource.profile file +if grep -q "JAVA_EUREKA_COMP_NAME" $AZURE_CONFIG_FILE && grep -q "JAVA_SBA_COMP_NAME" $AZURE_CONFIG_FILE; then + echo "Variables appended to azure-resource.profile file successfully." +else + echo "Error: Variables JAVA_EUREKA_COMP_NAME JAVA_SBA_COMP_NAME not appended to azure-resource.profile file." + exit 1 +fi \ No newline at end of file From 766ca0a86dd624e58d76f69b18375379aa4c6b8e Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Tue, 11 Mar 2025 17:38:55 -0700 Subject: [PATCH 18/38] add new module --- .../lab-2/deploy-component-apps.sh | 51 +++++++++++++++---- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/tools/azd-extension/lab-2/deploy-component-apps.sh b/tools/azd-extension/lab-2/deploy-component-apps.sh index 342935c..2fc15b7 100644 --- a/tools/azd-extension/lab-2/deploy-component-apps.sh +++ b/tools/azd-extension/lab-2/deploy-component-apps.sh @@ -1,22 +1,55 @@ #!/bin/bash +AZURE_CONFIG_FILE="../config/azure-resource.profile" +source $AZURE_CONFIG_FILE + # Get the application code from public upstream repo, and then build the applications. cd ../../../spring-petclinic-microservices git submodule update --init mvn clean package -DskipTests # Build the Docker image using the Dockerfile - DOCKERFILE="../tools/Dockerfile" if [ ! -f $DOCKERFILE ]; then - echo "Dockerfile not found at $DOCKERFILE" + echo "$DOCKERFILE not found " + exit 1 +fi + +# if ACA environment does not exist, exit +if [ -z "$ACA_ENVIRONMENT" ]; then + echo "Error: ACA environment [$ACA_ENVIRONMENT] not found." exit 1 fi -docker build -t petclinic-admin-server:latest -f $DOCKERFILE ./spring-petclinic-admin-server -docker build -t petclinic-api-gateway:latest -f $DOCKERFILE ./spring-petclinic-api-gateway -docker build -t petclinic-config-server:latest -f $DOCKERFILE ./spring-petclinic-config-server -docker build -t petclinic-customers-service:latest -f $DOCKERFILE ./spring-petclinic-customers-service -docker build -t petclinic-discovery-server:latest -f $DOCKERFILE ./spring-petclinic-discovery-server -docker build -t petclinic-vets-service:latest -f $DOCKERFILE ./spring-petclinic-vets-service -docker build -t petclinic-visits-service:latest -f $DOCKERFILE ./spring-petclinic-visits-service +APP_NAME="api-gateway" +cp -f ../tools/Dockerfile ./spring-petclinic-$APP_NAME/Dockerfile + +# Disable path conversion for MSYS (Git Bash) +export MSYS_NO_PATHCONV=1 + +echo "az containerapp create \ + --name $APP_NAME \ + --resource-group $RESOURCE_GROUP \ + --environment $ACA_ENVIRONMENT \ + --source ./spring-petclinic-$APP_NAME \ + --registry-server $MYACR.azurecr.io \ + --registry-identity $APPS_IDENTITY_ID \ + --ingress external \ + --target-port 8080 \ + --min-replicas 1 \ + --bind $JAVA_CONFIG_COMP_NAME $JAVA_EUREKA_COMP_NAME \ + --runtime java" + +az containerapp create \ + --name $APP_NAME \ + --resource-group $RESOURCE_GROUP \ + --environment $ACA_ENVIRONMENT \ + --source ./spring-petclinic-$APP_NAME \ + --registry-server $MYACR.azurecr.io \ + --registry-identity $APPS_IDENTITY_ID \ + --ingress external \ + --target-port 8080 \ + --min-replicas 1 \ + --bind $JAVA_CONFIG_COMP_NAME $JAVA_EUREKA_COMP_NAME \ + --runtime java + From 901cf04c15be3a25334387ceda761697ff1f11c2 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Wed, 12 Mar 2025 12:58:15 -0700 Subject: [PATCH 19/38] update .gitignore --- .gitignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 650c37f..b8d7d0e 100644 --- a/.gitignore +++ b/.gitignore @@ -432,4 +432,8 @@ FodyWeavers.xsd *.msp # JetBrains Rider -*.sln.iml \ No newline at end of file +*.sln.iml +tools/azd-extension/lab-2/azure-resource.profile +tools/azd-extension/config/azure-resource.profile +tools/azd-extension/config/application-mysql.yml +spring-petclinic-microservices \ No newline at end of file From 1dfd41670d8b08b27945a077b3a90ec30630ae00 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Wed, 12 Mar 2025 12:59:19 -0700 Subject: [PATCH 20/38] update .gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index b8d7d0e..3bc9b7e 100644 --- a/.gitignore +++ b/.gitignore @@ -436,4 +436,4 @@ FodyWeavers.xsd tools/azd-extension/lab-2/azure-resource.profile tools/azd-extension/config/azure-resource.profile tools/azd-extension/config/application-mysql.yml -spring-petclinic-microservices \ No newline at end of file +spring-petclinic-microservices/* \ No newline at end of file From 87d939adea18a21b8997d6672e804c44721e02f2 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Wed, 12 Mar 2025 16:10:39 -0700 Subject: [PATCH 21/38] export LOCATION --- tools/azd-extension/lab-2/create-aca-env.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/azd-extension/lab-2/create-aca-env.sh b/tools/azd-extension/lab-2/create-aca-env.sh index 5516315..3b28fb6 100644 --- a/tools/azd-extension/lab-2/create-aca-env.sh +++ b/tools/azd-extension/lab-2/create-aca-env.sh @@ -74,6 +74,7 @@ export ACA_ENVIRONMENT_ID=$(az containerapp env show -n $ACA_ENVIRONMENT -g $RES # Write variables to the azure-resource.profile { echo "RESOURCE_GROUP=$RESOURCE_GROUP" + echo "LOCATION=$LOCATION" echo "UNIQUEID=$UNIQUEID" echo "APPNAME=$APPNAME" echo "ACA_ENVIRONMENT=$ACA_ENVIRONMENT" From 7e2780b9cebd29efb1f38ce396d7abc705623732 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Wed, 12 Mar 2025 19:35:44 -0700 Subject: [PATCH 22/38] add lab-3 --- .../lab-3/create-openai-service.sh | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 tools/azd-extension/lab-3/create-openai-service.sh diff --git a/tools/azd-extension/lab-3/create-openai-service.sh b/tools/azd-extension/lab-3/create-openai-service.sh new file mode 100644 index 0000000..02c8704 --- /dev/null +++ b/tools/azd-extension/lab-3/create-openai-service.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +AZURE_CONFIG_FILE="../config/azure-resource.profile" +source $AZURE_CONFIG_FILE + +AI_LOCATION=$LOCATION + +# Create an Azure OpenAI account +OPEN_AI_SERVICE_NAME=open-ai-account-$UNIQUEID +az cognitiveservices account create \ + --resource-group $RESOURCE_GROUP \ + --name $OPEN_AI_SERVICE_NAME \ + --location $AI_LOCATION \ + --kind OpenAI \ + --sku s0 \ + --custom-domain $OPEN_AI_SERVICE_NAME + +# Check if the OpenAI account was created successfully +AI_ID=$(az cognitiveservices account show --resource-group $RESOURCE_GROUP --name $OPEN_AI_SERVICE_NAME -o tsv --query id 2>/dev/null) +if [[ -n $AI_ID ]]; then + echo -e "${GREEN}INFO:${NC} OpenAI instance $OPEN_AI_SERVICE_NAME already exists" +else + echo -e "${YELLOW}INFO:${NC} Creating OpenAI instance $OPEN_AI_SERVICE_NAME in region $AI_LOCATION ..." +fi + +# deploy the language +az cognitiveservices account deployment create \ + --resource-group $RESOURCE_GROUP \ + --name $OPEN_AI_SERVICE_NAME \ + --deployment-name gpt-4o \ + --model-name gpt-4o \ + --model-version 2024-08-06 \ + --model-format OpenAI \ + --sku-name "GlobalStandard" \ + --sku-capacity 10 + +echo "OPEN_AI_SERVICE_NAME=$OPEN_AI_SERVICE_NAME" >> $AZURE_CONFIG_FILE \ No newline at end of file From dc6a7eda0d7ca1aac5a87e563c85310f488d97b8 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Wed, 12 Mar 2025 20:16:57 -0700 Subject: [PATCH 23/38] create main script as entry point --- tools/azd-extension/lab-2/lab-2-main.sh | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tools/azd-extension/lab-2/lab-2-main.sh diff --git a/tools/azd-extension/lab-2/lab-2-main.sh b/tools/azd-extension/lab-2/lab-2-main.sh new file mode 100644 index 0000000..d40535c --- /dev/null +++ b/tools/azd-extension/lab-2/lab-2-main.sh @@ -0,0 +1,8 @@ +# !/bin/bash + +./collect-user-info.sh +./create-aca-env.sh +./create-mysql.sh +./create-container-registry.sh +./create-java-components.sh +./deploy-component-apps.sh \ No newline at end of file From 058f3506a90e8d9deb4bfb44f20da2da9dc02c02 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Wed, 12 Mar 2025 20:46:29 -0700 Subject: [PATCH 24/38] add script for lab 3 --- tools/azd-extension/lab-3/create-openai-service.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/azd-extension/lab-3/create-openai-service.sh b/tools/azd-extension/lab-3/create-openai-service.sh index 02c8704..24ed5c4 100644 --- a/tools/azd-extension/lab-3/create-openai-service.sh +++ b/tools/azd-extension/lab-3/create-openai-service.sh @@ -23,7 +23,7 @@ else echo -e "${YELLOW}INFO:${NC} Creating OpenAI instance $OPEN_AI_SERVICE_NAME in region $AI_LOCATION ..." fi -# deploy the language +# deploy the language model az cognitiveservices account deployment create \ --resource-group $RESOURCE_GROUP \ --name $OPEN_AI_SERVICE_NAME \ From b210c9fe4c6262588a0117bc3ecf78e9744f684b Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Thu, 13 Mar 2025 10:47:39 -0700 Subject: [PATCH 25/38] bug fixing --- tools/azd-extension/lab-2/lab-2-main.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/azd-extension/lab-2/lab-2-main.sh b/tools/azd-extension/lab-2/lab-2-main.sh index d40535c..336a01c 100644 --- a/tools/azd-extension/lab-2/lab-2-main.sh +++ b/tools/azd-extension/lab-2/lab-2-main.sh @@ -1,8 +1,8 @@ -# !/bin/bash +#!/bin/bash ./collect-user-info.sh ./create-aca-env.sh -./create-mysql.sh -./create-container-registry.sh -./create-java-components.sh -./deploy-component-apps.sh \ No newline at end of file +# ./create-mysql.sh +# ./create-container-registry.sh +# ./create-java-components.sh +# ./deploy-component-apps.sh \ No newline at end of file From fa209e05e2942f8971dc0489f0ab26347b872db6 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Thu, 13 Mar 2025 10:48:18 -0700 Subject: [PATCH 26/38] bug fixing --- tools/azd-extension/lab-2/lab-2-main.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/azd-extension/lab-2/lab-2-main.sh b/tools/azd-extension/lab-2/lab-2-main.sh index 336a01c..4e3cb89 100644 --- a/tools/azd-extension/lab-2/lab-2-main.sh +++ b/tools/azd-extension/lab-2/lab-2-main.sh @@ -2,7 +2,7 @@ ./collect-user-info.sh ./create-aca-env.sh -# ./create-mysql.sh -# ./create-container-registry.sh -# ./create-java-components.sh -# ./deploy-component-apps.sh \ No newline at end of file +./create-mysql.sh +./create-container-registry.sh +./create-java-components.sh +./deploy-component-apps.sh \ No newline at end of file From a71b2a3784dd2293d772014aae6ee04b34124642 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Thu, 13 Mar 2025 11:26:46 -0700 Subject: [PATCH 27/38] bug fixing --- tools/azd-extension/lab-2/create-aca-env.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/azd-extension/lab-2/create-aca-env.sh b/tools/azd-extension/lab-2/create-aca-env.sh index 3b28fb6..2d1b749 100644 --- a/tools/azd-extension/lab-2/create-aca-env.sh +++ b/tools/azd-extension/lab-2/create-aca-env.sh @@ -11,6 +11,13 @@ UNIQUEID=$(openssl rand -hex 3) export APPNAME=petclinic export RESOURCE_GROUP=$(az group list --query "[?contains(name, 'petclinic')].{Name:name}[0]" -o tsv) +random_element() { + local array=("$@") + echo "${array[RANDOM % ${#array[@]}]}" +} + +LOCATION=$(random_element australiaeast brazilsouth eastasia eastus2 japaneast southindia swedencentral westus) + if [ -z "$RESOURCE_GROUP" ]; then RESOURCE_GROUP=rg-$APPNAME-$UNIQUEID LOCATION=$(random_element australiaeast brazilsouth eastasia eastus2 japaneast southindia swedencentral westus) From 678f85a29be555b1fdaee276f2004d58fa9d7746 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Thu, 13 Mar 2025 12:29:13 -0700 Subject: [PATCH 28/38] clean up --- tools/azd-extension/lab-2/create-aca-env.sh | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/tools/azd-extension/lab-2/create-aca-env.sh b/tools/azd-extension/lab-2/create-aca-env.sh index 2d1b749..b436f5c 100644 --- a/tools/azd-extension/lab-2/create-aca-env.sh +++ b/tools/azd-extension/lab-2/create-aca-env.sh @@ -1,22 +1,16 @@ #!/bin/bash # This script creates an Azure Container Apps environment with a dedicated plan and a virtual network. # It also creates a resource group and a virtual network with a subnet for the Azure Container Apps environment. -# The script uses the Azure CLI to create the resources and requires the user to be logged in to their Azure account. -# The script also requires the user to have the Azure CLI installed and configured on their machine. -# The script uses the `az` command to create the resources and requires the user to have the necessary permissions to create resources in their Azure account. -# The script uses the `openssl` command to generate a random unique ID for the resource group and virtual network names. -# The script uses the `az configure` command to set the default resource group for the Azure CLI commands. - -UNIQUEID=$(openssl rand -hex 3) -export APPNAME=petclinic -export RESOURCE_GROUP=$(az group list --query "[?contains(name, 'petclinic')].{Name:name}[0]" -o tsv) random_element() { local array=("$@") echo "${array[RANDOM % ${#array[@]}]}" } -LOCATION=$(random_element australiaeast brazilsouth eastasia eastus2 japaneast southindia swedencentral westus) +UNIQUEID=$(openssl rand -hex 3) + +export APPNAME=petclinic +export RESOURCE_GROUP=$(az group list --query "[?contains(name, '$APPNAME')].{Name:name}[0]" -o tsv) if [ -z "$RESOURCE_GROUP" ]; then RESOURCE_GROUP=rg-$APPNAME-$UNIQUEID From 5c65673dedd9b3cb50079e23b014ba5479bd5b0a Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Thu, 13 Mar 2025 12:44:26 -0700 Subject: [PATCH 29/38] clean up --- tools/azd-extension/lab-2/deploy-component-apps.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/azd-extension/lab-2/deploy-component-apps.sh b/tools/azd-extension/lab-2/deploy-component-apps.sh index 2fc15b7..a6757a1 100644 --- a/tools/azd-extension/lab-2/deploy-component-apps.sh +++ b/tools/azd-extension/lab-2/deploy-component-apps.sh @@ -3,6 +3,15 @@ AZURE_CONFIG_FILE="../config/azure-resource.profile" source $AZURE_CONFIG_FILE +SPRING_PETCLINIC_MICROSERIVCES="../../../spring-petclinic-microservices" + +# Check if the spring-petclinic-microservices directory exists +if [ ! -d "$SPRING_PETCLINIC_MICROSERIVCES" ]; then + echo "Error: $SPRING_PETCLINIC_MICROSERIVCES directory does not exist." + # create the directory + mkdir -p $SPRING_PETCLINIC_MICROSERIVCES +fi + # Get the application code from public upstream repo, and then build the applications. cd ../../../spring-petclinic-microservices git submodule update --init From 7366333b34488b809104b71551a04fd940786747 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Fri, 14 Mar 2025 15:13:18 -0700 Subject: [PATCH 30/38] create lab-3 --- tools/azd-extension/lab-3/ChatConfigure.java | 35 ++++++++++++++ tools/azd-extension/lab-3/ChatController.java | 31 ++++++++++++ .../azd-extension/lab-3/create-ai-account.sh | 47 +++++++++++++++++++ .../lab-3/create-openai-service.sh | 37 --------------- .../lab-3/create-spring-boot-ai.sh | 38 +++++++++++++++ 5 files changed, 151 insertions(+), 37 deletions(-) create mode 100644 tools/azd-extension/lab-3/ChatConfigure.java create mode 100644 tools/azd-extension/lab-3/ChatController.java create mode 100644 tools/azd-extension/lab-3/create-ai-account.sh delete mode 100644 tools/azd-extension/lab-3/create-openai-service.sh create mode 100644 tools/azd-extension/lab-3/create-spring-boot-ai.sh diff --git a/tools/azd-extension/lab-3/ChatConfigure.java b/tools/azd-extension/lab-3/ChatConfigure.java new file mode 100644 index 0000000..2f1a2ab --- /dev/null +++ b/tools/azd-extension/lab-3/ChatConfigure.java @@ -0,0 +1,35 @@ +// filepath: /workspaces/java-on-aca/tools/spring-petclinic-chat-service/src/main/java/org/springframework/ai/azure/openai/ChatConfigure.java +package org.springframework.ai.azure.openai; + +import com.azure.ai.openai.OpenAIClientBuilder; +import com.azure.ai.openai.OpenAIServiceVersion; +import com.azure.core.credential.AzureKeyCredential; +import com.azure.core.http.policy.HttpLogOptions; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ChatConfigure { + + @Bean + public OpenAIClientBuilder openAIClientBuilder() { + return new OpenAIClientBuilder() + .credential(new AzureKeyCredential(System.getenv("AZURE_OPENAI_API_KEY"))) + .endpoint(System.getenv("AZURE_OPENAI_ENDPOINT")) + .serviceVersion(OpenAIServiceVersion.V2024_02_15_PREVIEW) + .httpLogOptions(new HttpLogOptions().setLogLevel(com.azure.core.http.policy.HttpLogDetailLevel.BODY_AND_HEADERS)); + } + + @Bean + public AzureOpenAiChatModel azureOpenAiChatModel(OpenAIClientBuilder openAIClientBuilder) { + return AzureOpenAiChatModel.builder() + .openAIClientBuilder(openAIClientBuilder) + .defaultOptions(AzureOpenAiChatOptions.builder().deploymentName("gpt-4o").maxTokens(1000).build()) + .build(); + } + + @Bean + public ChatClient chatClient(AzureOpenAiChatModel azureOpenAiChatModel) { + return ChatClient.builder(azureOpenAiChatModel).build(); + } +} \ No newline at end of file diff --git a/tools/azd-extension/lab-3/ChatController.java b/tools/azd-extension/lab-3/ChatController.java new file mode 100644 index 0000000..9d259d1 --- /dev/null +++ b/tools/azd-extension/lab-3/ChatController.java @@ -0,0 +1,31 @@ +// filepath: /workspaces/java-on-aca/tools/spring-petclinic-chat-service/src/main/java/org/springframework/ai/azure/openai/ChatController.java +package org.springframework.ai.azure.openai; + +import org.springframework.ai.chat.client.ChatClient; +import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor; +import org.springframework.ai.chat.model.ChatResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ChatController { + + private static final String SYSTEM_PROMPT = "You are a joke bot. You are funny and witty."; + + @Autowired + private ChatClient chatClient; + + @PostMapping("/chatclient") + public String chat(@RequestBody String userInput) { + ChatResponse response = chatClient.prompt() + .advisors(new SimpleLoggerAdvisor()) + .system(SYSTEM_PROMPT) + .user(userInput) + .call() + .chatResponse(); + + return response.getResults().get(0).getOutput().getText(); + } +} \ No newline at end of file diff --git a/tools/azd-extension/lab-3/create-ai-account.sh b/tools/azd-extension/lab-3/create-ai-account.sh new file mode 100644 index 0000000..8b513dd --- /dev/null +++ b/tools/azd-extension/lab-3/create-ai-account.sh @@ -0,0 +1,47 @@ +#!/bin/bash +AZURE_CONFIG_FILE="../config/azure-resource.profile" +source $AZURE_CONFIG_FILE + +AI_LOCATION=$LOCATION + +OPEN_AI_SERVICE_NAME=open-ai-account-$UNIQUEID +az cognitiveservices account create \ + --resource-group $RESOURCE_GROUP \ + --name $OPEN_AI_SERVICE_NAME \ + --location $AI_LOCATION \ + --kind OpenAI \ + --sku s0 \ + --custom-domain $OPEN_AI_SERVICE_NAME + +az cognitiveservices account deployment create \ + --resource-group $RESOURCE_GROUP \ + --name $OPEN_AI_SERVICE_NAME \ + --deployment-name gpt-4o \ + --model-name gpt-4o \ + --model-version 2024-08-06 \ + --model-format OpenAI \ + --sku-name "GlobalStandard" \ + --sku-capacity 10 + +# Query the Azure OpenAI endpoint +AZURE_OPENAI_ENDPOINT=$(az cognitiveservices account show \ + --resource-group $RESOURCE_GROUP \ + --name $OPEN_AI_SERVICE_NAME \ + --query "properties.endpoint" \ + --output tsv) + +# Query the Azure OpenAI API key +AZURE_OPENAI_API_KEY=$(az cognitiveservices account keys list \ + --resource-group $RESOURCE_GROUP \ + --name $OPEN_AI_SERVICE_NAME \ + --query "key1" \ + --output tsv) + +# Export the endpoint and API key as environment variables +export AZURE_OPENAI_ENDPOINT +export AZURE_OPENAI_API_KEY +{ + echo "AZURE_OPENAI_ENDPOINT=$AZURE_OPENAI_ENDPOINT" + echo "AZURE_OPENAI_API_KEY=$AZURE_OPENAI_API_KEY" +} >> $AZURE_CONFIG_FILE + diff --git a/tools/azd-extension/lab-3/create-openai-service.sh b/tools/azd-extension/lab-3/create-openai-service.sh deleted file mode 100644 index 24ed5c4..0000000 --- a/tools/azd-extension/lab-3/create-openai-service.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash - -AZURE_CONFIG_FILE="../config/azure-resource.profile" -source $AZURE_CONFIG_FILE - -AI_LOCATION=$LOCATION - -# Create an Azure OpenAI account -OPEN_AI_SERVICE_NAME=open-ai-account-$UNIQUEID -az cognitiveservices account create \ - --resource-group $RESOURCE_GROUP \ - --name $OPEN_AI_SERVICE_NAME \ - --location $AI_LOCATION \ - --kind OpenAI \ - --sku s0 \ - --custom-domain $OPEN_AI_SERVICE_NAME - -# Check if the OpenAI account was created successfully -AI_ID=$(az cognitiveservices account show --resource-group $RESOURCE_GROUP --name $OPEN_AI_SERVICE_NAME -o tsv --query id 2>/dev/null) -if [[ -n $AI_ID ]]; then - echo -e "${GREEN}INFO:${NC} OpenAI instance $OPEN_AI_SERVICE_NAME already exists" -else - echo -e "${YELLOW}INFO:${NC} Creating OpenAI instance $OPEN_AI_SERVICE_NAME in region $AI_LOCATION ..." -fi - -# deploy the language model -az cognitiveservices account deployment create \ - --resource-group $RESOURCE_GROUP \ - --name $OPEN_AI_SERVICE_NAME \ - --deployment-name gpt-4o \ - --model-name gpt-4o \ - --model-version 2024-08-06 \ - --model-format OpenAI \ - --sku-name "GlobalStandard" \ - --sku-capacity 10 - -echo "OPEN_AI_SERVICE_NAME=$OPEN_AI_SERVICE_NAME" >> $AZURE_CONFIG_FILE \ No newline at end of file diff --git a/tools/azd-extension/lab-3/create-spring-boot-ai.sh b/tools/azd-extension/lab-3/create-spring-boot-ai.sh new file mode 100644 index 0000000..7f867cb --- /dev/null +++ b/tools/azd-extension/lab-3/create-spring-boot-ai.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +AZURE_CONFIG_FILE="../config/azure-resource.profile" +source $AZURE_CONFIG_FILE + +SPRING_PETCLINIC_CHAT_SERVICE="../../spring-petclinic-chat-service" + +POM=$SPRING_PETCLINIC_CHAT_SERVICE/pom.xml +SPRING_AI_VERSION="1.0.0-M6" + +# update the spring-ai.version in the pom.xml +if grep -q "" $POM; then + sed -i "s|.*|$SPRING_AI_VERSION|" $POM +else + sed -i "//a \ $SPRING_AI_VERSION" $POM +fi + +{ + echo "## AI VERSION" + echo "SPRING_AI_VERSION=$SPRING_AI_VERSION" +} >> $AZURE_CONFIG_FILE + +TEST_FILE="https://raw.githubusercontent.com/spring-projects/spring-ai/refs/heads/$SPRING_AI_VERSION/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiChatClientIT.java" +curl $TEST_FILE -o $SPRING_PETCLINIC_CHAT_SERVICE/src/main/resources/AzureOpenAiChatClientIT.java + +CHAT_CONFIGURE_JAVA="ChatConfigure.java" +CHAT_CONTROLLER_JAVA="ChatController.java" + +cp $CHAT_CONFIGURE_JAVA $SPRING_PETCLINIC_CHAT_SERVICE/src/main/resources +cp $CHAT_CONTROLLER_JAVA $SPRING_PETCLINIC_CHAT_SERVICE/src/main/resources + +cd $SPRING_PETCLINIC_CHAT_SERVICE +mvn clean package -DskipTests + +export AZURE_OPENAI_API_KEY="$AZURE_OPENAI_API_KEY" +export AZURE_OPENAI_ENDPOINT="$AZURE_OPENAI_ENDPOINT" + +mvn spring-boot:run \ No newline at end of file From 293b48b4f00bc9ff708b0dca5b1b05f8d3cf09ae Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Sat, 15 Mar 2025 14:15:14 -0700 Subject: [PATCH 31/38] bug fixing --- tools/azd-extension/lab-2/create-aca-env.sh | 2 +- .../lab-2/create-container-registry.sh | 2 -- tools/azd-extension/lab-2/create-mysql.sh | 2 +- tools/azd-extension/lab-2/lab-2-main.sh | 17 ++++++++++++++++- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/tools/azd-extension/lab-2/create-aca-env.sh b/tools/azd-extension/lab-2/create-aca-env.sh index b436f5c..a177587 100644 --- a/tools/azd-extension/lab-2/create-aca-env.sh +++ b/tools/azd-extension/lab-2/create-aca-env.sh @@ -14,7 +14,7 @@ export RESOURCE_GROUP=$(az group list --query "[?contains(name, '$APPNAME')].{Na if [ -z "$RESOURCE_GROUP" ]; then RESOURCE_GROUP=rg-$APPNAME-$UNIQUEID - LOCATION=$(random_element australiaeast brazilsouth eastasia eastus2 japaneast southindia swedencentral westus) + LOCATION=westus echo "Creating resource group [$RESOURCE_GROUP] in region [$LOCATION]..." az group create -g $RESOURCE_GROUP -l $LOCATION else diff --git a/tools/azd-extension/lab-2/create-container-registry.sh b/tools/azd-extension/lab-2/create-container-registry.sh index b318169..bc64ae0 100644 --- a/tools/azd-extension/lab-2/create-container-registry.sh +++ b/tools/azd-extension/lab-2/create-container-registry.sh @@ -15,8 +15,6 @@ AZURE_CONFIG_FILE="../config/azure-resource.profile" source $AZURE_CONFIG_FILE -APPNAME=petclinic - # Check if a container registry containing the string $APPNAME already exists MYACR=$(az acr list --resource-group $RESOURCE_GROUP --query "[?contains(name, '$APPNAME')].{Name:name}[0]" -o tsv) diff --git a/tools/azd-extension/lab-2/create-mysql.sh b/tools/azd-extension/lab-2/create-mysql.sh index 56e2fae..aef9375 100644 --- a/tools/azd-extension/lab-2/create-mysql.sh +++ b/tools/azd-extension/lab-2/create-mysql.sh @@ -37,7 +37,7 @@ az mysql flexible-server firewall-rule create \ echo " spring: datasource: - url: jdbc:mysql://${MYSQL_SERVER_NAME}.mysql.database.azure.com:3306/petclinic?useSSL=true + url: jdbc:mysql://${MYSQL_SERVER_NAME}.mysql.database.azure.com:3306/$DATABASE_NAME?useSSL=true username: ${MYSQL_ADMIN_USERNAME} password: ${MYSQL_ADMIN_PASSWORD} sql: diff --git a/tools/azd-extension/lab-2/lab-2-main.sh b/tools/azd-extension/lab-2/lab-2-main.sh index 4e3cb89..1706eff 100644 --- a/tools/azd-extension/lab-2/lab-2-main.sh +++ b/tools/azd-extension/lab-2/lab-2-main.sh @@ -1,8 +1,23 @@ #!/bin/bash +echo "Starting Lab 2..." + +echo "Step 1: Collecting user information..." ./collect-user-info.sh + +echo "Step 2: Creating Azure Container Apps environment..." ./create-aca-env.sh + +echo "Step 3: Creating MySql instance..." ./create-mysql.sh + +echo "Step 4: Creating Azure Container Registry..." ./create-container-registry.sh + +echo "Step 5: Creating Java Spring Boot components..." ./create-java-components.sh -./deploy-component-apps.sh \ No newline at end of file + +echo "Step 6: Deploy API Gateway..." +./deploy-component-apps.sh + +echo "Lab 2 completed." \ No newline at end of file From 77c96ebc68a37c4e7d9201f689abc0f39da784b4 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Tue, 18 Mar 2025 10:19:21 -0700 Subject: [PATCH 32/38] add java modules --- tools/azd-extension/lab-3/ChatConfigure.java | 45 +++++++++---------- tools/azd-extension/lab-3/ChatController.java | 12 +++-- 2 files changed, 27 insertions(+), 30 deletions(-) diff --git a/tools/azd-extension/lab-3/ChatConfigure.java b/tools/azd-extension/lab-3/ChatConfigure.java index 2f1a2ab..fc13165 100644 --- a/tools/azd-extension/lab-3/ChatConfigure.java +++ b/tools/azd-extension/lab-3/ChatConfigure.java @@ -1,35 +1,34 @@ -// filepath: /workspaces/java-on-aca/tools/spring-petclinic-chat-service/src/main/java/org/springframework/ai/azure/openai/ChatConfigure.java -package org.springframework.ai.azure.openai; +package org.springframework.samples.petclinic.chat; -import com.azure.ai.openai.OpenAIClientBuilder; -import com.azure.ai.openai.OpenAIServiceVersion; -import com.azure.core.credential.AzureKeyCredential; -import com.azure.core.http.policy.HttpLogOptions; +import org.springframework.ai.chat.client.ChatClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + @Configuration public class ChatConfigure { - @Bean - public OpenAIClientBuilder openAIClientBuilder() { - return new OpenAIClientBuilder() - .credential(new AzureKeyCredential(System.getenv("AZURE_OPENAI_API_KEY"))) - .endpoint(System.getenv("AZURE_OPENAI_ENDPOINT")) - .serviceVersion(OpenAIServiceVersion.V2024_02_15_PREVIEW) - .httpLogOptions(new HttpLogOptions().setLogLevel(com.azure.core.http.policy.HttpLogDetailLevel.BODY_AND_HEADERS)); - } + private static final Logger logger = LoggerFactory.getLogger(ChatConfigure.class); @Bean - public AzureOpenAiChatModel azureOpenAiChatModel(OpenAIClientBuilder openAIClientBuilder) { - return AzureOpenAiChatModel.builder() - .openAIClientBuilder(openAIClientBuilder) - .defaultOptions(AzureOpenAiChatOptions.builder().deploymentName("gpt-4o").maxTokens(1000).build()) - .build(); - } + public ChatClient chatClient() { + String endpoint = System.getenv("AZURE_OPENAI_ENDPOINT"); + String apiKey = System.getenv("AZURE_OPENAI_API_KEY"); + + // Debug logging to verify the environment variables + logger.info("AZURE_OPENAI_API_KEY: {}", apiKey); + logger.info("AZURE_OPENAI_ENDPOINT: {}", endpoint); - @Bean - public ChatClient chatClient(AzureOpenAiChatModel azureOpenAiChatModel) { - return ChatClient.builder(azureOpenAiChatModel).build(); + if (apiKey == null || apiKey.isEmpty()) { + throw new IllegalArgumentException("AZURE_OPENAI_API_KEY environment variable is not set"); + } + if (endpoint == null || endpoint.isEmpty()) { + throw new IllegalArgumentException("AZURE_OPENAI_ENDPOINT environment variable is not set"); + } + + // return new ChatClient(endpoint, apiKey); + return new ChatClient("https://open-ai-account-3537fb.openai.azure.com/", "efd6975f0ac847c0802479692e06a226"); } } \ No newline at end of file diff --git a/tools/azd-extension/lab-3/ChatController.java b/tools/azd-extension/lab-3/ChatController.java index 9d259d1..c1fa096 100644 --- a/tools/azd-extension/lab-3/ChatController.java +++ b/tools/azd-extension/lab-3/ChatController.java @@ -1,15 +1,14 @@ // filepath: /workspaces/java-on-aca/tools/spring-petclinic-chat-service/src/main/java/org/springframework/ai/azure/openai/ChatController.java -package org.springframework.ai.azure.openai; +package org.springframework.samples.petclinic.chat; import org.springframework.ai.chat.client.ChatClient; -import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RestController +@RequestMapping("/chatclient") + public class ChatController { private static final String SYSTEM_PROMPT = "You are a joke bot. You are funny and witty."; @@ -17,10 +16,9 @@ public class ChatController { @Autowired private ChatClient chatClient; - @PostMapping("/chatclient") + @PostMapping public String chat(@RequestBody String userInput) { ChatResponse response = chatClient.prompt() - .advisors(new SimpleLoggerAdvisor()) .system(SYSTEM_PROMPT) .user(userInput) .call() From d2b4001ed89face69968fc90e68fbf661c06ccf1 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Tue, 18 Mar 2025 10:41:39 -0700 Subject: [PATCH 33/38] fix bugs in Java modules --- .../lab-3/AzureOpenAiConfig.java | 25 ++++++++++++++ tools/azd-extension/lab-3/ChatConfigure.java | 34 ------------------- tools/azd-extension/lab-3/ChatController.java | 32 ++++++++++------- 3 files changed, 44 insertions(+), 47 deletions(-) create mode 100644 tools/azd-extension/lab-3/AzureOpenAiConfig.java delete mode 100644 tools/azd-extension/lab-3/ChatConfigure.java diff --git a/tools/azd-extension/lab-3/AzureOpenAiConfig.java b/tools/azd-extension/lab-3/AzureOpenAiConfig.java new file mode 100644 index 0000000..b52155b --- /dev/null +++ b/tools/azd-extension/lab-3/AzureOpenAiConfig.java @@ -0,0 +1,25 @@ +package org.springframework.samples.petclinic.chat; + +import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAIClientBuilderCustomizer; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.azure.core.http.HttpClient; +import com.azure.core.util.HttpClientOptions; + +import java.time.Duration; + +@Configuration +public class AzureOpenAiConfig { + + @Bean + public AzureOpenAIClientBuilderCustomizer responseTimeoutCustomizer() { + return openAiClientBuilder -> { + HttpClientOptions clientOptions = new HttpClientOptions() + .setResponseTimeout(Duration.ofMinutes(5)); + openAiClientBuilder.httpClient(HttpClient.createDefault(clientOptions)); + }; + } + +} \ No newline at end of file diff --git a/tools/azd-extension/lab-3/ChatConfigure.java b/tools/azd-extension/lab-3/ChatConfigure.java deleted file mode 100644 index fc13165..0000000 --- a/tools/azd-extension/lab-3/ChatConfigure.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.springframework.samples.petclinic.chat; - -import org.springframework.ai.chat.client.ChatClient; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@Configuration -public class ChatConfigure { - - private static final Logger logger = LoggerFactory.getLogger(ChatConfigure.class); - - @Bean - public ChatClient chatClient() { - String endpoint = System.getenv("AZURE_OPENAI_ENDPOINT"); - String apiKey = System.getenv("AZURE_OPENAI_API_KEY"); - - // Debug logging to verify the environment variables - logger.info("AZURE_OPENAI_API_KEY: {}", apiKey); - logger.info("AZURE_OPENAI_ENDPOINT: {}", endpoint); - - if (apiKey == null || apiKey.isEmpty()) { - throw new IllegalArgumentException("AZURE_OPENAI_API_KEY environment variable is not set"); - } - if (endpoint == null || endpoint.isEmpty()) { - throw new IllegalArgumentException("AZURE_OPENAI_ENDPOINT environment variable is not set"); - } - - // return new ChatClient(endpoint, apiKey); - return new ChatClient("https://open-ai-account-3537fb.openai.azure.com/", "efd6975f0ac847c0802479692e06a226"); - } -} \ No newline at end of file diff --git a/tools/azd-extension/lab-3/ChatController.java b/tools/azd-extension/lab-3/ChatController.java index c1fa096..6ed0e59 100644 --- a/tools/azd-extension/lab-3/ChatController.java +++ b/tools/azd-extension/lab-3/ChatController.java @@ -1,29 +1,35 @@ // filepath: /workspaces/java-on-aca/tools/spring-petclinic-chat-service/src/main/java/org/springframework/ai/azure/openai/ChatController.java package org.springframework.samples.petclinic.chat; -import org.springframework.ai.chat.client.ChatClient; +import java.util.Map; + +import org.springframework.ai.azure.openai.AzureOpenAiChatModel; +import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.model.ChatResponse; +import org.springframework.ai.chat.prompt.Prompt; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; -@RestController -@RequestMapping("/chatclient") +import reactor.core.publisher.Flux; +@RestController public class ChatController { - private static final String SYSTEM_PROMPT = "You are a joke bot. You are funny and witty."; + private final AzureOpenAiChatModel chatModel; @Autowired - private ChatClient chatClient; + public ChatController(AzureOpenAiChatModel chatModel) { + this.chatModel = chatModel; + } - @PostMapping - public String chat(@RequestBody String userInput) { - ChatResponse response = chatClient.prompt() - .system(SYSTEM_PROMPT) - .user(userInput) - .call() - .chatResponse(); + @GetMapping("/ai/generate") + public Map generate(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) { + return Map.of("generation", this.chatModel.call(message)); + } - return response.getResults().get(0).getOutput().getText(); + @GetMapping("/ai/generateStream") + public Flux generateStream(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) { + Prompt prompt = new Prompt(new UserMessage(message)); + return this.chatModel.stream(prompt); } } \ No newline at end of file From 9e43a81a6f427f6f05a4a09ea321d11a267080b6 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Tue, 18 Mar 2025 11:17:37 -0700 Subject: [PATCH 34/38] lab-3 fully working version --- .../azd-extension/lab-3/create-ai-account.sh | 2 + .../lab-3/create-spring-boot-ai.sh | 87 ++++++++++++++++--- 2 files changed, 77 insertions(+), 12 deletions(-) diff --git a/tools/azd-extension/lab-3/create-ai-account.sh b/tools/azd-extension/lab-3/create-ai-account.sh index 8b513dd..9349caf 100644 --- a/tools/azd-extension/lab-3/create-ai-account.sh +++ b/tools/azd-extension/lab-3/create-ai-account.sh @@ -5,6 +5,8 @@ source $AZURE_CONFIG_FILE AI_LOCATION=$LOCATION OPEN_AI_SERVICE_NAME=open-ai-account-$UNIQUEID + +# Create a new Azure Cognitive Services account az cognitiveservices account create \ --resource-group $RESOURCE_GROUP \ --name $OPEN_AI_SERVICE_NAME \ diff --git a/tools/azd-extension/lab-3/create-spring-boot-ai.sh b/tools/azd-extension/lab-3/create-spring-boot-ai.sh index 7f867cb..c8a321a 100644 --- a/tools/azd-extension/lab-3/create-spring-boot-ai.sh +++ b/tools/azd-extension/lab-3/create-spring-boot-ai.sh @@ -3,17 +3,38 @@ AZURE_CONFIG_FILE="../config/azure-resource.profile" source $AZURE_CONFIG_FILE -SPRING_PETCLINIC_CHAT_SERVICE="../../spring-petclinic-chat-service" +SPRING_PETCLINIC_MICROSERIVCES="../../../spring-petclinic-microservices" +SPRING_PETCLINIC_CHAT_SERVICE="spring-petclinic-chat-service" + +cd $SPRING_PETCLINIC_MICROSERIVCES +# Check if the spring-petclinic-chat-service directory exists +if [ -d "$SPRING_PETCLINIC_CHAT_SERVICE" ]; then + # remove the directory + echo "Remove directory: $SPRING_PETCLINIC_CHAT_SERVICE." + rm -rf $SPRING_PETCLINIC_CHAT_SERVICE + + echo "Recreate directory: $SPRING_PETCLINIC_CHAT_SERVICE." + # recreate the directory + mkdir -p $SPRING_PETCLINIC_CHAT_SERVICE +fi + + curl https://start.spring.io/starter.tgz \ + -d dependencies=web,cloud-eureka,actuator,lombok,spring-ai-azure-openai \ + -d name=chat-service -d type=maven-project \ + -d jvmVersion=17 -d language=java -d packaging=jar \ + -d groupId=org.springframework.samples.petclinic -d artifactId=chat \ + -d description="Spring Petclinic Chat Service" \ + | tar -xzvf - -C $SPRING_PETCLINIC_CHAT_SERVICE POM=$SPRING_PETCLINIC_CHAT_SERVICE/pom.xml SPRING_AI_VERSION="1.0.0-M6" -# update the spring-ai.version in the pom.xml -if grep -q "" $POM; then - sed -i "s|.*|$SPRING_AI_VERSION|" $POM -else - sed -i "//a \ $SPRING_AI_VERSION" $POM -fi +# # update the spring-ai.version in the pom.xml +# if grep -q "" $POM; then +# sed -i "s|.*|$SPRING_AI_VERSION|" $POM +# else +# sed -i "//a \ $SPRING_AI_VERSION" $POM +# fi { echo "## AI VERSION" @@ -23,16 +44,58 @@ fi TEST_FILE="https://raw.githubusercontent.com/spring-projects/spring-ai/refs/heads/$SPRING_AI_VERSION/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiChatClientIT.java" curl $TEST_FILE -o $SPRING_PETCLINIC_CHAT_SERVICE/src/main/resources/AzureOpenAiChatClientIT.java -CHAT_CONFIGURE_JAVA="ChatConfigure.java" -CHAT_CONTROLLER_JAVA="ChatController.java" +CHAT_CONFIGURE_JAVA="../tools/azd-extension/lab-3/AzureOpenAiConfig.java" +CHAT_CONTROLLER_JAVA="../tools/azd-extension/lab-3/ChatController.java" +APPLICATION_PROPERTIES="../tools/azd-extension/lab-3/application.properties" +DOCKERFILE="../tools/Dockerfile" + +cp $CHAT_CONFIGURE_JAVA $SPRING_PETCLINIC_CHAT_SERVICE/src/main/java/org/springframework/samples/petclinic/chat +cp $CHAT_CONTROLLER_JAVA $SPRING_PETCLINIC_CHAT_SERVICE/src/main/java/org/springframework/samples/petclinic/chat -cp $CHAT_CONFIGURE_JAVA $SPRING_PETCLINIC_CHAT_SERVICE/src/main/resources -cp $CHAT_CONTROLLER_JAVA $SPRING_PETCLINIC_CHAT_SERVICE/src/main/resources +{ + echo "spring.application.name=chat-service" + echo "spring.ai.azure.openai.api-key=$AZURE_OPENAI_API_KEY" + echo "spring.ai.azure.openai.endpoint=$AZURE_OPENAI_ENDPOINT" + echo "spring.ai.azure.openai.chat.options.deployment-name=gpt-4o" + echo "spring.ai.azure.openai.chat.options.temperature=0.7" +} > $APPLICATION_PROPERTIES + +cp $APPLICATION_PROPERTIES $SPRING_PETCLINIC_CHAT_SERVICE/src/main/resources/application.properties cd $SPRING_PETCLINIC_CHAT_SERVICE mvn clean package -DskipTests +# Export the environment variables export AZURE_OPENAI_API_KEY="$AZURE_OPENAI_API_KEY" export AZURE_OPENAI_ENDPOINT="$AZURE_OPENAI_ENDPOINT" -mvn spring-boot:run \ No newline at end of file +APP_NAME=chat-service + +cd .. +echo "APPS_IDENTITY_ID: $APPS_IDENTITY_ID" + +cp -f $DOCKERFILE ./spring-petclinic-$APP_NAME/Dockerfile +# Disable path conversion for MSYS (Git Bash) +export MSYS_NO_PATHCONV=1 +az containerapp create \ + --name $APP_NAME \ + --resource-group $RESOURCE_GROUP \ + --environment $ACA_ENVIRONMENT \ + --source ./spring-petclinic-$APP_NAME \ + --registry-server $MYACR.azurecr.io \ + --registry-identity $APPS_IDENTITY_ID \ + --ingress external \ + --target-port 8080 \ + --min-replicas 1 \ + --bind $JAVA_CONFIG_COMP_NAME $JAVA_EUREKA_COMP_NAME \ + --runtime java + +CHAT_URL=$(az containerapp show \ + --resource-group $RESOURCE_GROUP \ + --name $APP_NAME \ + --query properties.configuration.ingress.fqdn \ + -o tsv) + +echo "Chat service URL: $CHAT_URL" + +curl -XPOST https://$CHAT_URL/chatclient -d 'Hi, tell a joke' From 77e68cb317226d930018788c86de701bcf0ce91d Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Tue, 18 Mar 2025 11:18:54 -0700 Subject: [PATCH 35/38] add main script for lab-3 --- tools/azd-extension/lab-3/lab-3-main.sh | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tools/azd-extension/lab-3/lab-3-main.sh diff --git a/tools/azd-extension/lab-3/lab-3-main.sh b/tools/azd-extension/lab-3/lab-3-main.sh new file mode 100644 index 0000000..40926bf --- /dev/null +++ b/tools/azd-extension/lab-3/lab-3-main.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +set -e + +echo "Starting Lab 3..." + +echo "Step 1: Create AI account..." +./create-ai-account.sh +if [ $? -ne 0 ]; then + echo "Error: Step 1 failed. Exiting." + exit 1 +fi + +echo "Step 2: Create Spring Boot AI service..." +./create-spring-boot-ai.sh +if [ $? -ne 0 ]; then + echo "Error: Step 2 failed. Exiting." + exit 1 +fi + +echo "Lab 3 completed successfully." \ No newline at end of file From 6b03acfe8ec19c944d60d75b887d7dd05ec67d61 Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Tue, 18 Mar 2025 14:24:16 -0700 Subject: [PATCH 36/38] update chat joke url --- tools/azd-extension/lab-3/create-spring-boot-ai.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/azd-extension/lab-3/create-spring-boot-ai.sh b/tools/azd-extension/lab-3/create-spring-boot-ai.sh index c8a321a..ba7ba48 100644 --- a/tools/azd-extension/lab-3/create-spring-boot-ai.sh +++ b/tools/azd-extension/lab-3/create-spring-boot-ai.sh @@ -98,4 +98,4 @@ CHAT_URL=$(az containerapp show \ echo "Chat service URL: $CHAT_URL" -curl -XPOST https://$CHAT_URL/chatclient -d 'Hi, tell a joke' +curl https://$CHAT_URL/ai/generate From 55f730de2189f5a5ec87c88fdd72767743c4a96d Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Wed, 19 Mar 2025 12:28:46 -0700 Subject: [PATCH 37/38] create scripts in lab-4 --- .../lab-4/enable-log-analytics.sh | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tools/azd-extension/lab-4/enable-log-analytics.sh diff --git a/tools/azd-extension/lab-4/enable-log-analytics.sh b/tools/azd-extension/lab-4/enable-log-analytics.sh new file mode 100644 index 0000000..9be4e38 --- /dev/null +++ b/tools/azd-extension/lab-4/enable-log-analytics.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +AZURE_CONFIG_FILE="../config/azure-resource.profile" +source $AZURE_CONFIG_FILE + +WORKSPACE=la-$APPNAME-$UNIQUEID +az monitor log-analytics workspace create \ + --resource-group $RESOURCE_GROUP \ + --workspace-name $WORKSPACE + +WORKSPACE_ID=$(az monitor log-analytics workspace show -n $WORKSPACE -g $RESOURCE_GROUP --query id -o tsv) +WORKSPACE_CUSTOMER_ID=$(az monitor log-analytics workspace show -n $WORKSPACE -g $RESOURCE_GROUP --query customerId -o tsv) +WORKSPACE_KEY=$(az monitor log-analytics workspace get-shared-keys -n $WORKSPACE -g $RESOURCE_GROUP --query primarySharedKey -o tsv) + +az containerapp env update \ + --name $ACA_ENVIRONMENT \ + --resource-group $RESOURCE_GROUP \ + --logs-destination log-analytics \ + --logs-workspace-id $WORKSPACE_CUSTOMER_ID \ + --logs-workspace-key $WORKSPACE_KEY From 710a35b64e788986d199306cedfa1fca3fe33a4b Mon Sep 17 00:00:00 2001 From: Pete Tian Date: Wed, 19 Mar 2025 12:43:36 -0700 Subject: [PATCH 38/38] more for lab-4 --- .../lab-4/config-app-insights.sh | 26 +++++++++++++++++++ .../lab-4/enable-log-analytics.sh | 6 +++++ 2 files changed, 32 insertions(+) create mode 100644 tools/azd-extension/lab-4/config-app-insights.sh diff --git a/tools/azd-extension/lab-4/config-app-insights.sh b/tools/azd-extension/lab-4/config-app-insights.sh new file mode 100644 index 0000000..2535668 --- /dev/null +++ b/tools/azd-extension/lab-4/config-app-insights.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +AZURE_CONFIG_FILE="../config/azure-resource.profile" +source $AZURE_CONFIG_FILE +export MSYS_NO_PATHCONV=1 + +APP_INSIGHTS_NAME=app-insights-$APPNAME-$UNIQUEID +az monitor app-insights component create \ + --resource-group $RESOURCE_GROUP \ + --app $APP_INSIGHTS_NAME \ + --location $LOCATION \ + --kind web \ + --workspace $WORKSPACE_ID + +export APP_INSIGHTS_CONN=$(az monitor app-insights component show --app $APP_INSIGHTS_NAME -g $RESOURCE_GROUP --query connectionString --output tsv) + +"APP_INSIGHTS_CONN='$APP_INSIGHTS_CONN'" >> $AZURE_CONFIG_FILE + +APP_NAME="api-gateway" +az containerapp update \ + --name $APP_NAME \ + --resource-group $RESOURCE_GROUP \ + --set-env-vars JAVA_TOOL_OPTIONS='-javaagent:/applicationinsights-agent.jar' APPLICATIONINSIGHTS_CONNECTION_STRING="$APP_INSIGHTS_CONN" APPLICATIONINSIGHTS_CONFIGURATION_CONTENT='{"role": {"name": "'$APP_NAME'"}}' + +export RESOURCE_GROUP APP_INSIGHTS_CONN +bash ../../update-apps-appinsights.sh diff --git a/tools/azd-extension/lab-4/enable-log-analytics.sh b/tools/azd-extension/lab-4/enable-log-analytics.sh index 9be4e38..1ee6d88 100644 --- a/tools/azd-extension/lab-4/enable-log-analytics.sh +++ b/tools/azd-extension/lab-4/enable-log-analytics.sh @@ -18,3 +18,9 @@ az containerapp env update \ --logs-destination log-analytics \ --logs-workspace-id $WORKSPACE_CUSTOMER_ID \ --logs-workspace-key $WORKSPACE_KEY + +{ + echo "WORKSPACE_ID=$WORKSPACE_ID" + echo "WORKSPACE_CUSTOMER_ID=$WORKSPACE_CUSTOMER_ID" + echo "WORKSPACE_KEY='$WORKSPACE_KEY'" +} >> $AZURE_CONFIG_FILE \ No newline at end of file