From 4dc26fe8c409d65659324aeca8c75b199938e7ea Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Sep 2025 16:26:44 +0000 Subject: [PATCH 1/3] Initial plan From 6b8071c9da2903d6a056f40104a8c8978bb1916c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Sep 2025 16:30:56 +0000 Subject: [PATCH 2/3] Initial assessment: Migration to Azure Managed Identity authentication appears complete Co-authored-by: richposada <454664+richposada@users.noreply.github.com> --- mi-sql-public-demo/dependency-reduced-pom.xml | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 mi-sql-public-demo/dependency-reduced-pom.xml diff --git a/mi-sql-public-demo/dependency-reduced-pom.xml b/mi-sql-public-demo/dependency-reduced-pom.xml new file mode 100644 index 0000000..9a8898f --- /dev/null +++ b/mi-sql-public-demo/dependency-reduced-pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + com.example + demo + 1.0-SNAPSHOT + + + + maven-shade-plugin + 3.2.4 + + + package + + shade + + + + + com.example.MainSQL + + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + + + + + + + + com.azure.spring + spring-cloud-azure-dependencies + 5.22.0 + pom + import + + + + + 17 + 17 + 17 + + From c78e231da6db853ddf8d5b47f44d5781d1bbec95 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Sep 2025 16:35:01 +0000 Subject: [PATCH 3/3] Enhance Azure Managed Identity configuration with environment variable support and improved error handling Co-authored-by: richposada <454664+richposada@users.noreply.github.com> --- .gitignore | 3 + mi-sql-public-demo/dependency-reduced-pom.xml | 56 ------------------- .../src/main/java/com/example/MainSQL.java | 50 ++++++++++++++++- .../src/main/resources/application.properties | 4 +- 4 files changed, 54 insertions(+), 59 deletions(-) delete mode 100644 mi-sql-public-demo/dependency-reduced-pom.xml diff --git a/.gitignore b/.gitignore index cd4f7a7..ba75d8d 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,6 @@ build/ .vscode/ /logs/ + +# Maven shade plugin generated files +dependency-reduced-pom.xml diff --git a/mi-sql-public-demo/dependency-reduced-pom.xml b/mi-sql-public-demo/dependency-reduced-pom.xml deleted file mode 100644 index 9a8898f..0000000 --- a/mi-sql-public-demo/dependency-reduced-pom.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - 4.0.0 - com.example - demo - 1.0-SNAPSHOT - - - - maven-shade-plugin - 3.2.4 - - - package - - shade - - - - - com.example.MainSQL - - - - - *:* - - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - - - - - - - - - - - com.azure.spring - spring-cloud-azure-dependencies - 5.22.0 - pom - import - - - - - 17 - 17 - 17 - - diff --git a/mi-sql-public-demo/src/main/java/com/example/MainSQL.java b/mi-sql-public-demo/src/main/java/com/example/MainSQL.java index bedc095..41b6748 100644 --- a/mi-sql-public-demo/src/main/java/com/example/MainSQL.java +++ b/mi-sql-public-demo/src/main/java/com/example/MainSQL.java @@ -4,6 +4,8 @@ import java.io.IOException; import java.io.InputStream; import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.sql.*; @@ -11,6 +13,33 @@ public class MainSQL { + /** + * Simple placeholder resolver for ${VAR_NAME} and ${VAR_NAME:default} patterns + */ + private static String resolvePlaceholders(String input) { + if (input == null) return null; + + Pattern pattern = Pattern.compile("\\$\\{([^}:]+)(?::([^}]*))?\\}"); + Matcher matcher = pattern.matcher(input); + StringBuffer result = new StringBuffer(); + + while (matcher.find()) { + String varName = matcher.group(1); + String defaultValue = matcher.group(2); + String envValue = System.getenv(varName); + + if (envValue != null) { + matcher.appendReplacement(result, Matcher.quoteReplacement(envValue)); + } else if (defaultValue != null) { + matcher.appendReplacement(result, Matcher.quoteReplacement(defaultValue)); + } else { + // Leave placeholder unresolved + matcher.appendReplacement(result, Matcher.quoteReplacement(matcher.group(0))); + } + } + matcher.appendTail(result); + return result.toString(); + } public static void main(String[] args) { @@ -30,10 +59,29 @@ public static void main(String[] args) { String connString = properties.getProperty("spring.datasource.url"); if (connString == null) { - System.out.println("spring.datasource.url property not found in application.properties"); + System.out.println("ERROR: spring.datasource.url property not found in application.properties"); + return; + } + + // Resolve environment variable placeholders + connString = resolvePlaceholders(connString); + + // Check for unresolved placeholders + if (connString.contains("${AZ_DATABASE_SERVER_NAME}")) { + System.out.println("ERROR: AZ_DATABASE_SERVER_NAME environment variable is not set"); + System.out.println("Please set the AZ_DATABASE_SERVER_NAME environment variable to your Azure SQL server name"); return; } + String clientId = properties.getProperty("spring.cloud.azure.credential.client-id"); + if (clientId != null) { + clientId = resolvePlaceholders(clientId); + if (clientId.contains("${AZURE_CLIENT_ID}")) { + System.out.println("WARNING: AZURE_CLIENT_ID environment variable is not set"); + System.out.println("This is required for user-assigned managed identity, but optional for system-assigned managed identity"); + } + } + System.out.println("Connection string: " + connString); SQLServerDataSource ds = new SQLServerDataSource(); diff --git a/mi-sql-public-demo/src/main/resources/application.properties b/mi-sql-public-demo/src/main/resources/application.properties index ecef929..4301aa0 100644 --- a/mi-sql-public-demo/src/main/resources/application.properties +++ b/mi-sql-public-demo/src/main/resources/application.properties @@ -1,6 +1,6 @@ # Azure SQL Database configuration with Managed Identity -spring.datasource.url=jdbc:sqlserver://${AZ_DATABASE_SERVER_NAME}.database.windows.net:1433;database=demo;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;authentication=ActiveDirectoryMSI +spring.datasource.url=jdbc:sqlserver://${AZ_DATABASE_SERVER_NAME}.database.windows.net:1433;database=${AZ_DATABASE_NAME:demo};encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;authentication=ActiveDirectoryMSI # Azure Managed Identity configuration spring.cloud.azure.credential.managed-identity-enabled=true -spring.cloud.azure.credential.client-id= \ No newline at end of file +spring.cloud.azure.credential.client-id=${AZURE_CLIENT_ID} \ No newline at end of file