From 03f8ab49082d7ea1ffcc7e50f3ef66e5105c5667 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 5 Aug 2020 10:34:30 -0600 Subject: [PATCH 01/47] In progress --- .../azure-identity-spring-library/pom.xml | 36 +++++ .../spring/AzureIdentitySpringHelper.java | 138 ++++++++++++++++++ sdk/spring/pom.xml | 1 + 3 files changed, 175 insertions(+) create mode 100644 sdk/spring/azure-identity-spring-library/pom.xml create mode 100644 sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java diff --git a/sdk/spring/azure-identity-spring-library/pom.xml b/sdk/spring/azure-identity-spring-library/pom.xml new file mode 100644 index 000000000000..55b2917eaa6b --- /dev/null +++ b/sdk/spring/azure-identity-spring-library/pom.xml @@ -0,0 +1,36 @@ + + + + 4.0.0 + + com.azure + azure-spring-boot-service + 1.0.0 + + azure-identity-spring-library + 1.0.0-SNAPSHOT + jar + Azure Identity Spring Integration Library + + UTF-8 + 1.8 + 1.8 + + + + org.springframework + spring-context + 5.2.8.RELEASE + + + org.springframework + spring-core + 5.2.8.RELEASE + + + com.azure + azure-identity + 1.0.9 + + + diff --git a/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java b/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java new file mode 100644 index 000000000000..b786a898f2a8 --- /dev/null +++ b/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + */ +package com.microsoft.azure.identity.spring; + +import com.azure.core.credential.TokenCredential; +import com.azure.identity.ClientCertificateCredentialBuilder; +import com.azure.identity.ClientSecretCredentialBuilder; +import com.azure.identity.DefaultAzureCredentialBuilder; +import java.util.HashMap; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +/** + * A helper class to deal with credentials in a Spring environment. + * + * @author manfred.riem@microsoft.com + */ +@Component +public class AzureIdentitySpringHelper { + + /** + * Defines the AZURE_CREDENTIAL_PREFIX. + */ + private static final String AZURE_CREDENTIAL_PREFIX = "azure.credential."; + + /** + * Stores the named credentials. + */ + private final HashMap credentials; + + /** + * Constructor. + */ + public AzureIdentitySpringHelper() { + credentials = new HashMap<>(); + credentials.put("", new DefaultAzureCredentialBuilder().build()); + } + + /** + * Add a named credential. + * + * @param name the name. + * @param credential the credential. + */ + public void addNamedCredential(String name, TokenCredential credential) { + credentials.put(name, credential); + } + + /** + * Get the default Azure credential. + * + * @return the default Azure credential + */ + public TokenCredential getDefaultCredential() { + return credentials.get(""); + } + + /** + * Get the named credential. + * + * @param name the name. + * @return the named credential, or null if not found. + */ + public TokenCredential getNamedCredential(String name) { + return credentials.get(name); + } + + /** + * Populate from Environment. + * + * @param environment the environment. + */ + public void populate(Environment environment) { + populateNamedCredential(environment, ""); + String credentialNamesKey = AZURE_CREDENTIAL_PREFIX + "names"; + if (environment.containsProperty(credentialNamesKey)) { + String[] credentialNames = environment.getProperty(credentialNamesKey).split(","); + for(int i=0; iazure-spring-boot-starter-servicebus-jms azure-spring-boot-samples azure-spring-boot-tests + azure-identity-spring-library From 7266ac56054a5aa95b8f7126150cb9bffd483968 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Thu, 6 Aug 2020 08:04:47 -0600 Subject: [PATCH 02/47] Throw an exception when configuration is incomplete --- .../azure/identity/spring/AzureIdentitySpringHelper.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java b/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java index b786a898f2a8..c6e017113c2b 100644 --- a/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java +++ b/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java @@ -123,7 +123,10 @@ private void populateNamedCredential(Environment environment, String name) { .pemCertificate(clientCertificatePath) .build(); credentials.put(name, credential); + return; } + + throw new RuntimeException("Configuration for azure.credential" + name + " is incomplete"); } /** From 0de9b4084cdfab84d8d7738f6bf2197d95223e8a Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Thu, 6 Aug 2020 08:18:06 -0600 Subject: [PATCH 03/47] Added class level JavaDoc --- .../spring/AzureIdentitySpringHelper.java | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java b/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java index c6e017113c2b..0e1409c5fdfa 100644 --- a/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java +++ b/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java @@ -14,6 +14,48 @@ /** * A helper class to deal with credentials in a Spring environment. + * + *

+ * This helper class makes it possible to configure credentials to be used + * within a Spring context. + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Property TuplesDescription
+ * azure.credential.(name.)tenantId
+ * azure.credential.(name.)clientId
+ * azure.credential.(name.)clientSecret + *
+ * the Azure Tenant ID
+ * the Client ID
+ * the Client Certificate
+ *
+ * azure.credential.(name.)tenantId
+ * azure.credential.(name.)clientId
+ * azure.credential.(name.)clientCertificate + *
+ * the Azure Tenant ID
+ * the Client ID
+ * the path to the PEM client certificate + *
+ * + * where name is the name of the credential. Note if + * name is entirely omitted it is taken to be the default + * credential. Note if the default credential is omitted it is configure to use + * AzureDefaultCredential which allows for the use a Managed Identity (if it is + * present). * * @author manfred.riem@microsoft.com */ @@ -113,7 +155,7 @@ private void populateNamedCredential(Environment environment, String name) { return; } - String clientCertificateKey = AZURE_CREDENTIAL_PREFIX + name + "clientSecret"; + String clientCertificateKey = AZURE_CREDENTIAL_PREFIX + name + "clientCertificate"; String clientCertificatePath = environment.getProperty(clientCertificateKey); if (clientCertificatePath != null) { From 3964b6871614439e85214eb9559d704f18c389c8 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Thu, 6 Aug 2020 08:41:34 -0600 Subject: [PATCH 04/47] Resolve POM conflict --- sdk/spring/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/spring/pom.xml b/sdk/spring/pom.xml index dd4508739452..fcb70eff1b41 100644 --- a/sdk/spring/pom.xml +++ b/sdk/spring/pom.xml @@ -9,6 +9,7 @@ pom 1.0.0 + azure-identity-spring-library azure-spring-boot azure-spring-boot-starter azure-spring-boot-starter-active-directory @@ -20,7 +21,6 @@ azure-spring-boot-starter-servicebus-jms azure-spring-boot-samples azure-spring-boot-tests - azure-identity-spring-library From 9fb49bae28560dd24ba2134a8e01668153115569 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Thu, 6 Aug 2020 09:22:47 -0600 Subject: [PATCH 05/47] Added unit tests --- .../azure-identity-spring-library/pom.xml | 33 +++++++ .../spring/AzureIdentitySpringHelper.java | 25 ++--- .../spring/AzureIdentitySpringHelperTest.java | 92 +++++++++++++++++++ 3 files changed, 138 insertions(+), 12 deletions(-) create mode 100644 sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelperTest.java diff --git a/sdk/spring/azure-identity-spring-library/pom.xml b/sdk/spring/azure-identity-spring-library/pom.xml index 55b2917eaa6b..bfd1e8106f58 100644 --- a/sdk/spring/azure-identity-spring-library/pom.xml +++ b/sdk/spring/azure-identity-spring-library/pom.xml @@ -16,6 +16,15 @@ 1.8 1.8 + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M5 + + + org.springframework @@ -32,5 +41,29 @@ azure-identity 1.0.9 + + org.junit.jupiter + junit-jupiter-api + 5.6.2 + test + + + org.junit.jupiter + junit-jupiter-params + 5.6.2 + test + + + org.junit.jupiter + junit-jupiter-engine + 5.6.2 + test + + + junit + junit + test + 4.13 + diff --git a/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java b/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java index 0e1409c5fdfa..d7c2712286c0 100644 --- a/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java +++ b/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java @@ -1,7 +1,5 @@ -/* - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. package com.microsoft.azure.identity.spring; import com.azure.core.credential.TokenCredential; @@ -132,14 +130,15 @@ public void populate(Environment environment) { * @param name the name. */ private void populateNamedCredential(Environment environment, String name) { + String standardizedName = name; - if (!name.equals("") && !name.endsWith(".")) { - name = name + "."; + if (!standardizedName.equals("") && !standardizedName.endsWith(".")) { + standardizedName = standardizedName + "."; } - String tenantIdKey = AZURE_CREDENTIAL_PREFIX + name + "tenantId"; - String clientIdKey = AZURE_CREDENTIAL_PREFIX + name + "clientId"; - String clientSecretKey = AZURE_CREDENTIAL_PREFIX + name + "clientSecret"; + String tenantIdKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "tenantId"; + String clientIdKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "clientId"; + String clientSecretKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "clientSecret"; String tenantId = environment.getProperty(tenantIdKey); String clientId = environment.getProperty(clientIdKey); @@ -155,10 +154,10 @@ private void populateNamedCredential(Environment environment, String name) { return; } - String clientCertificateKey = AZURE_CREDENTIAL_PREFIX + name + "clientCertificate"; + String clientCertificateKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "clientCertificate"; String clientCertificatePath = environment.getProperty(clientCertificateKey); - if (clientCertificatePath != null) { + if (tenantId != null && clientId != null && clientCertificatePath != null) { TokenCredential credential = new ClientCertificateCredentialBuilder() .tenantId(tenantId) .clientId(clientId) @@ -168,7 +167,9 @@ private void populateNamedCredential(Environment environment, String name) { return; } - throw new RuntimeException("Configuration for azure.credential" + name + " is incomplete"); + if (!name.equals("")) { + throw new RuntimeException("Configuration for azure.credential." + name + " is incomplete"); + } } /** diff --git a/sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelperTest.java b/sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelperTest.java new file mode 100644 index 000000000000..d8a467aea270 --- /dev/null +++ b/sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelperTest.java @@ -0,0 +1,92 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.microsoft.azure.identity.spring; + +import com.azure.identity.ClientSecretCredential; +import com.azure.identity.DefaultAzureCredential; +import com.azure.identity.DefaultAzureCredentialBuilder; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import org.junit.jupiter.api.Test; +import org.springframework.core.env.StandardEnvironment; + +/** + * The unit tests for the AzureIdentitySpringHelper class. + * + * @author manfred.riem@microsoft.com + */ +public class AzureIdentitySpringHelperTest { + + /** + * Test addNamedCredential method. + */ + @Test + public void testAddNamedCredential() { + DefaultAzureCredential credential = new DefaultAzureCredentialBuilder().build(); + AzureIdentitySpringHelper helper = new AzureIdentitySpringHelper(); + helper.addNamedCredential("cred1", credential); + assertNotNull(helper.getNamedCredential("cred1")); + helper.removeNamedCredential("cred1"); + assertNull(helper.getNamedCredential("cred1")); + } + + /** + * Test getDefaultCredential method. + */ + @Test + public void testGetDefaultCredential() { + AzureIdentitySpringHelper helper = new AzureIdentitySpringHelper(); + assertNotNull(helper.getDefaultCredential()); + } + + /** + * Test populate method. + */ + @Test + public void testPopulate() { + System.setProperty("azure.credential.names", ""); + System.setProperty("azure.credential.tenantId", "tenantId"); + System.setProperty("azure.credential.clientId", "clientId"); + System.setProperty("azure.credential.clientSecret", "clientSecret"); + StandardEnvironment environment = new StandardEnvironment(); + AzureIdentitySpringHelper helper = new AzureIdentitySpringHelper(); + helper.populate(environment); + assertNotNull(helper.getDefaultCredential()); + assertTrue(helper.getDefaultCredential() instanceof ClientSecretCredential); + } + + /** + * Test populate method. + */ + @Test + public void testPopulate2() { + System.setProperty("azure.credential.names", "myname"); + System.setProperty("azure.credential.myname.tenantId", "tenantId"); + System.setProperty("azure.credential.myname.clientId", "clientId"); + System.setProperty("azure.credential.myname.clientSecret", "clientSecret"); + StandardEnvironment environment = new StandardEnvironment(); + AzureIdentitySpringHelper helper = new AzureIdentitySpringHelper(); + helper.populate(environment); + assertNotNull(helper.getNamedCredential("myname")); + assertTrue(helper.getNamedCredential("myname") instanceof ClientSecretCredential); + } + + /** + * Test populate method. + */ + @Test + public void testPopulate3() { + System.setProperty("azure.credential.names", "myname2"); + System.setProperty("azure.credential.myname2.tenantId", "tenantId"); + System.setProperty("azure.credential.myname2.clientSecret", "clientSecret"); + StandardEnvironment environment = new StandardEnvironment(); + AzureIdentitySpringHelper helper = new AzureIdentitySpringHelper(); + try { + helper.populate(environment); + fail(); + } catch(RuntimeException re) { + } + } +} From bedcf50acf160a8a8525b072d9307616fc64574f Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Thu, 13 Aug 2020 15:29:45 -0400 Subject: [PATCH 06/47] Changing the Identity Helper into a builder --- .../spring/AzureIdentitySpringHelper.java | 184 ------------------ .../spring/SpringEnvironmentTokenBuilder.java | 174 +++++++++++++++++ .../spring/AzureIdentitySpringHelperTest.java | 92 --------- .../SpringEnvironmentTokenBuilderTest.java | 88 +++++++++ 4 files changed, 262 insertions(+), 276 deletions(-) delete mode 100644 sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java create mode 100644 sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/SpringEnvironmentTokenBuilder.java delete mode 100644 sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelperTest.java create mode 100644 sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/SpringEnvironmentTokenBuilderTest.java diff --git a/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java b/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java deleted file mode 100644 index d7c2712286c0..000000000000 --- a/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -package com.microsoft.azure.identity.spring; - -import com.azure.core.credential.TokenCredential; -import com.azure.identity.ClientCertificateCredentialBuilder; -import com.azure.identity.ClientSecretCredentialBuilder; -import com.azure.identity.DefaultAzureCredentialBuilder; -import java.util.HashMap; -import org.springframework.core.env.Environment; -import org.springframework.stereotype.Component; - -/** - * A helper class to deal with credentials in a Spring environment. - * - *

- * This helper class makes it possible to configure credentials to be used - * within a Spring context. - *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
Property TuplesDescription
- * azure.credential.(name.)tenantId
- * azure.credential.(name.)clientId
- * azure.credential.(name.)clientSecret - *
- * the Azure Tenant ID
- * the Client ID
- * the Client Certificate
- *
- * azure.credential.(name.)tenantId
- * azure.credential.(name.)clientId
- * azure.credential.(name.)clientCertificate - *
- * the Azure Tenant ID
- * the Client ID
- * the path to the PEM client certificate - *
- * - * where name is the name of the credential. Note if - * name is entirely omitted it is taken to be the default - * credential. Note if the default credential is omitted it is configure to use - * AzureDefaultCredential which allows for the use a Managed Identity (if it is - * present). - * - * @author manfred.riem@microsoft.com - */ -@Component -public class AzureIdentitySpringHelper { - - /** - * Defines the AZURE_CREDENTIAL_PREFIX. - */ - private static final String AZURE_CREDENTIAL_PREFIX = "azure.credential."; - - /** - * Stores the named credentials. - */ - private final HashMap credentials; - - /** - * Constructor. - */ - public AzureIdentitySpringHelper() { - credentials = new HashMap<>(); - credentials.put("", new DefaultAzureCredentialBuilder().build()); - } - - /** - * Add a named credential. - * - * @param name the name. - * @param credential the credential. - */ - public void addNamedCredential(String name, TokenCredential credential) { - credentials.put(name, credential); - } - - /** - * Get the default Azure credential. - * - * @return the default Azure credential - */ - public TokenCredential getDefaultCredential() { - return credentials.get(""); - } - - /** - * Get the named credential. - * - * @param name the name. - * @return the named credential, or null if not found. - */ - public TokenCredential getNamedCredential(String name) { - return credentials.get(name); - } - - /** - * Populate from Environment. - * - * @param environment the environment. - */ - public void populate(Environment environment) { - populateNamedCredential(environment, ""); - String credentialNamesKey = AZURE_CREDENTIAL_PREFIX + "names"; - if (environment.containsProperty(credentialNamesKey)) { - String[] credentialNames = environment.getProperty(credentialNamesKey).split(","); - for(int i=0; i + * This helper class makes it possible to configure credentials to be used + * within a Spring context. + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Property TuplesDescription
azure.credential.(name.)tenantId
+ * azure.credential.(name.)clientId
+ * azure.credential.(name.)clientSecret
the Azure Tenant ID
+ * the Client ID
+ * the Client Certificate
+ *
azure.credential.(name.)tenantId
+ * azure.credential.(name.)clientId
+ * azure.credential.(name.)clientCertificate
the Azure Tenant ID
+ * the Client ID
+ * the path to the PEM client certificate
+ * + * where name is the name of the credential. Note if + * name is entirely omitted it is taken to be the default + * credential. Note if the default credential is omitted it is configure to use + * AzureDefaultCredential which allows for the use a Managed Identity (if it is + * present). + * + * @author manfred.riem@microsoft.com + */ +public class SpringEnvironmentTokenBuilder { + + /** + * Defines the AZURE_CREDENTIAL_PREFIX. + */ + private static final String AZURE_CREDENTIAL_PREFIX = "azure.credential."; + + /** + * Stores the named credentials. + */ + private final HashMap credentials; + + /** + * Stores the name of the credential to be returned. If omitted, the default + * credential will be returned. + */ + private String name = ""; + + /** + * Constructor. + */ + public SpringEnvironmentTokenBuilder() { + credentials = new HashMap<>(); + credentials.put("", new DefaultAzureCredentialBuilder().build()); + } + + /** + * Populate from Environment. + * + * @param environment the environment. + */ + public SpringEnvironmentTokenBuilder fromEnvironment(Environment environment) { + populateNamedCredential(environment, ""); + String credentialNamesKey = AZURE_CREDENTIAL_PREFIX + "names"; + if (environment.containsProperty(credentialNamesKey)) { + String[] credentialNames = environment.getProperty(credentialNamesKey).split(","); + for (int i = 0; i < credentialNames.length; i++) { + populateNamedCredential(environment, credentialNames[i]); + } + } + return this; + } + + /** + * Populate a named credential. + * + * @param environment the environment + * @param name the name. + */ + private void populateNamedCredential(Environment environment, String name) { + String standardizedName = name; + + if (!standardizedName.equals("") && !standardizedName.endsWith(".")) { + standardizedName = standardizedName + "."; + } + + String tenantIdKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "tenantId"; + String clientIdKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "clientId"; + String clientSecretKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "clientSecret"; + + String tenantId = environment.getProperty(tenantIdKey); + String clientId = environment.getProperty(clientIdKey); + String clientSecret = environment.getProperty(clientSecretKey); + + if (tenantId != null && clientId != null && clientSecret != null) { + TokenCredential credential = new ClientSecretCredentialBuilder().tenantId(tenantId).clientId(clientId) + .clientSecret(clientSecret).build(); + credentials.put(name, credential); + return; + } + + String clientCertificateKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "clientCertificate"; + String clientCertificatePath = environment.getProperty(clientCertificateKey); + + if (tenantId != null && clientId != null && clientCertificatePath != null) { + TokenCredential credential = new ClientCertificateCredentialBuilder().tenantId(tenantId).clientId(clientId) + .pemCertificate(clientCertificatePath).build(); + credentials.put(name, credential); + return; + } + + if (!name.equals("")) { + throw new IllegalStateException("Configuration for azure.credential." + name + " is incomplete"); + } + } + + /** + * Sets the builder to return a credential named name + * + * @param name + * @return + */ + public SpringEnvironmentTokenBuilder namedCredential(String name) { + this.name = name; + return this; + } + + /** + * Sets the builder to return the default credential. + */ + public SpringEnvironmentTokenBuilder defaultCredential() { + return namedCredential(""); + } + + /** + * Builds an Azure TokenCredendial. + * + * @throws IllegalArgumentException if attempting to retrieve a named credential + * not defined in the environment. + */ + public TokenCredential build() { + TokenCredential result = credentials.get(name); + if (result == null) { + throw new IllegalArgumentException( + "Attempting to retrieve Azure credential not configured in the environment. (name=" + name + ")"); + } else { + return result; + } + } +} diff --git a/sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelperTest.java b/sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelperTest.java deleted file mode 100644 index d8a467aea270..000000000000 --- a/sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelperTest.java +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -package com.microsoft.azure.identity.spring; - -import com.azure.identity.ClientSecretCredential; -import com.azure.identity.DefaultAzureCredential; -import com.azure.identity.DefaultAzureCredentialBuilder; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; -import org.junit.jupiter.api.Test; -import org.springframework.core.env.StandardEnvironment; - -/** - * The unit tests for the AzureIdentitySpringHelper class. - * - * @author manfred.riem@microsoft.com - */ -public class AzureIdentitySpringHelperTest { - - /** - * Test addNamedCredential method. - */ - @Test - public void testAddNamedCredential() { - DefaultAzureCredential credential = new DefaultAzureCredentialBuilder().build(); - AzureIdentitySpringHelper helper = new AzureIdentitySpringHelper(); - helper.addNamedCredential("cred1", credential); - assertNotNull(helper.getNamedCredential("cred1")); - helper.removeNamedCredential("cred1"); - assertNull(helper.getNamedCredential("cred1")); - } - - /** - * Test getDefaultCredential method. - */ - @Test - public void testGetDefaultCredential() { - AzureIdentitySpringHelper helper = new AzureIdentitySpringHelper(); - assertNotNull(helper.getDefaultCredential()); - } - - /** - * Test populate method. - */ - @Test - public void testPopulate() { - System.setProperty("azure.credential.names", ""); - System.setProperty("azure.credential.tenantId", "tenantId"); - System.setProperty("azure.credential.clientId", "clientId"); - System.setProperty("azure.credential.clientSecret", "clientSecret"); - StandardEnvironment environment = new StandardEnvironment(); - AzureIdentitySpringHelper helper = new AzureIdentitySpringHelper(); - helper.populate(environment); - assertNotNull(helper.getDefaultCredential()); - assertTrue(helper.getDefaultCredential() instanceof ClientSecretCredential); - } - - /** - * Test populate method. - */ - @Test - public void testPopulate2() { - System.setProperty("azure.credential.names", "myname"); - System.setProperty("azure.credential.myname.tenantId", "tenantId"); - System.setProperty("azure.credential.myname.clientId", "clientId"); - System.setProperty("azure.credential.myname.clientSecret", "clientSecret"); - StandardEnvironment environment = new StandardEnvironment(); - AzureIdentitySpringHelper helper = new AzureIdentitySpringHelper(); - helper.populate(environment); - assertNotNull(helper.getNamedCredential("myname")); - assertTrue(helper.getNamedCredential("myname") instanceof ClientSecretCredential); - } - - /** - * Test populate method. - */ - @Test - public void testPopulate3() { - System.setProperty("azure.credential.names", "myname2"); - System.setProperty("azure.credential.myname2.tenantId", "tenantId"); - System.setProperty("azure.credential.myname2.clientSecret", "clientSecret"); - StandardEnvironment environment = new StandardEnvironment(); - AzureIdentitySpringHelper helper = new AzureIdentitySpringHelper(); - try { - helper.populate(environment); - fail(); - } catch(RuntimeException re) { - } - } -} diff --git a/sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/SpringEnvironmentTokenBuilderTest.java b/sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/SpringEnvironmentTokenBuilderTest.java new file mode 100644 index 000000000000..496385d04edf --- /dev/null +++ b/sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/SpringEnvironmentTokenBuilderTest.java @@ -0,0 +1,88 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.microsoft.azure.identity.spring; + +import com.azure.identity.ClientSecretCredential; +import com.azure.identity.DefaultAzureCredential; +import com.azure.identity.DefaultAzureCredentialBuilder; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import org.junit.jupiter.api.Test; +import org.springframework.core.env.StandardEnvironment; + +/** + * The unit tests for the AzureIdentitySpringHelper class. + * + * @author manfred.riem@microsoft.com + */ +public class SpringEnvironmentTokenBuilderTest { + + /** + * Test getDefaultCredential method. + */ + @Test + public void testGetDefaultCredential() { + SpringEnvironmentTokenBuilder builder = new SpringEnvironmentTokenBuilder(); + assertNotNull(builder.build()); + assertEquals(builder.build(), builder.defaultCredential().build()); + } + + /** + * Test populate method. + */ + @Test + public void testPopulate() { + System.setProperty("azure.credential.names", ""); + System.setProperty("azure.credential.tenantId", "tenantId"); + System.setProperty("azure.credential.clientId", "clientId"); + System.setProperty("azure.credential.clientSecret", "clientSecret"); + StandardEnvironment environment = new StandardEnvironment(); + SpringEnvironmentTokenBuilder builder = new SpringEnvironmentTokenBuilder(); + builder.fromEnvironment(environment); + + assertNotNull(builder.build()); + assertTrue(builder.build() instanceof ClientSecretCredential); + assertEquals(builder.build(), builder.defaultCredential().build()); + } + + /** + * Test populate method. + */ + @Test + public void testPopulate2() { + System.setProperty("azure.credential.names", "myname"); + System.setProperty("azure.credential.myname.tenantId", "tenantId"); + System.setProperty("azure.credential.myname.clientId", "clientId"); + System.setProperty("azure.credential.myname.clientSecret", "clientSecret"); + StandardEnvironment environment = new StandardEnvironment(); + SpringEnvironmentTokenBuilder builder = new SpringEnvironmentTokenBuilder(); + builder.fromEnvironment(environment); + assertNotNull(builder.namedCredential("myname").build()); + assertTrue(builder.build() instanceof ClientSecretCredential); + assertNotEquals(builder.build(), builder.defaultCredential().build()); + } + + /** + * Test populate method. + */ + @Test + public void testPopulate3() { + System.setProperty("azure.credential.names", "myname2"); + System.setProperty("azure.credential.myname2.tenantId", "tenantId"); + System.setProperty("azure.credential.myname2.clientSecret", "clientSecret"); + StandardEnvironment environment = new StandardEnvironment(); + SpringEnvironmentTokenBuilder builder = new SpringEnvironmentTokenBuilder(); + try { + builder.fromEnvironment(environment); + fail(); + } catch (Throwable t) { + assertEquals(IllegalStateException.class, t.getClass(), + "Unexpected exception class on missing configuration field."); + } + } +} From 9ad8a7989bc65e5d4477c4e494e07ae7a2f6c01e Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Fri, 14 Aug 2020 21:45:21 -0400 Subject: [PATCH 07/47] Adding storage resource sample, autoconfiguration for blob storage with default identity --- .../azure-identity-spring-library/pom.xml | 2 +- .../README.adoc | 113 ++++++++ .../pom.xml | 58 ++++ .../main/java/com/example/BlobController.java | 43 +++ .../java/com/example/StorageApplication.java | 21 ++ .../src/main/resources/application.properties | 24 ++ .../com/example/StorageApplicationIT.java | 50 ++++ .../resources/application-test.properties | 8 + .../main/resources/META-INF/spring.provides | 2 +- sdk/spring/azure-spring-cloud-storage/pom.xml | 265 +++++++++--------- .../AzureStorageAutoConfiguration.java | 94 ++++--- sdk/spring/pom.xml | 1 + 12 files changed, 510 insertions(+), 171 deletions(-) create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/README.adoc create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/pom.xml create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/BlobController.java create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/StorageApplication.java create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/java/com/example/StorageApplicationIT.java create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/resources/application-test.properties diff --git a/sdk/spring/azure-identity-spring-library/pom.xml b/sdk/spring/azure-identity-spring-library/pom.xml index bfd1e8106f58..457d1880c49b 100644 --- a/sdk/spring/azure-identity-spring-library/pom.xml +++ b/sdk/spring/azure-identity-spring-library/pom.xml @@ -8,9 +8,9 @@ 1.0.0 azure-identity-spring-library - 1.0.0-SNAPSHOT jar Azure Identity Spring Integration Library + 1.0.0-beta.1 UTF-8 1.8 diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/README.adoc b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/README.adoc new file mode 100644 index 000000000000..4a721ed4e225 --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/README.adoc @@ -0,0 +1,113 @@ += Spring Cloud Azure Storage Starter Sample + +This code sample demonstrates how to read and write files with the Spring Resource abstraction for Azure Storage using +the +link:../../spring-cloud-azure-starters/spring-starter-azure-storage[Spring Cloud Azure Storage Starter].Running this sample will be charged by Azure. You can check the usage and bill at https://azure.microsoft.com/en-us/account/[this link]. + +Running this sample will be charged by Azure. You can check the usage and bill at https://azure.microsoft.com/en-us/account/[this link]. + +Maven coordinates: + +[source,xml] +---- + + com.microsoft.azure + spring-starter-azure-storage + +---- + +Gradle coordinates: + +[source] +---- +dependencies { + compile group: 'com.microsoft.azure', name: 'spring-starter-azure-storage' +} +---- + +== Access key based usage + +1. Create https://docs.microsoft.com/en-us/azure/storage/[Azure Storage] + +2. Update link:src/main/resources/application.properties[application.properties] + ++ +.... +spring.cloud.azure.storage.account=[storage-account-name] + +# Fill storage account access key copied from portal +spring.cloud.azure.storage.access-key=[storage-account-accesskey] + +.... + +== Credential file based usage + +1. Create azure credential file. Please see https://github.com/Azure/azure-libraries-for-java/blob/master/AUTH.md[how to create credential file]. ++ +.... +$ az login +$ az account set --subscription +$ az ad sp create-for-rbac --sdk-auth > my.azureauth +.... ++ +Make sure `my.azureauth` is encoded with UTF-8. + +2. Put credential file under `src/main/resources/`. + +3. Create https://docs.microsoft.com/en-us/azure/storage/[Azure Storage]. Or enable auto create +resources feature in link:src/main/resources/application.properties[application.properties]: ++ +.... +spring.cloud.azure.auto-create-resources=true + +# Example region is westUS, northchina +spring.cloud.azure.region=[region] +.... + +5. Update link:src/main/resources/application.properties[application.properties] ++ +.... + +# Enter 'my.azureauth' here if following step 1 and 2 +spring.cloud.azure.credential-file-path=[credential-file-path] + +spring.cloud.azure.resource-group=[resource-group] + +spring.cloud.azure.storage.account=[account-name] +.... + +== How to run + +5. Update link:src/main/resources/application.properties[application.properties] + ++ +.... + +# Default environment is GLOBAL. Provide your own if in another environment +# Example environment is China, GLOBAL +# spring.cloud.azure.environment=[environment] + +# Change into your containerName, blobName +blob=azure-blob://containerName/blobName + +.... + +6. Start the `StorageApplication` Spring Boot app. ++ +``` +$ mvn spring-boot:run +``` + +7. Send a POST request to update file contents: ++ +``` +$ curl -d 'new message' -H 'Content-Type: text/plain' localhost:8080/blob +``` ++ +Verify by sending a GET request ++ +``` +$ curl -XGET http://localhost:8080/blob +``` + +8. Delete the resources on http://ms.portal.azure.com/[Azure Portal] to avoid unexpected charges. diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/pom.xml b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/pom.xml new file mode 100644 index 000000000000..2e255d1546df --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/pom.xml @@ -0,0 +1,58 @@ + + + + com.azure + azure-spring-boot-service + 1.0.0 + ../.. + + 4.0.0 + + 1.8 + 1.8 + 2.3.3.RELEASE + + + azure-spring-boot-sample-storage-resource + Spring Cloud Azure Storage Resource Sample + + + com.microsoft.azure + spring-starter-azure-storage + 1.2.8-beta.1 + + + + org.springframework.boot + spring-boot-starter + ${spring.boot.version} + + + + org.springframework.boot + spring-boot-starter-web + ${spring.boot.version} + + + + junit + junit + 4.12 + test + + + org.springframework.boot + spring-boot-starter-test + ${spring.boot.version} + test + + + org.junit.vintage + junit-vintage-engine + + + + + + + diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/BlobController.java b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/BlobController.java new file mode 100644 index 000000000000..34d07941b451 --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/BlobController.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See LICENSE in the project root for + * license information. + */ + +package com.example; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.Resource; +import org.springframework.core.io.WritableResource; +import org.springframework.util.StreamUtils; +import org.springframework.web.bind.annotation.*; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.Charset; + +/** + * @author Warren Zhu + */ +@RestController +@RequestMapping("blob") +public class BlobController { + + @Value("${blob}") + private Resource blobFile; + + @GetMapping + public String readBlobFile() throws IOException { + return StreamUtils.copyToString( + this.blobFile.getInputStream(), + Charset.defaultCharset()); + } + + @PostMapping + public String writeBlobFile(@RequestBody String data) throws IOException { + try (OutputStream os = ((WritableResource) this.blobFile).getOutputStream()) { + os.write(data.getBytes()); + } + return "file was updated"; + } +} diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/StorageApplication.java b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/StorageApplication.java new file mode 100644 index 000000000000..e9f5752e9d70 --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/StorageApplication.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See LICENSE in the project root for + * license information. + */ + +package com.example; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author Warren Zhu + */ +@SpringBootApplication +public class StorageApplication { + + public static void main(String[] args) { + SpringApplication.run(StorageApplication.class, args); + } +} diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties new file mode 100644 index 000000000000..d48ad9e5632b --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties @@ -0,0 +1,24 @@ +# Credential file based usage + +spring.cloud.azure.credential-file-path=[credential-file-path] +spring.cloud.azure.resource-group=[resource-group] + +# Access key based usage + +# Fill storage account access key copied from portal +# spring.cloud.azure.storage.access-key=[storage-account-accesskey] + +# Storage account name length should be between 3 and 24 +# and use numbers and lower-case letters only. +spring.cloud.azure.storage.account=[account-name] + +# Change into your containerName and blobName +blob=azure-blob://containerName/blobName + +# spring.cloud.azure.auto-create-resources=true + +# Default environment is GLOBAL. Provide your own if in another environment +# Example environment is China, GLOBAL +# spring.cloud.azure.environment=[environment] +# Example region is westUS, northchina +# spring.cloud.azure.region=[region] diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/java/com/example/StorageApplicationIT.java b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/java/com/example/StorageApplicationIT.java new file mode 100644 index 000000000000..9d7193b29265 --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/java/com/example/StorageApplicationIT.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See LICENSE in the project root for + * license information. + */ +package com.example; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import java.util.UUID; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = StorageApplication.class) +@AutoConfigureMockMvc +@TestPropertySource( + locations = "classpath:application-test.properties") +public class StorageApplicationIT { + + @Autowired + private MockMvc mvc; + + @Test + public void testPostAndGetSuccess() + throws Exception { + String content = UUID.randomUUID().toString(); + + mvc.perform(post("/blob") + .contentType(MediaType.APPLICATION_JSON).content(content)) + .andExpect(status().isOk()) + .andExpect(content().string("file was updated")); + + mvc.perform(get("/blob") + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string(content)); + } +} diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/resources/application-test.properties b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/resources/application-test.properties new file mode 100644 index 000000000000..197151f76113 --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/resources/application-test.properties @@ -0,0 +1,8 @@ +spring.cloud.azure.credential-file-path=file:@credential@ +spring.cloud.azure.resource-group=spring-cloud + +blob=azure-blob://container1/blob1 +spring.cloud.azure.storage.account=springcloud + +spring.cloud.azure.region=westUS +spring.cloud.azure.auto-create-resources=true diff --git a/sdk/spring/azure-spring-cloud-starter-storage/src/main/resources/META-INF/spring.provides b/sdk/spring/azure-spring-cloud-starter-storage/src/main/resources/META-INF/spring.provides index 6ac0341c54f5..166f52fb2739 100644 --- a/sdk/spring/azure-spring-cloud-starter-storage/src/main/resources/META-INF/spring.provides +++ b/sdk/spring/azure-spring-cloud-starter-storage/src/main/resources/META-INF/spring.provides @@ -1 +1 @@ -provides: spring-cloud-azure-context, spring-cloud-azure-autoconfigure +provides: spring-cloud-azure-context, spring-cloud-azure-storage diff --git a/sdk/spring/azure-spring-cloud-storage/pom.xml b/sdk/spring/azure-spring-cloud-storage/pom.xml index daf98e404114..98e83d234182 100644 --- a/sdk/spring/azure-spring-cloud-storage/pom.xml +++ b/sdk/spring/azure-spring-cloud-storage/pom.xml @@ -1,132 +1,139 @@ - - com.azure - azure-client-sdk-parent - 1.7.0 - ../../parents/azure-client-sdk-parent - - 4.0.0 - - com.microsoft.azure - spring-cloud-azure-storage - 1.2.8-beta.1 - - Spring Cloud Azure Storage - - - - com.microsoft.azure - spring-cloud-azure-context - 1.2.8-beta.1 - - - - com.microsoft.azure - spring-cloud-azure-telemetry - 1.2.8-beta.1 - - - com.azure - azure-storage-blob - 12.7.0 - - - - com.azure - azure-storage-file-share - 12.5.0 - - - - - com.azure - azure-storage-queue - 12.5.2 - true - - - - - com.microsoft.azure - spring-integration-storage-queue - 1.2.8-beta.1 - true - - - - org.hibernate.validator - hibernate-validator - 6.1.5.Final - - - - org.springframework.boot - spring-boot-starter-test - 2.3.2.RELEASE - test - - - - junit - junit - 4.13 - test - - - - org.mockito - mockito-core - 3.3.3 - test - - - - org.powermock - powermock-api-mockito2 - 2.0.2 - test - - - - org.powermock - powermock-module-junit4 - 2.0.2 - test - - - - - com.google.code.findbugs - jsr305 - 3.0.2 - provided - - - - - - - org.apache.maven.plugins - maven-enforcer-plugin - 3.0.0-M3 - - - - - com.microsoft.azure:spring-cloud-azure-context:[1.2.8-beta.1] - com.microsoft.azure:spring-cloud-azure-telemetry:[1.2.8-beta.1] - com.microsoft.azure:spring-integration-storage-queue:[1.2.8-beta.1] - org.hibernate.validator:hibernate-validator:[6.1.5.Final] - - - - - - - + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + com.azure + azure-client-sdk-parent + 1.7.0 + ../../parents/azure-client-sdk-parent + + 4.0.0 + + com.microsoft.azure + spring-cloud-azure-storage + 1.2.8-beta.1 + + Spring Cloud Azure Storage + + + + com.microsoft.azure + spring-cloud-azure-context + 1.2.8-beta.1 + + + + com.microsoft.azure + spring-cloud-azure-telemetry + 1.2.8-beta.1 + + + + com.azure + azure-identity-spring-library + 1.0.0-beta.1 + + + + com.azure + azure-storage-blob + 12.7.0 + + + + com.azure + azure-storage-file-share + 12.5.0 + + + + + com.azure + azure-storage-queue + 12.5.2 + true + + + + + com.microsoft.azure + spring-integration-storage-queue + 1.2.8-beta.1 + true + + + + org.hibernate.validator + hibernate-validator + 6.1.5.Final + + + + org.springframework.boot + spring-boot-starter-test + 2.3.2.RELEASE + test + + + + junit + junit + 4.13 + test + + + + org.mockito + mockito-core + 3.3.3 + test + + + + org.powermock + powermock-api-mockito2 + 2.0.2 + test + + + + org.powermock + powermock-module-junit4 + 2.0.2 + test + + + + + com.google.code.findbugs + jsr305 + 3.0.2 + provided + + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.0.0-M3 + + + + + com.microsoft.azure:spring-cloud-azure-context:[1.2.8-beta.1] + com.microsoft.azure:spring-cloud-azure-telemetry:[1.2.8-beta.1] + com.microsoft.azure:spring-integration-storage-queue:[1.2.8-beta.1] + org.hibernate.validator:hibernate-validator:[6.1.5.Final] + + + + + + + diff --git a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java index 21a860284e09..cc0d773626ca 100644 --- a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java @@ -3,16 +3,12 @@ package com.microsoft.azure.spring.cloud.autoconfigure.storage; -import com.azure.core.http.policy.HttpLogOptions; -import com.azure.storage.blob.BlobServiceClientBuilder; -import com.azure.storage.file.share.ShareServiceClientBuilder; -import com.microsoft.azure.management.storage.StorageAccount; -import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; -import com.microsoft.azure.spring.cloud.context.core.api.EnvironmentProvider; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; -import com.microsoft.azure.spring.cloud.context.core.storage.StorageConnectionStringProvider; -import com.microsoft.azure.spring.cloud.storage.AzureStorageProtocolResolver; -import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; +import static com.microsoft.azure.spring.cloud.context.core.util.Constants.SPRING_CLOUD_STORAGE_BLOB_APPLICATION_ID; +import static com.microsoft.azure.spring.cloud.context.core.util.Constants.SPRING_CLOUD_STORAGE_FILE_SHARE_APPLICATION_ID; + +import javax.annotation.PostConstruct; + +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -24,11 +20,20 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.core.env.Environment; -import javax.annotation.PostConstruct; - -import static com.microsoft.azure.spring.cloud.context.core.util.Constants.SPRING_CLOUD_STORAGE_BLOB_APPLICATION_ID; -import static com.microsoft.azure.spring.cloud.context.core.util.Constants.SPRING_CLOUD_STORAGE_FILE_SHARE_APPLICATION_ID; +import com.azure.core.credential.TokenCredential; +import com.azure.core.http.policy.HttpLogOptions; +import com.azure.storage.blob.BlobServiceClientBuilder; +import com.azure.storage.file.share.ShareServiceClientBuilder; +import com.microsoft.azure.identity.spring.SpringEnvironmentTokenBuilder; +import com.microsoft.azure.management.storage.StorageAccount; +import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; +import com.microsoft.azure.spring.cloud.context.core.api.EnvironmentProvider; +import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; +import com.microsoft.azure.spring.cloud.context.core.storage.StorageConnectionStringProvider; +import com.microsoft.azure.spring.cloud.storage.AzureStorageProtocolResolver; +import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; /** * An auto-configuration for Azure Storage Account @@ -37,7 +42,7 @@ */ @Configuration @AutoConfigureAfter(AzureContextAutoConfiguration.class) -@ConditionalOnClass({BlobServiceClientBuilder.class, ShareServiceClientBuilder.class}) +@ConditionalOnClass({ BlobServiceClientBuilder.class, ShareServiceClientBuilder.class }) @ConditionalOnProperty(name = "spring.cloud.azure.storage.account") @EnableConfigurationProperties(AzureStorageProperties.class) public class AzureStorageAutoConfiguration { @@ -53,54 +58,63 @@ public void collectTelemetry() { TelemetryCollector.getInstance().addService(STORAGE); } + @Autowired + private Environment environment; + @Bean @ConditionalOnMissingBean public BlobServiceClientBuilder blobServiceClientBuilder(AzureStorageProperties storageProperties, - EnvironmentProvider environmentProvider) { - String connectionString; + EnvironmentProvider environmentProvider) { + + BlobServiceClientBuilder authenticatedClientBuilder = null; + + // Use storage credentials where provided, default identity otherwise. + if (StringUtils.isNotBlank(storageProperties.getAccessKey())) { + String connectionString = null; + if (resourceManagerProvider != null) { + StorageAccount storageAccount = resourceManagerProvider.getStorageAccountManager() + .getOrCreate(storageProperties.getAccount()); + connectionString = StorageConnectionStringProvider.getConnectionString(storageAccount, + environmentProvider.getEnvironment(), storageProperties.isSecureTransfer()); + } else { + connectionString = StorageConnectionStringProvider.getConnectionString(storageProperties.getAccount(), + storageProperties.getAccessKey(), environmentProvider.getEnvironment()); + TelemetryCollector.getInstance().addProperty(STORAGE, ACCOUNT_NAME, storageProperties.getAccount()); + } + authenticatedClientBuilder = new BlobServiceClientBuilder().connectionString(connectionString); - if (resourceManagerProvider != null) { - String accountName = storageProperties.getAccount(); - - StorageAccount storageAccount = resourceManagerProvider.getStorageAccountManager().getOrCreate(accountName); - connectionString = StorageConnectionStringProvider.getConnectionString(storageAccount, - environmentProvider.getEnvironment(), storageProperties.isSecureTransfer()); } else { - connectionString = StorageConnectionStringProvider - .getConnectionString(storageProperties.getAccount(), storageProperties.getAccessKey(), - environmentProvider.getEnvironment()); - TelemetryCollector.getInstance().addProperty(STORAGE, ACCOUNT_NAME, storageProperties.getAccount()); + TokenCredential defaultIdentityCredential = new SpringEnvironmentTokenBuilder().fromEnvironment(environment) + .defaultCredential().build(); + authenticatedClientBuilder = new BlobServiceClientBuilder().credential(defaultIdentityCredential); } - - return new BlobServiceClientBuilder().connectionString(connectionString) - .httpLogOptions(new HttpLogOptions().setApplicationId(SPRING_CLOUD_STORAGE_BLOB_APPLICATION_ID)); + return authenticatedClientBuilder + .httpLogOptions(new HttpLogOptions().setApplicationId(SPRING_CLOUD_STORAGE_BLOB_APPLICATION_ID)); } @Bean @ConditionalOnMissingBean public ShareServiceClientBuilder shareServiceClientBuilder(AzureStorageProperties storageProperties, - EnvironmentProvider environmentProvider) { + EnvironmentProvider environmentProvider) { String connectionString; - + String connectionString1; if (resourceManagerProvider != null) { String accountName = storageProperties.getAccount(); StorageAccount storageAccount = resourceManagerProvider.getStorageAccountManager().getOrCreate(accountName); - - connectionString = StorageConnectionStringProvider - .getConnectionString(storageAccount, environmentProvider.getEnvironment(), - storageProperties.isSecureTransfer()); + connectionString1 = StorageConnectionStringProvider.getConnectionString(storageAccount, + environmentProvider.getEnvironment(), storageProperties.isSecureTransfer()); } else { - connectionString = StorageConnectionStringProvider - .getConnectionString(storageProperties.getAccount(), storageProperties.getAccessKey(), - environmentProvider.getEnvironment()); + connectionString1 = StorageConnectionStringProvider.getConnectionString(storageProperties.getAccount(), + storageProperties.getAccessKey(), environmentProvider.getEnvironment()); TelemetryCollector.getInstance().addProperty(STORAGE, ACCOUNT_NAME, storageProperties.getAccount()); } + connectionString = connectionString1; return new ShareServiceClientBuilder().connectionString(connectionString) - .httpLogOptions(new HttpLogOptions().setApplicationId(SPRING_CLOUD_STORAGE_FILE_SHARE_APPLICATION_ID)); + .httpLogOptions(new HttpLogOptions().setApplicationId(SPRING_CLOUD_STORAGE_FILE_SHARE_APPLICATION_ID)); } @Configuration diff --git a/sdk/spring/pom.xml b/sdk/spring/pom.xml index 31f42d9a988f..b5e6eab755e2 100644 --- a/sdk/spring/pom.xml +++ b/sdk/spring/pom.xml @@ -37,6 +37,7 @@ azure-spring-boot-samples/azure-spring-boot-sample-servicebus-jms-queue azure-spring-boot-samples/azure-spring-boot-sample-servicebus-jms-topic azure-spring-boot-samples/azure-spring-boot-sample-storage-blob + azure-spring-boot-samples/azure-spring-boot-sample-storage-resource azure-spring-boot-samples/azure-spring-data-sample-gremlin azure-spring-boot-samples/azure-spring-data-sample-gremlin-web-service azure-spring-boot-samples/azure-cloud-foundry-service-sample From f9adbe0ae855934580faffb633fb07ed49cb2ae4 Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Sun, 16 Aug 2020 23:17:33 -0400 Subject: [PATCH 08/47] Attempting to generate an endpoint string --- .../src/main/resources/application.properties | 12 +++++----- .../StorageConnectionStringBuilder.java | 24 +++++++++++++++---- .../AzureStorageAutoConfiguration.java | 6 ++++- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties index d48ad9e5632b..f039956ab7b8 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties @@ -1,7 +1,7 @@ # Credential file based usage -spring.cloud.azure.credential-file-path=[credential-file-path] -spring.cloud.azure.resource-group=[resource-group] +# spring.cloud.azure.credential-file-path=[credential-file-path] +# spring.cloud.azure.resource-group=test # Access key based usage @@ -10,15 +10,15 @@ spring.cloud.azure.resource-group=[resource-group] # Storage account name length should be between 3 and 24 # and use numbers and lower-case letters only. -spring.cloud.azure.storage.account=[account-name] +spring.cloud.azure.storage.account=ybstorgtest # Change into your containerName and blobName -blob=azure-blob://containerName/blobName +blob=azure-blob://tainer/yevblob -# spring.cloud.azure.auto-create-resources=true +spring.cloud.azure.auto-create-resources=true # Default environment is GLOBAL. Provide your own if in another environment # Example environment is China, GLOBAL # spring.cloud.azure.environment=[environment] # Example region is westUS, northchina -# spring.cloud.azure.region=[region] +spring.cloud.azure.region=centralus diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/storage/StorageConnectionStringBuilder.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/storage/StorageConnectionStringBuilder.java index 5cfb0856e6f6..1071a208efc7 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/storage/StorageConnectionStringBuilder.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/storage/StorageConnectionStringBuilder.java @@ -5,6 +5,7 @@ import com.microsoft.azure.AzureEnvironment; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; public class StorageConnectionStringBuilder { @@ -23,20 +24,33 @@ public class StorageConnectionStringBuilder { private static final String SEPARATOR = ";"; - public static String build(String accountName, String accountKey, AzureEnvironment environment, boolean - isSecureTransfer) { + private static String build(String accountName, Optional accountKey, AzureEnvironment environment, + boolean isSecureTransfer) { Map map = new HashMap<>(); map.put(DEFAULT_PROTOCOL, resolveProtocol(isSecureTransfer)); map.put(ACCOUNT_NAME, accountName); - map.put(ACCOUNT_KEY, accountKey); - // Remove starting dot since AzureEnvironment.storageEndpointSuffix() starts with dot + + if (accountKey.isPresent()) { + map.put(ACCOUNT_KEY, accountKey.get()); + } + // Remove starting dot since AzureEnvironment.storageEndpointSuffix() starts + // with dot map.put(ENDPOINT_SUFFIX, environment.storageEndpointSuffix().substring(1)); return map.entrySet().stream().map(Object::toString).collect(Collectors.joining(SEPARATOR)); } + public static String build(String accountName, String accountKey, AzureEnvironment environment, + boolean isSecureTransfer) { + return build(accountName, Optional.of(accountKey), environment, isSecureTransfer); + } + public static String build(String accountName, String accountKey, AzureEnvironment environment) { - return build(accountName, accountKey, environment, true); + return build(accountName, Optional.of(accountKey), environment, true); + } + + public static String build(String accountName, AzureEnvironment environment, boolean isSecureTransfer) { + return build(accountName, Optional.empty(), environment, isSecureTransfer); } private static String resolveProtocol(boolean isSecureTransfer) { diff --git a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java index cc0d773626ca..1913b3e6ef01 100644 --- a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java @@ -31,6 +31,7 @@ import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; import com.microsoft.azure.spring.cloud.context.core.api.EnvironmentProvider; import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; +import com.microsoft.azure.spring.cloud.context.core.storage.StorageConnectionStringBuilder; import com.microsoft.azure.spring.cloud.context.core.storage.StorageConnectionStringProvider; import com.microsoft.azure.spring.cloud.storage.AzureStorageProtocolResolver; import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; @@ -86,7 +87,10 @@ public BlobServiceClientBuilder blobServiceClientBuilder(AzureStorageProperties } else { TokenCredential defaultIdentityCredential = new SpringEnvironmentTokenBuilder().fromEnvironment(environment) .defaultCredential().build(); - authenticatedClientBuilder = new BlobServiceClientBuilder().credential(defaultIdentityCredential); + String connectionString = StorageConnectionStringBuilder.build(storageProperties.getAccount(), + environmentProvider.getEnvironment(), storageProperties.isSecureTransfer()); + authenticatedClientBuilder = new BlobServiceClientBuilder().credential(defaultIdentityCredential) + .connectionString(connectionString); } return authenticatedClientBuilder From 9cac0d30bd28427128d745571647a3f71ec70b1a Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Thu, 20 Aug 2020 20:12:21 -0400 Subject: [PATCH 09/47] Provisional workaround for using IdentityToken in Shared service connections --- sdk/spring/azure-spring-cloud-context/pom.xml | 211 +++++++++--------- .../AzureEnvironmentAutoConfiguration.java | 3 + .../context/core/api/EnvironmentProvider.java | 14 ++ .../storage/StorageEndpointStringBuilder.java | 20 ++ sdk/spring/azure-spring-cloud-storage/pom.xml | 6 + .../AzureStorageAutoConfiguration.java | 63 ++++-- .../storage/AzureStorageProperties.java | 10 + 7 files changed, 208 insertions(+), 119 deletions(-) create mode 100644 sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/storage/StorageEndpointStringBuilder.java diff --git a/sdk/spring/azure-spring-cloud-context/pom.xml b/sdk/spring/azure-spring-cloud-context/pom.xml index ccaeaedd2411..e783c38b3599 100644 --- a/sdk/spring/azure-spring-cloud-context/pom.xml +++ b/sdk/spring/azure-spring-cloud-context/pom.xml @@ -1,115 +1,122 @@ - - com.azure - azure-client-sdk-parent - 1.7.0 - ../../parents/azure-client-sdk-parent - - 4.0.0 + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + com.azure + azure-client-sdk-parent + 1.7.0 + ../../parents/azure-client-sdk-parent + + 4.0.0 - com.microsoft.azure - spring-cloud-azure-context - 1.2.8-beta.1 + com.microsoft.azure + spring-cloud-azure-context + 1.2.8-beta.1 - Spring Cloud Azure Context - https://github.com/Azure/azure-sdk-for-java + Spring Cloud Azure Context + https://github.com/Azure/azure-sdk-for-java - - 0.10 - 0.15 - + + 0.10 + 0.15 + - - - org.springframework - spring-context - 5.2.8.RELEASE - - - org.springframework.boot - spring-boot-starter-aop - 2.3.2.RELEASE - + + + org.springframework + spring-context + 5.2.8.RELEASE + + + org.springframework.boot + spring-boot-starter-aop + 2.3.2.RELEASE + - - org.springframework - spring-context-support - 5.2.8.RELEASE - true - - - commons-io - commons-io - 2.5 - + + org.springframework + spring-context-support + 5.2.8.RELEASE + true + + + commons-io + commons-io + 2.5 + - - com.microsoft.azure - azure - 1.34.0 - - - com.microsoft.azure - spring-cloud-azure-telemetry - 1.2.8-beta.1 - + + com.microsoft.azure + azure + 1.34.0 + + + com.azure + azure-core-management + 1.0.0-beta.2 + - - - com.google.code.findbugs - jsr305 - 3.0.2 - provided - - - - junit - junit - 4.13 - test - - - org.mockito - mockito-core - 3.3.3 - test - - - org.springframework.boot - spring-boot-starter-test - 2.3.2.RELEASE - test - + + com.microsoft.azure + spring-cloud-azure-telemetry + 1.2.8-beta.1 + - + + + com.google.code.findbugs + jsr305 + 3.0.2 + provided + - - - - org.apache.maven.plugins - maven-enforcer-plugin - 3.0.0-M3 - - - - - com.microsoft.azure:spring-cloud-azure-telemetry:[1.2.8-beta.1] - com.microsoft.azure:azure:[1.34.0] - commons-io:commons-io:[2.5] - org.springframework:spring-context:[5.2.8.RELEASE] - org.springframework:spring-context-support:[5.2.8.RELEASE] - org.springframework.boot:spring-boot-starter-aop:[2.3.2.RELEASE] - - - - - - - + + + junit + junit + 4.13 + test + + + org.mockito + mockito-core + 3.3.3 + test + + + org.springframework.boot + spring-boot-starter-test + 2.3.2.RELEASE + test + + + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.0.0-M3 + + + + + com.microsoft.azure:spring-cloud-azure-telemetry:[1.2.8-beta.1] + com.microsoft.azure:azure:[1.34.0] + commons-io:commons-io:[2.5] + org.springframework:spring-context:[5.2.8.RELEASE] + org.springframework:spring-context-support:[5.2.8.RELEASE] + org.springframework.boot:spring-boot-starter-aop:[2.3.2.RELEASE] + + + + + + + diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureEnvironmentAutoConfiguration.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureEnvironmentAutoConfiguration.java index 69010683afa6..11314ae04b50 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureEnvironmentAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureEnvironmentAutoConfiguration.java @@ -32,4 +32,7 @@ public EnvironmentProvider environmentProvider() { return defaultEnvironmentProvider; } + + + } diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/api/EnvironmentProvider.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/api/EnvironmentProvider.java index afbd8a74b3d6..ac0a775b2260 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/api/EnvironmentProvider.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/api/EnvironmentProvider.java @@ -3,6 +3,8 @@ package com.microsoft.azure.spring.cloud.context.core.api; +import java.util.Arrays; + import com.microsoft.azure.AzureEnvironment; /** @@ -13,4 +15,16 @@ public interface EnvironmentProvider { AzureEnvironment getEnvironment(); + + /** + * @return The Azure environment as defined by the + * com.azure.core.management SDK. + */ + default com.azure.core.management.AzureEnvironment getCoreEnvironment() { + return Arrays.stream(com.azure.core.management.AzureEnvironment.knownEnvironments()) + .filter(coreEnvironment -> getEnvironment().managementEndpoint() + .equals(coreEnvironment.getManagementEndpoint())) + .findAny().get(); + } + } diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/storage/StorageEndpointStringBuilder.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/storage/StorageEndpointStringBuilder.java new file mode 100644 index 000000000000..9f67fc2fa7ed --- /dev/null +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/storage/StorageEndpointStringBuilder.java @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.microsoft.azure.spring.cloud.context.core.storage; + +import com.microsoft.azure.AzureEnvironment; + +public class StorageEndpointStringBuilder { + public static String buildBlobEndpoint(String storageAccount, AzureEnvironment azureEnvironment, + boolean isSecureTransfer) { + String scheme = isSecureTransfer ? "https://" : "http://"; + return scheme + storageAccount + ".blob" + azureEnvironment.storageEndpointSuffix(); + } + + public static String buildSharesEndpoint(String storageAccount, AzureEnvironment azureEnvironment, + boolean isSecureTransfer) { + String scheme = isSecureTransfer ? "https://" : "http://"; + return scheme + storageAccount + ".file" + azureEnvironment.storageEndpointSuffix(); + } +} diff --git a/sdk/spring/azure-spring-cloud-storage/pom.xml b/sdk/spring/azure-spring-cloud-storage/pom.xml index 98e83d234182..0215bb696a4a 100644 --- a/sdk/spring/azure-spring-cloud-storage/pom.xml +++ b/sdk/spring/azure-spring-cloud-storage/pom.xml @@ -29,6 +29,12 @@ 1.2.8-beta.1 + + com.azure.resourcemanager + azure-resourcemanager-storage + 2.0.0-beta.3 + + com.azure azure-identity-spring-library diff --git a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java index 1913b3e6ef01..a41482f72e22 100644 --- a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java @@ -6,6 +6,8 @@ import static com.microsoft.azure.spring.cloud.context.core.util.Constants.SPRING_CLOUD_STORAGE_BLOB_APPLICATION_ID; import static com.microsoft.azure.spring.cloud.context.core.util.Constants.SPRING_CLOUD_STORAGE_FILE_SHARE_APPLICATION_ID; +import java.util.Collections; + import javax.annotation.PostConstruct; import org.apache.commons.lang3.StringUtils; @@ -23,16 +25,24 @@ import org.springframework.core.env.Environment; import com.azure.core.credential.TokenCredential; +import com.azure.core.http.HttpClient; +import com.azure.core.http.HttpPipeline; import com.azure.core.http.policy.HttpLogOptions; +import com.azure.core.util.logging.ClientLogger; +import com.azure.resourcemanager.storage.StorageManagementClient; +import com.azure.resourcemanager.storage.StorageManagementClientBuilder; +import com.azure.resourcemanager.storage.fluent.StorageAccountsClient; import com.azure.storage.blob.BlobServiceClientBuilder; +import com.azure.storage.blob.implementation.util.BuilderHelper; +import com.azure.storage.common.policy.RequestRetryOptions; import com.azure.storage.file.share.ShareServiceClientBuilder; import com.microsoft.azure.identity.spring.SpringEnvironmentTokenBuilder; import com.microsoft.azure.management.storage.StorageAccount; import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; import com.microsoft.azure.spring.cloud.context.core.api.EnvironmentProvider; import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; -import com.microsoft.azure.spring.cloud.context.core.storage.StorageConnectionStringBuilder; import com.microsoft.azure.spring.cloud.context.core.storage.StorageConnectionStringProvider; +import com.microsoft.azure.spring.cloud.context.core.storage.StorageEndpointStringBuilder; import com.microsoft.azure.spring.cloud.storage.AzureStorageProtocolResolver; import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; @@ -87,10 +97,10 @@ public BlobServiceClientBuilder blobServiceClientBuilder(AzureStorageProperties } else { TokenCredential defaultIdentityCredential = new SpringEnvironmentTokenBuilder().fromEnvironment(environment) .defaultCredential().build(); - String connectionString = StorageConnectionStringBuilder.build(storageProperties.getAccount(), - environmentProvider.getEnvironment(), storageProperties.isSecureTransfer()); + authenticatedClientBuilder = new BlobServiceClientBuilder().credential(defaultIdentityCredential) - .connectionString(connectionString); + .endpoint(StorageEndpointStringBuilder.buildBlobEndpoint(storageProperties.getAccount(), + environmentProvider.getEnvironment(), storageProperties.isSecureTransfer())); } return authenticatedClientBuilder @@ -101,23 +111,42 @@ public BlobServiceClientBuilder blobServiceClientBuilder(AzureStorageProperties @ConditionalOnMissingBean public ShareServiceClientBuilder shareServiceClientBuilder(AzureStorageProperties storageProperties, EnvironmentProvider environmentProvider) { - String connectionString; - String connectionString1; - if (resourceManagerProvider != null) { - String accountName = storageProperties.getAccount(); - StorageAccount storageAccount = resourceManagerProvider.getStorageAccountManager().getOrCreate(accountName); - connectionString1 = StorageConnectionStringProvider.getConnectionString(storageAccount, - environmentProvider.getEnvironment(), storageProperties.isSecureTransfer()); + ShareServiceClientBuilder authenticatedClientBuilder = null; + // Use storage credentials where provided, default identity otherwise. + if (StringUtils.isNotBlank(storageProperties.getAccessKey())) { + String connectionString; + if (resourceManagerProvider != null) { + String accountName = storageProperties.getAccount(); + + StorageAccount storageAccount = resourceManagerProvider.getStorageAccountManager() + .getOrCreate(accountName); + connectionString = StorageConnectionStringProvider.getConnectionString(storageAccount, + environmentProvider.getEnvironment(), storageProperties.isSecureTransfer()); + } else { + connectionString = StorageConnectionStringProvider.getConnectionString(storageProperties.getAccount(), + storageProperties.getAccessKey(), environmentProvider.getEnvironment()); + TelemetryCollector.getInstance().addProperty(STORAGE, ACCOUNT_NAME, storageProperties.getAccount()); + } + authenticatedClientBuilder = new ShareServiceClientBuilder().connectionString(connectionString); } else { - connectionString1 = StorageConnectionStringProvider.getConnectionString(storageProperties.getAccount(), - storageProperties.getAccessKey(), environmentProvider.getEnvironment()); - TelemetryCollector.getInstance().addProperty(STORAGE, ACCOUNT_NAME, storageProperties.getAccount()); - } - connectionString = connectionString1; + TokenCredential defaultIdentityCredential = new SpringEnvironmentTokenBuilder().fromEnvironment(environment) + .defaultCredential().build(); + + String endpoint = StorageEndpointStringBuilder.buildSharesEndpoint(storageProperties.getAccount(), + environmentProvider.getEnvironment(), storageProperties.isSecureTransfer()); + + HttpPipeline pipeline = BuilderHelper.buildPipeline(null, defaultIdentityCredential, null, endpoint, + new RequestRetryOptions(), new HttpLogOptions(), HttpClient.createDefault(), + Collections.emptyList(), new com.azure.core.util.Configuration(), + new ClientLogger(this.getClass())); - return new ShareServiceClientBuilder().connectionString(connectionString) + authenticatedClientBuilder = new ShareServiceClientBuilder().pipeline(pipeline); + + } + + return authenticatedClientBuilder .httpLogOptions(new HttpLogOptions().setApplicationId(SPRING_CLOUD_STORAGE_FILE_SHARE_APPLICATION_ID)); } diff --git a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageProperties.java b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageProperties.java index 948df2c015cd..79917382c77e 100644 --- a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageProperties.java +++ b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageProperties.java @@ -27,6 +27,8 @@ public class AzureStorageProperties { * Either accessKey or credentialFilePath should be provided */ private String accessKey; + + private String resourceGroup; public String getAccount() { return account; @@ -51,4 +53,12 @@ public boolean isSecureTransfer() { public void setSecureTransfer(boolean secureTransfer) { this.secureTransfer = secureTransfer; } + + public String getResourceGroup() { + return resourceGroup; + } + + public void setResourceGroup(String resourceGroup) { + this.resourceGroup = resourceGroup; + } } From 41f32faa1e7bdc8df6f76cca05486a66bda534b7 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 5 Aug 2020 10:34:30 -0600 Subject: [PATCH 10/47] In progress --- .../azure-identity-spring-library/pom.xml | 36 +++++ .../spring/AzureIdentitySpringHelper.java | 138 ++++++++++++++++++ 2 files changed, 174 insertions(+) create mode 100644 sdk/spring/azure-identity-spring-library/pom.xml create mode 100644 sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java diff --git a/sdk/spring/azure-identity-spring-library/pom.xml b/sdk/spring/azure-identity-spring-library/pom.xml new file mode 100644 index 000000000000..55b2917eaa6b --- /dev/null +++ b/sdk/spring/azure-identity-spring-library/pom.xml @@ -0,0 +1,36 @@ + + + + 4.0.0 + + com.azure + azure-spring-boot-service + 1.0.0 + + azure-identity-spring-library + 1.0.0-SNAPSHOT + jar + Azure Identity Spring Integration Library + + UTF-8 + 1.8 + 1.8 + + + + org.springframework + spring-context + 5.2.8.RELEASE + + + org.springframework + spring-core + 5.2.8.RELEASE + + + com.azure + azure-identity + 1.0.9 + + + diff --git a/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java b/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java new file mode 100644 index 000000000000..b786a898f2a8 --- /dev/null +++ b/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + */ +package com.microsoft.azure.identity.spring; + +import com.azure.core.credential.TokenCredential; +import com.azure.identity.ClientCertificateCredentialBuilder; +import com.azure.identity.ClientSecretCredentialBuilder; +import com.azure.identity.DefaultAzureCredentialBuilder; +import java.util.HashMap; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +/** + * A helper class to deal with credentials in a Spring environment. + * + * @author manfred.riem@microsoft.com + */ +@Component +public class AzureIdentitySpringHelper { + + /** + * Defines the AZURE_CREDENTIAL_PREFIX. + */ + private static final String AZURE_CREDENTIAL_PREFIX = "azure.credential."; + + /** + * Stores the named credentials. + */ + private final HashMap credentials; + + /** + * Constructor. + */ + public AzureIdentitySpringHelper() { + credentials = new HashMap<>(); + credentials.put("", new DefaultAzureCredentialBuilder().build()); + } + + /** + * Add a named credential. + * + * @param name the name. + * @param credential the credential. + */ + public void addNamedCredential(String name, TokenCredential credential) { + credentials.put(name, credential); + } + + /** + * Get the default Azure credential. + * + * @return the default Azure credential + */ + public TokenCredential getDefaultCredential() { + return credentials.get(""); + } + + /** + * Get the named credential. + * + * @param name the name. + * @return the named credential, or null if not found. + */ + public TokenCredential getNamedCredential(String name) { + return credentials.get(name); + } + + /** + * Populate from Environment. + * + * @param environment the environment. + */ + public void populate(Environment environment) { + populateNamedCredential(environment, ""); + String credentialNamesKey = AZURE_CREDENTIAL_PREFIX + "names"; + if (environment.containsProperty(credentialNamesKey)) { + String[] credentialNames = environment.getProperty(credentialNamesKey).split(","); + for(int i=0; i Date: Thu, 6 Aug 2020 08:04:47 -0600 Subject: [PATCH 11/47] Throw an exception when configuration is incomplete --- .../azure/identity/spring/AzureIdentitySpringHelper.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java b/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java index b786a898f2a8..c6e017113c2b 100644 --- a/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java +++ b/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java @@ -123,7 +123,10 @@ private void populateNamedCredential(Environment environment, String name) { .pemCertificate(clientCertificatePath) .build(); credentials.put(name, credential); + return; } + + throw new RuntimeException("Configuration for azure.credential" + name + " is incomplete"); } /** From f0322af41067e23c2d9d753a50019bb93dbfd5ad Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Thu, 6 Aug 2020 08:18:06 -0600 Subject: [PATCH 12/47] Added class level JavaDoc --- .../spring/AzureIdentitySpringHelper.java | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java b/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java index c6e017113c2b..0e1409c5fdfa 100644 --- a/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java +++ b/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java @@ -14,6 +14,48 @@ /** * A helper class to deal with credentials in a Spring environment. + * + *

+ * This helper class makes it possible to configure credentials to be used + * within a Spring context. + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Property TuplesDescription
+ * azure.credential.(name.)tenantId
+ * azure.credential.(name.)clientId
+ * azure.credential.(name.)clientSecret + *
+ * the Azure Tenant ID
+ * the Client ID
+ * the Client Certificate
+ *
+ * azure.credential.(name.)tenantId
+ * azure.credential.(name.)clientId
+ * azure.credential.(name.)clientCertificate + *
+ * the Azure Tenant ID
+ * the Client ID
+ * the path to the PEM client certificate + *
+ * + * where name is the name of the credential. Note if + * name is entirely omitted it is taken to be the default + * credential. Note if the default credential is omitted it is configure to use + * AzureDefaultCredential which allows for the use a Managed Identity (if it is + * present). * * @author manfred.riem@microsoft.com */ @@ -113,7 +155,7 @@ private void populateNamedCredential(Environment environment, String name) { return; } - String clientCertificateKey = AZURE_CREDENTIAL_PREFIX + name + "clientSecret"; + String clientCertificateKey = AZURE_CREDENTIAL_PREFIX + name + "clientCertificate"; String clientCertificatePath = environment.getProperty(clientCertificateKey); if (clientCertificatePath != null) { From 8a6385c0755d67869695bd4c9a38f8fed3612856 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Thu, 6 Aug 2020 08:41:34 -0600 Subject: [PATCH 13/47] Resolve POM conflict --- sdk/spring/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/spring/pom.xml b/sdk/spring/pom.xml index 28bebe38efd1..f7f83e16c11e 100644 --- a/sdk/spring/pom.xml +++ b/sdk/spring/pom.xml @@ -9,6 +9,7 @@ pom 1.0.0 + azure-identity-spring-library azure-spring-boot azure-spring-boot-starter azure-spring-boot-starter-active-directory From 9305ee1b5a5a2f9d00f08af30d0121e7eca54d51 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Thu, 6 Aug 2020 09:22:47 -0600 Subject: [PATCH 14/47] Added unit tests --- .../azure-identity-spring-library/pom.xml | 33 +++++++ .../spring/AzureIdentitySpringHelper.java | 25 ++--- .../spring/AzureIdentitySpringHelperTest.java | 92 +++++++++++++++++++ 3 files changed, 138 insertions(+), 12 deletions(-) create mode 100644 sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelperTest.java diff --git a/sdk/spring/azure-identity-spring-library/pom.xml b/sdk/spring/azure-identity-spring-library/pom.xml index 55b2917eaa6b..bfd1e8106f58 100644 --- a/sdk/spring/azure-identity-spring-library/pom.xml +++ b/sdk/spring/azure-identity-spring-library/pom.xml @@ -16,6 +16,15 @@ 1.8 1.8
+ + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M5 + + + org.springframework @@ -32,5 +41,29 @@ azure-identity 1.0.9 + + org.junit.jupiter + junit-jupiter-api + 5.6.2 + test + + + org.junit.jupiter + junit-jupiter-params + 5.6.2 + test + + + org.junit.jupiter + junit-jupiter-engine + 5.6.2 + test + + + junit + junit + test + 4.13 + diff --git a/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java b/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java index 0e1409c5fdfa..d7c2712286c0 100644 --- a/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java +++ b/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java @@ -1,7 +1,5 @@ -/* - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. package com.microsoft.azure.identity.spring; import com.azure.core.credential.TokenCredential; @@ -132,14 +130,15 @@ public void populate(Environment environment) { * @param name the name. */ private void populateNamedCredential(Environment environment, String name) { + String standardizedName = name; - if (!name.equals("") && !name.endsWith(".")) { - name = name + "."; + if (!standardizedName.equals("") && !standardizedName.endsWith(".")) { + standardizedName = standardizedName + "."; } - String tenantIdKey = AZURE_CREDENTIAL_PREFIX + name + "tenantId"; - String clientIdKey = AZURE_CREDENTIAL_PREFIX + name + "clientId"; - String clientSecretKey = AZURE_CREDENTIAL_PREFIX + name + "clientSecret"; + String tenantIdKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "tenantId"; + String clientIdKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "clientId"; + String clientSecretKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "clientSecret"; String tenantId = environment.getProperty(tenantIdKey); String clientId = environment.getProperty(clientIdKey); @@ -155,10 +154,10 @@ private void populateNamedCredential(Environment environment, String name) { return; } - String clientCertificateKey = AZURE_CREDENTIAL_PREFIX + name + "clientCertificate"; + String clientCertificateKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "clientCertificate"; String clientCertificatePath = environment.getProperty(clientCertificateKey); - if (clientCertificatePath != null) { + if (tenantId != null && clientId != null && clientCertificatePath != null) { TokenCredential credential = new ClientCertificateCredentialBuilder() .tenantId(tenantId) .clientId(clientId) @@ -168,7 +167,9 @@ private void populateNamedCredential(Environment environment, String name) { return; } - throw new RuntimeException("Configuration for azure.credential" + name + " is incomplete"); + if (!name.equals("")) { + throw new RuntimeException("Configuration for azure.credential." + name + " is incomplete"); + } } /** diff --git a/sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelperTest.java b/sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelperTest.java new file mode 100644 index 000000000000..d8a467aea270 --- /dev/null +++ b/sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelperTest.java @@ -0,0 +1,92 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.microsoft.azure.identity.spring; + +import com.azure.identity.ClientSecretCredential; +import com.azure.identity.DefaultAzureCredential; +import com.azure.identity.DefaultAzureCredentialBuilder; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import org.junit.jupiter.api.Test; +import org.springframework.core.env.StandardEnvironment; + +/** + * The unit tests for the AzureIdentitySpringHelper class. + * + * @author manfred.riem@microsoft.com + */ +public class AzureIdentitySpringHelperTest { + + /** + * Test addNamedCredential method. + */ + @Test + public void testAddNamedCredential() { + DefaultAzureCredential credential = new DefaultAzureCredentialBuilder().build(); + AzureIdentitySpringHelper helper = new AzureIdentitySpringHelper(); + helper.addNamedCredential("cred1", credential); + assertNotNull(helper.getNamedCredential("cred1")); + helper.removeNamedCredential("cred1"); + assertNull(helper.getNamedCredential("cred1")); + } + + /** + * Test getDefaultCredential method. + */ + @Test + public void testGetDefaultCredential() { + AzureIdentitySpringHelper helper = new AzureIdentitySpringHelper(); + assertNotNull(helper.getDefaultCredential()); + } + + /** + * Test populate method. + */ + @Test + public void testPopulate() { + System.setProperty("azure.credential.names", ""); + System.setProperty("azure.credential.tenantId", "tenantId"); + System.setProperty("azure.credential.clientId", "clientId"); + System.setProperty("azure.credential.clientSecret", "clientSecret"); + StandardEnvironment environment = new StandardEnvironment(); + AzureIdentitySpringHelper helper = new AzureIdentitySpringHelper(); + helper.populate(environment); + assertNotNull(helper.getDefaultCredential()); + assertTrue(helper.getDefaultCredential() instanceof ClientSecretCredential); + } + + /** + * Test populate method. + */ + @Test + public void testPopulate2() { + System.setProperty("azure.credential.names", "myname"); + System.setProperty("azure.credential.myname.tenantId", "tenantId"); + System.setProperty("azure.credential.myname.clientId", "clientId"); + System.setProperty("azure.credential.myname.clientSecret", "clientSecret"); + StandardEnvironment environment = new StandardEnvironment(); + AzureIdentitySpringHelper helper = new AzureIdentitySpringHelper(); + helper.populate(environment); + assertNotNull(helper.getNamedCredential("myname")); + assertTrue(helper.getNamedCredential("myname") instanceof ClientSecretCredential); + } + + /** + * Test populate method. + */ + @Test + public void testPopulate3() { + System.setProperty("azure.credential.names", "myname2"); + System.setProperty("azure.credential.myname2.tenantId", "tenantId"); + System.setProperty("azure.credential.myname2.clientSecret", "clientSecret"); + StandardEnvironment environment = new StandardEnvironment(); + AzureIdentitySpringHelper helper = new AzureIdentitySpringHelper(); + try { + helper.populate(environment); + fail(); + } catch(RuntimeException re) { + } + } +} From 92fd3dd63f565bc2beb67d79faea67bd91796e6e Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Thu, 13 Aug 2020 15:29:45 -0400 Subject: [PATCH 15/47] Changing the Identity Helper into a builder --- .../spring/AzureIdentitySpringHelper.java | 184 ------------------ .../spring/SpringEnvironmentTokenBuilder.java | 174 +++++++++++++++++ .../spring/AzureIdentitySpringHelperTest.java | 92 --------- .../SpringEnvironmentTokenBuilderTest.java | 88 +++++++++ 4 files changed, 262 insertions(+), 276 deletions(-) delete mode 100644 sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java create mode 100644 sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/SpringEnvironmentTokenBuilder.java delete mode 100644 sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelperTest.java create mode 100644 sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/SpringEnvironmentTokenBuilderTest.java diff --git a/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java b/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java deleted file mode 100644 index d7c2712286c0..000000000000 --- a/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelper.java +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -package com.microsoft.azure.identity.spring; - -import com.azure.core.credential.TokenCredential; -import com.azure.identity.ClientCertificateCredentialBuilder; -import com.azure.identity.ClientSecretCredentialBuilder; -import com.azure.identity.DefaultAzureCredentialBuilder; -import java.util.HashMap; -import org.springframework.core.env.Environment; -import org.springframework.stereotype.Component; - -/** - * A helper class to deal with credentials in a Spring environment. - * - *

- * This helper class makes it possible to configure credentials to be used - * within a Spring context. - *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
Property TuplesDescription
- * azure.credential.(name.)tenantId
- * azure.credential.(name.)clientId
- * azure.credential.(name.)clientSecret - *
- * the Azure Tenant ID
- * the Client ID
- * the Client Certificate
- *
- * azure.credential.(name.)tenantId
- * azure.credential.(name.)clientId
- * azure.credential.(name.)clientCertificate - *
- * the Azure Tenant ID
- * the Client ID
- * the path to the PEM client certificate - *
- * - * where name is the name of the credential. Note if - * name is entirely omitted it is taken to be the default - * credential. Note if the default credential is omitted it is configure to use - * AzureDefaultCredential which allows for the use a Managed Identity (if it is - * present). - * - * @author manfred.riem@microsoft.com - */ -@Component -public class AzureIdentitySpringHelper { - - /** - * Defines the AZURE_CREDENTIAL_PREFIX. - */ - private static final String AZURE_CREDENTIAL_PREFIX = "azure.credential."; - - /** - * Stores the named credentials. - */ - private final HashMap credentials; - - /** - * Constructor. - */ - public AzureIdentitySpringHelper() { - credentials = new HashMap<>(); - credentials.put("", new DefaultAzureCredentialBuilder().build()); - } - - /** - * Add a named credential. - * - * @param name the name. - * @param credential the credential. - */ - public void addNamedCredential(String name, TokenCredential credential) { - credentials.put(name, credential); - } - - /** - * Get the default Azure credential. - * - * @return the default Azure credential - */ - public TokenCredential getDefaultCredential() { - return credentials.get(""); - } - - /** - * Get the named credential. - * - * @param name the name. - * @return the named credential, or null if not found. - */ - public TokenCredential getNamedCredential(String name) { - return credentials.get(name); - } - - /** - * Populate from Environment. - * - * @param environment the environment. - */ - public void populate(Environment environment) { - populateNamedCredential(environment, ""); - String credentialNamesKey = AZURE_CREDENTIAL_PREFIX + "names"; - if (environment.containsProperty(credentialNamesKey)) { - String[] credentialNames = environment.getProperty(credentialNamesKey).split(","); - for(int i=0; i + * This helper class makes it possible to configure credentials to be used + * within a Spring context. + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Property TuplesDescription
azure.credential.(name.)tenantId
+ * azure.credential.(name.)clientId
+ * azure.credential.(name.)clientSecret
the Azure Tenant ID
+ * the Client ID
+ * the Client Certificate
+ *
azure.credential.(name.)tenantId
+ * azure.credential.(name.)clientId
+ * azure.credential.(name.)clientCertificate
the Azure Tenant ID
+ * the Client ID
+ * the path to the PEM client certificate
+ * + * where name is the name of the credential. Note if + * name is entirely omitted it is taken to be the default + * credential. Note if the default credential is omitted it is configure to use + * AzureDefaultCredential which allows for the use a Managed Identity (if it is + * present). + * + * @author manfred.riem@microsoft.com + */ +public class SpringEnvironmentTokenBuilder { + + /** + * Defines the AZURE_CREDENTIAL_PREFIX. + */ + private static final String AZURE_CREDENTIAL_PREFIX = "azure.credential."; + + /** + * Stores the named credentials. + */ + private final HashMap credentials; + + /** + * Stores the name of the credential to be returned. If omitted, the default + * credential will be returned. + */ + private String name = ""; + + /** + * Constructor. + */ + public SpringEnvironmentTokenBuilder() { + credentials = new HashMap<>(); + credentials.put("", new DefaultAzureCredentialBuilder().build()); + } + + /** + * Populate from Environment. + * + * @param environment the environment. + */ + public SpringEnvironmentTokenBuilder fromEnvironment(Environment environment) { + populateNamedCredential(environment, ""); + String credentialNamesKey = AZURE_CREDENTIAL_PREFIX + "names"; + if (environment.containsProperty(credentialNamesKey)) { + String[] credentialNames = environment.getProperty(credentialNamesKey).split(","); + for (int i = 0; i < credentialNames.length; i++) { + populateNamedCredential(environment, credentialNames[i]); + } + } + return this; + } + + /** + * Populate a named credential. + * + * @param environment the environment + * @param name the name. + */ + private void populateNamedCredential(Environment environment, String name) { + String standardizedName = name; + + if (!standardizedName.equals("") && !standardizedName.endsWith(".")) { + standardizedName = standardizedName + "."; + } + + String tenantIdKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "tenantId"; + String clientIdKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "clientId"; + String clientSecretKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "clientSecret"; + + String tenantId = environment.getProperty(tenantIdKey); + String clientId = environment.getProperty(clientIdKey); + String clientSecret = environment.getProperty(clientSecretKey); + + if (tenantId != null && clientId != null && clientSecret != null) { + TokenCredential credential = new ClientSecretCredentialBuilder().tenantId(tenantId).clientId(clientId) + .clientSecret(clientSecret).build(); + credentials.put(name, credential); + return; + } + + String clientCertificateKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "clientCertificate"; + String clientCertificatePath = environment.getProperty(clientCertificateKey); + + if (tenantId != null && clientId != null && clientCertificatePath != null) { + TokenCredential credential = new ClientCertificateCredentialBuilder().tenantId(tenantId).clientId(clientId) + .pemCertificate(clientCertificatePath).build(); + credentials.put(name, credential); + return; + } + + if (!name.equals("")) { + throw new IllegalStateException("Configuration for azure.credential." + name + " is incomplete"); + } + } + + /** + * Sets the builder to return a credential named name + * + * @param name + * @return + */ + public SpringEnvironmentTokenBuilder namedCredential(String name) { + this.name = name; + return this; + } + + /** + * Sets the builder to return the default credential. + */ + public SpringEnvironmentTokenBuilder defaultCredential() { + return namedCredential(""); + } + + /** + * Builds an Azure TokenCredendial. + * + * @throws IllegalArgumentException if attempting to retrieve a named credential + * not defined in the environment. + */ + public TokenCredential build() { + TokenCredential result = credentials.get(name); + if (result == null) { + throw new IllegalArgumentException( + "Attempting to retrieve Azure credential not configured in the environment. (name=" + name + ")"); + } else { + return result; + } + } +} diff --git a/sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelperTest.java b/sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelperTest.java deleted file mode 100644 index d8a467aea270..000000000000 --- a/sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/AzureIdentitySpringHelperTest.java +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -package com.microsoft.azure.identity.spring; - -import com.azure.identity.ClientSecretCredential; -import com.azure.identity.DefaultAzureCredential; -import com.azure.identity.DefaultAzureCredentialBuilder; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; -import org.junit.jupiter.api.Test; -import org.springframework.core.env.StandardEnvironment; - -/** - * The unit tests for the AzureIdentitySpringHelper class. - * - * @author manfred.riem@microsoft.com - */ -public class AzureIdentitySpringHelperTest { - - /** - * Test addNamedCredential method. - */ - @Test - public void testAddNamedCredential() { - DefaultAzureCredential credential = new DefaultAzureCredentialBuilder().build(); - AzureIdentitySpringHelper helper = new AzureIdentitySpringHelper(); - helper.addNamedCredential("cred1", credential); - assertNotNull(helper.getNamedCredential("cred1")); - helper.removeNamedCredential("cred1"); - assertNull(helper.getNamedCredential("cred1")); - } - - /** - * Test getDefaultCredential method. - */ - @Test - public void testGetDefaultCredential() { - AzureIdentitySpringHelper helper = new AzureIdentitySpringHelper(); - assertNotNull(helper.getDefaultCredential()); - } - - /** - * Test populate method. - */ - @Test - public void testPopulate() { - System.setProperty("azure.credential.names", ""); - System.setProperty("azure.credential.tenantId", "tenantId"); - System.setProperty("azure.credential.clientId", "clientId"); - System.setProperty("azure.credential.clientSecret", "clientSecret"); - StandardEnvironment environment = new StandardEnvironment(); - AzureIdentitySpringHelper helper = new AzureIdentitySpringHelper(); - helper.populate(environment); - assertNotNull(helper.getDefaultCredential()); - assertTrue(helper.getDefaultCredential() instanceof ClientSecretCredential); - } - - /** - * Test populate method. - */ - @Test - public void testPopulate2() { - System.setProperty("azure.credential.names", "myname"); - System.setProperty("azure.credential.myname.tenantId", "tenantId"); - System.setProperty("azure.credential.myname.clientId", "clientId"); - System.setProperty("azure.credential.myname.clientSecret", "clientSecret"); - StandardEnvironment environment = new StandardEnvironment(); - AzureIdentitySpringHelper helper = new AzureIdentitySpringHelper(); - helper.populate(environment); - assertNotNull(helper.getNamedCredential("myname")); - assertTrue(helper.getNamedCredential("myname") instanceof ClientSecretCredential); - } - - /** - * Test populate method. - */ - @Test - public void testPopulate3() { - System.setProperty("azure.credential.names", "myname2"); - System.setProperty("azure.credential.myname2.tenantId", "tenantId"); - System.setProperty("azure.credential.myname2.clientSecret", "clientSecret"); - StandardEnvironment environment = new StandardEnvironment(); - AzureIdentitySpringHelper helper = new AzureIdentitySpringHelper(); - try { - helper.populate(environment); - fail(); - } catch(RuntimeException re) { - } - } -} diff --git a/sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/SpringEnvironmentTokenBuilderTest.java b/sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/SpringEnvironmentTokenBuilderTest.java new file mode 100644 index 000000000000..496385d04edf --- /dev/null +++ b/sdk/spring/azure-identity-spring-library/src/test/java/com/microsoft/azure/identity/spring/SpringEnvironmentTokenBuilderTest.java @@ -0,0 +1,88 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.microsoft.azure.identity.spring; + +import com.azure.identity.ClientSecretCredential; +import com.azure.identity.DefaultAzureCredential; +import com.azure.identity.DefaultAzureCredentialBuilder; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import org.junit.jupiter.api.Test; +import org.springframework.core.env.StandardEnvironment; + +/** + * The unit tests for the AzureIdentitySpringHelper class. + * + * @author manfred.riem@microsoft.com + */ +public class SpringEnvironmentTokenBuilderTest { + + /** + * Test getDefaultCredential method. + */ + @Test + public void testGetDefaultCredential() { + SpringEnvironmentTokenBuilder builder = new SpringEnvironmentTokenBuilder(); + assertNotNull(builder.build()); + assertEquals(builder.build(), builder.defaultCredential().build()); + } + + /** + * Test populate method. + */ + @Test + public void testPopulate() { + System.setProperty("azure.credential.names", ""); + System.setProperty("azure.credential.tenantId", "tenantId"); + System.setProperty("azure.credential.clientId", "clientId"); + System.setProperty("azure.credential.clientSecret", "clientSecret"); + StandardEnvironment environment = new StandardEnvironment(); + SpringEnvironmentTokenBuilder builder = new SpringEnvironmentTokenBuilder(); + builder.fromEnvironment(environment); + + assertNotNull(builder.build()); + assertTrue(builder.build() instanceof ClientSecretCredential); + assertEquals(builder.build(), builder.defaultCredential().build()); + } + + /** + * Test populate method. + */ + @Test + public void testPopulate2() { + System.setProperty("azure.credential.names", "myname"); + System.setProperty("azure.credential.myname.tenantId", "tenantId"); + System.setProperty("azure.credential.myname.clientId", "clientId"); + System.setProperty("azure.credential.myname.clientSecret", "clientSecret"); + StandardEnvironment environment = new StandardEnvironment(); + SpringEnvironmentTokenBuilder builder = new SpringEnvironmentTokenBuilder(); + builder.fromEnvironment(environment); + assertNotNull(builder.namedCredential("myname").build()); + assertTrue(builder.build() instanceof ClientSecretCredential); + assertNotEquals(builder.build(), builder.defaultCredential().build()); + } + + /** + * Test populate method. + */ + @Test + public void testPopulate3() { + System.setProperty("azure.credential.names", "myname2"); + System.setProperty("azure.credential.myname2.tenantId", "tenantId"); + System.setProperty("azure.credential.myname2.clientSecret", "clientSecret"); + StandardEnvironment environment = new StandardEnvironment(); + SpringEnvironmentTokenBuilder builder = new SpringEnvironmentTokenBuilder(); + try { + builder.fromEnvironment(environment); + fail(); + } catch (Throwable t) { + assertEquals(IllegalStateException.class, t.getClass(), + "Unexpected exception class on missing configuration field."); + } + } +} From 06d8aa933e7936d2bf3ffd63cb4a6e82d114f9b9 Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Fri, 14 Aug 2020 21:45:21 -0400 Subject: [PATCH 16/47] Adding storage resource sample, autoconfiguration for blob storage with default identity --- .../azure-identity-spring-library/pom.xml | 2 +- .../README.adoc | 113 ++++++++++++++++++ .../pom.xml | 58 +++++++++ .../main/java/com/example/BlobController.java | 43 +++++++ .../java/com/example/StorageApplication.java | 21 ++++ .../src/main/resources/application.properties | 24 ++++ .../com/example/StorageApplicationIT.java | 50 ++++++++ .../resources/application-test.properties | 8 ++ .../main/resources/META-INF/spring.provides | 2 +- .../AzureStorageAutoConfiguration.java | 94 ++++++++------- sdk/spring/pom.xml | 1 + 11 files changed, 374 insertions(+), 42 deletions(-) create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/README.adoc create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/pom.xml create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/BlobController.java create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/StorageApplication.java create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/java/com/example/StorageApplicationIT.java create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/resources/application-test.properties diff --git a/sdk/spring/azure-identity-spring-library/pom.xml b/sdk/spring/azure-identity-spring-library/pom.xml index bfd1e8106f58..457d1880c49b 100644 --- a/sdk/spring/azure-identity-spring-library/pom.xml +++ b/sdk/spring/azure-identity-spring-library/pom.xml @@ -8,9 +8,9 @@ 1.0.0 azure-identity-spring-library - 1.0.0-SNAPSHOT jar Azure Identity Spring Integration Library + 1.0.0-beta.1 UTF-8 1.8 diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/README.adoc b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/README.adoc new file mode 100644 index 000000000000..4a721ed4e225 --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/README.adoc @@ -0,0 +1,113 @@ += Spring Cloud Azure Storage Starter Sample + +This code sample demonstrates how to read and write files with the Spring Resource abstraction for Azure Storage using +the +link:../../spring-cloud-azure-starters/spring-starter-azure-storage[Spring Cloud Azure Storage Starter].Running this sample will be charged by Azure. You can check the usage and bill at https://azure.microsoft.com/en-us/account/[this link]. + +Running this sample will be charged by Azure. You can check the usage and bill at https://azure.microsoft.com/en-us/account/[this link]. + +Maven coordinates: + +[source,xml] +---- + + com.microsoft.azure + spring-starter-azure-storage + +---- + +Gradle coordinates: + +[source] +---- +dependencies { + compile group: 'com.microsoft.azure', name: 'spring-starter-azure-storage' +} +---- + +== Access key based usage + +1. Create https://docs.microsoft.com/en-us/azure/storage/[Azure Storage] + +2. Update link:src/main/resources/application.properties[application.properties] + ++ +.... +spring.cloud.azure.storage.account=[storage-account-name] + +# Fill storage account access key copied from portal +spring.cloud.azure.storage.access-key=[storage-account-accesskey] + +.... + +== Credential file based usage + +1. Create azure credential file. Please see https://github.com/Azure/azure-libraries-for-java/blob/master/AUTH.md[how to create credential file]. ++ +.... +$ az login +$ az account set --subscription +$ az ad sp create-for-rbac --sdk-auth > my.azureauth +.... ++ +Make sure `my.azureauth` is encoded with UTF-8. + +2. Put credential file under `src/main/resources/`. + +3. Create https://docs.microsoft.com/en-us/azure/storage/[Azure Storage]. Or enable auto create +resources feature in link:src/main/resources/application.properties[application.properties]: ++ +.... +spring.cloud.azure.auto-create-resources=true + +# Example region is westUS, northchina +spring.cloud.azure.region=[region] +.... + +5. Update link:src/main/resources/application.properties[application.properties] ++ +.... + +# Enter 'my.azureauth' here if following step 1 and 2 +spring.cloud.azure.credential-file-path=[credential-file-path] + +spring.cloud.azure.resource-group=[resource-group] + +spring.cloud.azure.storage.account=[account-name] +.... + +== How to run + +5. Update link:src/main/resources/application.properties[application.properties] + ++ +.... + +# Default environment is GLOBAL. Provide your own if in another environment +# Example environment is China, GLOBAL +# spring.cloud.azure.environment=[environment] + +# Change into your containerName, blobName +blob=azure-blob://containerName/blobName + +.... + +6. Start the `StorageApplication` Spring Boot app. ++ +``` +$ mvn spring-boot:run +``` + +7. Send a POST request to update file contents: ++ +``` +$ curl -d 'new message' -H 'Content-Type: text/plain' localhost:8080/blob +``` ++ +Verify by sending a GET request ++ +``` +$ curl -XGET http://localhost:8080/blob +``` + +8. Delete the resources on http://ms.portal.azure.com/[Azure Portal] to avoid unexpected charges. diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/pom.xml b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/pom.xml new file mode 100644 index 000000000000..2e255d1546df --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/pom.xml @@ -0,0 +1,58 @@ + + + + com.azure + azure-spring-boot-service + 1.0.0 + ../.. + + 4.0.0 + + 1.8 + 1.8 + 2.3.3.RELEASE + + + azure-spring-boot-sample-storage-resource + Spring Cloud Azure Storage Resource Sample + + + com.microsoft.azure + spring-starter-azure-storage + 1.2.8-beta.1 + + + + org.springframework.boot + spring-boot-starter + ${spring.boot.version} + + + + org.springframework.boot + spring-boot-starter-web + ${spring.boot.version} + + + + junit + junit + 4.12 + test + + + org.springframework.boot + spring-boot-starter-test + ${spring.boot.version} + test + + + org.junit.vintage + junit-vintage-engine + + + + + + + diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/BlobController.java b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/BlobController.java new file mode 100644 index 000000000000..34d07941b451 --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/BlobController.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See LICENSE in the project root for + * license information. + */ + +package com.example; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.Resource; +import org.springframework.core.io.WritableResource; +import org.springframework.util.StreamUtils; +import org.springframework.web.bind.annotation.*; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.Charset; + +/** + * @author Warren Zhu + */ +@RestController +@RequestMapping("blob") +public class BlobController { + + @Value("${blob}") + private Resource blobFile; + + @GetMapping + public String readBlobFile() throws IOException { + return StreamUtils.copyToString( + this.blobFile.getInputStream(), + Charset.defaultCharset()); + } + + @PostMapping + public String writeBlobFile(@RequestBody String data) throws IOException { + try (OutputStream os = ((WritableResource) this.blobFile).getOutputStream()) { + os.write(data.getBytes()); + } + return "file was updated"; + } +} diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/StorageApplication.java b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/StorageApplication.java new file mode 100644 index 000000000000..e9f5752e9d70 --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/StorageApplication.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See LICENSE in the project root for + * license information. + */ + +package com.example; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author Warren Zhu + */ +@SpringBootApplication +public class StorageApplication { + + public static void main(String[] args) { + SpringApplication.run(StorageApplication.class, args); + } +} diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties new file mode 100644 index 000000000000..d48ad9e5632b --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties @@ -0,0 +1,24 @@ +# Credential file based usage + +spring.cloud.azure.credential-file-path=[credential-file-path] +spring.cloud.azure.resource-group=[resource-group] + +# Access key based usage + +# Fill storage account access key copied from portal +# spring.cloud.azure.storage.access-key=[storage-account-accesskey] + +# Storage account name length should be between 3 and 24 +# and use numbers and lower-case letters only. +spring.cloud.azure.storage.account=[account-name] + +# Change into your containerName and blobName +blob=azure-blob://containerName/blobName + +# spring.cloud.azure.auto-create-resources=true + +# Default environment is GLOBAL. Provide your own if in another environment +# Example environment is China, GLOBAL +# spring.cloud.azure.environment=[environment] +# Example region is westUS, northchina +# spring.cloud.azure.region=[region] diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/java/com/example/StorageApplicationIT.java b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/java/com/example/StorageApplicationIT.java new file mode 100644 index 000000000000..9d7193b29265 --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/java/com/example/StorageApplicationIT.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See LICENSE in the project root for + * license information. + */ +package com.example; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import java.util.UUID; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = StorageApplication.class) +@AutoConfigureMockMvc +@TestPropertySource( + locations = "classpath:application-test.properties") +public class StorageApplicationIT { + + @Autowired + private MockMvc mvc; + + @Test + public void testPostAndGetSuccess() + throws Exception { + String content = UUID.randomUUID().toString(); + + mvc.perform(post("/blob") + .contentType(MediaType.APPLICATION_JSON).content(content)) + .andExpect(status().isOk()) + .andExpect(content().string("file was updated")); + + mvc.perform(get("/blob") + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string(content)); + } +} diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/resources/application-test.properties b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/resources/application-test.properties new file mode 100644 index 000000000000..197151f76113 --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/resources/application-test.properties @@ -0,0 +1,8 @@ +spring.cloud.azure.credential-file-path=file:@credential@ +spring.cloud.azure.resource-group=spring-cloud + +blob=azure-blob://container1/blob1 +spring.cloud.azure.storage.account=springcloud + +spring.cloud.azure.region=westUS +spring.cloud.azure.auto-create-resources=true diff --git a/sdk/spring/azure-spring-cloud-starter-storage/src/main/resources/META-INF/spring.provides b/sdk/spring/azure-spring-cloud-starter-storage/src/main/resources/META-INF/spring.provides index 6ac0341c54f5..166f52fb2739 100644 --- a/sdk/spring/azure-spring-cloud-starter-storage/src/main/resources/META-INF/spring.provides +++ b/sdk/spring/azure-spring-cloud-starter-storage/src/main/resources/META-INF/spring.provides @@ -1 +1 @@ -provides: spring-cloud-azure-context, spring-cloud-azure-autoconfigure +provides: spring-cloud-azure-context, spring-cloud-azure-storage diff --git a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java index 21a860284e09..cc0d773626ca 100644 --- a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java @@ -3,16 +3,12 @@ package com.microsoft.azure.spring.cloud.autoconfigure.storage; -import com.azure.core.http.policy.HttpLogOptions; -import com.azure.storage.blob.BlobServiceClientBuilder; -import com.azure.storage.file.share.ShareServiceClientBuilder; -import com.microsoft.azure.management.storage.StorageAccount; -import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; -import com.microsoft.azure.spring.cloud.context.core.api.EnvironmentProvider; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; -import com.microsoft.azure.spring.cloud.context.core.storage.StorageConnectionStringProvider; -import com.microsoft.azure.spring.cloud.storage.AzureStorageProtocolResolver; -import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; +import static com.microsoft.azure.spring.cloud.context.core.util.Constants.SPRING_CLOUD_STORAGE_BLOB_APPLICATION_ID; +import static com.microsoft.azure.spring.cloud.context.core.util.Constants.SPRING_CLOUD_STORAGE_FILE_SHARE_APPLICATION_ID; + +import javax.annotation.PostConstruct; + +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -24,11 +20,20 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.core.env.Environment; -import javax.annotation.PostConstruct; - -import static com.microsoft.azure.spring.cloud.context.core.util.Constants.SPRING_CLOUD_STORAGE_BLOB_APPLICATION_ID; -import static com.microsoft.azure.spring.cloud.context.core.util.Constants.SPRING_CLOUD_STORAGE_FILE_SHARE_APPLICATION_ID; +import com.azure.core.credential.TokenCredential; +import com.azure.core.http.policy.HttpLogOptions; +import com.azure.storage.blob.BlobServiceClientBuilder; +import com.azure.storage.file.share.ShareServiceClientBuilder; +import com.microsoft.azure.identity.spring.SpringEnvironmentTokenBuilder; +import com.microsoft.azure.management.storage.StorageAccount; +import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; +import com.microsoft.azure.spring.cloud.context.core.api.EnvironmentProvider; +import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; +import com.microsoft.azure.spring.cloud.context.core.storage.StorageConnectionStringProvider; +import com.microsoft.azure.spring.cloud.storage.AzureStorageProtocolResolver; +import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; /** * An auto-configuration for Azure Storage Account @@ -37,7 +42,7 @@ */ @Configuration @AutoConfigureAfter(AzureContextAutoConfiguration.class) -@ConditionalOnClass({BlobServiceClientBuilder.class, ShareServiceClientBuilder.class}) +@ConditionalOnClass({ BlobServiceClientBuilder.class, ShareServiceClientBuilder.class }) @ConditionalOnProperty(name = "spring.cloud.azure.storage.account") @EnableConfigurationProperties(AzureStorageProperties.class) public class AzureStorageAutoConfiguration { @@ -53,54 +58,63 @@ public void collectTelemetry() { TelemetryCollector.getInstance().addService(STORAGE); } + @Autowired + private Environment environment; + @Bean @ConditionalOnMissingBean public BlobServiceClientBuilder blobServiceClientBuilder(AzureStorageProperties storageProperties, - EnvironmentProvider environmentProvider) { - String connectionString; + EnvironmentProvider environmentProvider) { + + BlobServiceClientBuilder authenticatedClientBuilder = null; + + // Use storage credentials where provided, default identity otherwise. + if (StringUtils.isNotBlank(storageProperties.getAccessKey())) { + String connectionString = null; + if (resourceManagerProvider != null) { + StorageAccount storageAccount = resourceManagerProvider.getStorageAccountManager() + .getOrCreate(storageProperties.getAccount()); + connectionString = StorageConnectionStringProvider.getConnectionString(storageAccount, + environmentProvider.getEnvironment(), storageProperties.isSecureTransfer()); + } else { + connectionString = StorageConnectionStringProvider.getConnectionString(storageProperties.getAccount(), + storageProperties.getAccessKey(), environmentProvider.getEnvironment()); + TelemetryCollector.getInstance().addProperty(STORAGE, ACCOUNT_NAME, storageProperties.getAccount()); + } + authenticatedClientBuilder = new BlobServiceClientBuilder().connectionString(connectionString); - if (resourceManagerProvider != null) { - String accountName = storageProperties.getAccount(); - - StorageAccount storageAccount = resourceManagerProvider.getStorageAccountManager().getOrCreate(accountName); - connectionString = StorageConnectionStringProvider.getConnectionString(storageAccount, - environmentProvider.getEnvironment(), storageProperties.isSecureTransfer()); } else { - connectionString = StorageConnectionStringProvider - .getConnectionString(storageProperties.getAccount(), storageProperties.getAccessKey(), - environmentProvider.getEnvironment()); - TelemetryCollector.getInstance().addProperty(STORAGE, ACCOUNT_NAME, storageProperties.getAccount()); + TokenCredential defaultIdentityCredential = new SpringEnvironmentTokenBuilder().fromEnvironment(environment) + .defaultCredential().build(); + authenticatedClientBuilder = new BlobServiceClientBuilder().credential(defaultIdentityCredential); } - - return new BlobServiceClientBuilder().connectionString(connectionString) - .httpLogOptions(new HttpLogOptions().setApplicationId(SPRING_CLOUD_STORAGE_BLOB_APPLICATION_ID)); + return authenticatedClientBuilder + .httpLogOptions(new HttpLogOptions().setApplicationId(SPRING_CLOUD_STORAGE_BLOB_APPLICATION_ID)); } @Bean @ConditionalOnMissingBean public ShareServiceClientBuilder shareServiceClientBuilder(AzureStorageProperties storageProperties, - EnvironmentProvider environmentProvider) { + EnvironmentProvider environmentProvider) { String connectionString; - + String connectionString1; if (resourceManagerProvider != null) { String accountName = storageProperties.getAccount(); StorageAccount storageAccount = resourceManagerProvider.getStorageAccountManager().getOrCreate(accountName); - - connectionString = StorageConnectionStringProvider - .getConnectionString(storageAccount, environmentProvider.getEnvironment(), - storageProperties.isSecureTransfer()); + connectionString1 = StorageConnectionStringProvider.getConnectionString(storageAccount, + environmentProvider.getEnvironment(), storageProperties.isSecureTransfer()); } else { - connectionString = StorageConnectionStringProvider - .getConnectionString(storageProperties.getAccount(), storageProperties.getAccessKey(), - environmentProvider.getEnvironment()); + connectionString1 = StorageConnectionStringProvider.getConnectionString(storageProperties.getAccount(), + storageProperties.getAccessKey(), environmentProvider.getEnvironment()); TelemetryCollector.getInstance().addProperty(STORAGE, ACCOUNT_NAME, storageProperties.getAccount()); } + connectionString = connectionString1; return new ShareServiceClientBuilder().connectionString(connectionString) - .httpLogOptions(new HttpLogOptions().setApplicationId(SPRING_CLOUD_STORAGE_FILE_SHARE_APPLICATION_ID)); + .httpLogOptions(new HttpLogOptions().setApplicationId(SPRING_CLOUD_STORAGE_FILE_SHARE_APPLICATION_ID)); } @Configuration diff --git a/sdk/spring/pom.xml b/sdk/spring/pom.xml index f7f83e16c11e..b7eec58cf019 100644 --- a/sdk/spring/pom.xml +++ b/sdk/spring/pom.xml @@ -39,6 +39,7 @@ azure-spring-boot-samples/azure-spring-boot-sample-servicebus-jms-queue azure-spring-boot-samples/azure-spring-boot-sample-servicebus-jms-topic azure-spring-boot-samples/azure-spring-boot-sample-storage-blob + azure-spring-boot-samples/azure-spring-boot-sample-storage-resource azure-spring-boot-samples/azure-spring-data-sample-gremlin azure-spring-boot-samples/azure-spring-data-sample-gremlin-web-service azure-spring-boot-samples/azure-cloud-foundry-service-sample From 723e46326ee118748a415d56a75bf876e1082b3e Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Sun, 16 Aug 2020 23:17:33 -0400 Subject: [PATCH 17/47] Attempting to generate an endpoint string --- .../src/main/resources/application.properties | 12 +++++----- .../StorageConnectionStringBuilder.java | 24 +++++++++++++++---- .../AzureStorageAutoConfiguration.java | 6 ++++- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties index d48ad9e5632b..f039956ab7b8 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties @@ -1,7 +1,7 @@ # Credential file based usage -spring.cloud.azure.credential-file-path=[credential-file-path] -spring.cloud.azure.resource-group=[resource-group] +# spring.cloud.azure.credential-file-path=[credential-file-path] +# spring.cloud.azure.resource-group=test # Access key based usage @@ -10,15 +10,15 @@ spring.cloud.azure.resource-group=[resource-group] # Storage account name length should be between 3 and 24 # and use numbers and lower-case letters only. -spring.cloud.azure.storage.account=[account-name] +spring.cloud.azure.storage.account=ybstorgtest # Change into your containerName and blobName -blob=azure-blob://containerName/blobName +blob=azure-blob://tainer/yevblob -# spring.cloud.azure.auto-create-resources=true +spring.cloud.azure.auto-create-resources=true # Default environment is GLOBAL. Provide your own if in another environment # Example environment is China, GLOBAL # spring.cloud.azure.environment=[environment] # Example region is westUS, northchina -# spring.cloud.azure.region=[region] +spring.cloud.azure.region=centralus diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/storage/StorageConnectionStringBuilder.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/storage/StorageConnectionStringBuilder.java index 5cfb0856e6f6..1071a208efc7 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/storage/StorageConnectionStringBuilder.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/storage/StorageConnectionStringBuilder.java @@ -5,6 +5,7 @@ import com.microsoft.azure.AzureEnvironment; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; public class StorageConnectionStringBuilder { @@ -23,20 +24,33 @@ public class StorageConnectionStringBuilder { private static final String SEPARATOR = ";"; - public static String build(String accountName, String accountKey, AzureEnvironment environment, boolean - isSecureTransfer) { + private static String build(String accountName, Optional accountKey, AzureEnvironment environment, + boolean isSecureTransfer) { Map map = new HashMap<>(); map.put(DEFAULT_PROTOCOL, resolveProtocol(isSecureTransfer)); map.put(ACCOUNT_NAME, accountName); - map.put(ACCOUNT_KEY, accountKey); - // Remove starting dot since AzureEnvironment.storageEndpointSuffix() starts with dot + + if (accountKey.isPresent()) { + map.put(ACCOUNT_KEY, accountKey.get()); + } + // Remove starting dot since AzureEnvironment.storageEndpointSuffix() starts + // with dot map.put(ENDPOINT_SUFFIX, environment.storageEndpointSuffix().substring(1)); return map.entrySet().stream().map(Object::toString).collect(Collectors.joining(SEPARATOR)); } + public static String build(String accountName, String accountKey, AzureEnvironment environment, + boolean isSecureTransfer) { + return build(accountName, Optional.of(accountKey), environment, isSecureTransfer); + } + public static String build(String accountName, String accountKey, AzureEnvironment environment) { - return build(accountName, accountKey, environment, true); + return build(accountName, Optional.of(accountKey), environment, true); + } + + public static String build(String accountName, AzureEnvironment environment, boolean isSecureTransfer) { + return build(accountName, Optional.empty(), environment, isSecureTransfer); } private static String resolveProtocol(boolean isSecureTransfer) { diff --git a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java index cc0d773626ca..1913b3e6ef01 100644 --- a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java @@ -31,6 +31,7 @@ import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; import com.microsoft.azure.spring.cloud.context.core.api.EnvironmentProvider; import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; +import com.microsoft.azure.spring.cloud.context.core.storage.StorageConnectionStringBuilder; import com.microsoft.azure.spring.cloud.context.core.storage.StorageConnectionStringProvider; import com.microsoft.azure.spring.cloud.storage.AzureStorageProtocolResolver; import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; @@ -86,7 +87,10 @@ public BlobServiceClientBuilder blobServiceClientBuilder(AzureStorageProperties } else { TokenCredential defaultIdentityCredential = new SpringEnvironmentTokenBuilder().fromEnvironment(environment) .defaultCredential().build(); - authenticatedClientBuilder = new BlobServiceClientBuilder().credential(defaultIdentityCredential); + String connectionString = StorageConnectionStringBuilder.build(storageProperties.getAccount(), + environmentProvider.getEnvironment(), storageProperties.isSecureTransfer()); + authenticatedClientBuilder = new BlobServiceClientBuilder().credential(defaultIdentityCredential) + .connectionString(connectionString); } return authenticatedClientBuilder From 62c5533bea31d67b527efcdc44080b0091b2b8d8 Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Thu, 20 Aug 2020 20:12:21 -0400 Subject: [PATCH 18/47] Provisional workaround for using IdentityToken in Shared service connections --- sdk/spring/azure-spring-cloud-context/pom.xml | 71 +++++++++---------- .../AzureEnvironmentAutoConfiguration.java | 3 + .../context/core/api/EnvironmentProvider.java | 14 ++++ .../storage/StorageEndpointStringBuilder.java | 20 ++++++ .../AzureStorageAutoConfiguration.java | 63 +++++++++++----- .../storage/AzureStorageProperties.java | 10 +++ 6 files changed, 128 insertions(+), 53 deletions(-) create mode 100644 sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/storage/StorageEndpointStringBuilder.java diff --git a/sdk/spring/azure-spring-cloud-context/pom.xml b/sdk/spring/azure-spring-cloud-context/pom.xml index 4cbf43f974e6..bdedfcbfea06 100644 --- a/sdk/spring/azure-spring-cloud-context/pom.xml +++ b/sdk/spring/azure-spring-cloud-context/pom.xml @@ -1,26 +1,26 @@ - - com.azure - azure-client-sdk-parent - 1.7.0 - ../../parents/azure-client-sdk-parent - - 4.0.0 + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + com.azure + azure-client-sdk-parent + 1.7.0 + ../../parents/azure-client-sdk-parent + + 4.0.0 com.microsoft.azure spring-cloud-azure-context 1.2.8 - Spring Cloud Azure Context - https://github.com/Azure/azure-sdk-for-java + Spring Cloud Azure Context + https://github.com/Azure/azure-sdk-for-java - - 0.10 - 0.15 - + + 0.10 + 0.15 + @@ -34,17 +34,17 @@ 2.3.3.RELEASE - - org.springframework - spring-context-support - 5.2.8.RELEASE - true - - - commons-io - commons-io - 2.5 - + + org.springframework + spring-context-support + 5.2.8.RELEASE + true + + + commons-io + commons-io + 2.5 + com.microsoft.azure @@ -63,15 +63,6 @@ true - - - com.google.code.findbugs - jsr305 - 3.0.2 - provided - @@ -93,7 +84,15 @@ test - + + + com.google.code.findbugs + jsr305 + 3.0.2 + provided + diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureEnvironmentAutoConfiguration.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureEnvironmentAutoConfiguration.java index 69010683afa6..11314ae04b50 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureEnvironmentAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureEnvironmentAutoConfiguration.java @@ -32,4 +32,7 @@ public EnvironmentProvider environmentProvider() { return defaultEnvironmentProvider; } + + + } diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/api/EnvironmentProvider.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/api/EnvironmentProvider.java index afbd8a74b3d6..ac0a775b2260 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/api/EnvironmentProvider.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/api/EnvironmentProvider.java @@ -3,6 +3,8 @@ package com.microsoft.azure.spring.cloud.context.core.api; +import java.util.Arrays; + import com.microsoft.azure.AzureEnvironment; /** @@ -13,4 +15,16 @@ public interface EnvironmentProvider { AzureEnvironment getEnvironment(); + + /** + * @return The Azure environment as defined by the + * com.azure.core.management SDK. + */ + default com.azure.core.management.AzureEnvironment getCoreEnvironment() { + return Arrays.stream(com.azure.core.management.AzureEnvironment.knownEnvironments()) + .filter(coreEnvironment -> getEnvironment().managementEndpoint() + .equals(coreEnvironment.getManagementEndpoint())) + .findAny().get(); + } + } diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/storage/StorageEndpointStringBuilder.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/storage/StorageEndpointStringBuilder.java new file mode 100644 index 000000000000..9f67fc2fa7ed --- /dev/null +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/storage/StorageEndpointStringBuilder.java @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.microsoft.azure.spring.cloud.context.core.storage; + +import com.microsoft.azure.AzureEnvironment; + +public class StorageEndpointStringBuilder { + public static String buildBlobEndpoint(String storageAccount, AzureEnvironment azureEnvironment, + boolean isSecureTransfer) { + String scheme = isSecureTransfer ? "https://" : "http://"; + return scheme + storageAccount + ".blob" + azureEnvironment.storageEndpointSuffix(); + } + + public static String buildSharesEndpoint(String storageAccount, AzureEnvironment azureEnvironment, + boolean isSecureTransfer) { + String scheme = isSecureTransfer ? "https://" : "http://"; + return scheme + storageAccount + ".file" + azureEnvironment.storageEndpointSuffix(); + } +} diff --git a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java index 1913b3e6ef01..a41482f72e22 100644 --- a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java @@ -6,6 +6,8 @@ import static com.microsoft.azure.spring.cloud.context.core.util.Constants.SPRING_CLOUD_STORAGE_BLOB_APPLICATION_ID; import static com.microsoft.azure.spring.cloud.context.core.util.Constants.SPRING_CLOUD_STORAGE_FILE_SHARE_APPLICATION_ID; +import java.util.Collections; + import javax.annotation.PostConstruct; import org.apache.commons.lang3.StringUtils; @@ -23,16 +25,24 @@ import org.springframework.core.env.Environment; import com.azure.core.credential.TokenCredential; +import com.azure.core.http.HttpClient; +import com.azure.core.http.HttpPipeline; import com.azure.core.http.policy.HttpLogOptions; +import com.azure.core.util.logging.ClientLogger; +import com.azure.resourcemanager.storage.StorageManagementClient; +import com.azure.resourcemanager.storage.StorageManagementClientBuilder; +import com.azure.resourcemanager.storage.fluent.StorageAccountsClient; import com.azure.storage.blob.BlobServiceClientBuilder; +import com.azure.storage.blob.implementation.util.BuilderHelper; +import com.azure.storage.common.policy.RequestRetryOptions; import com.azure.storage.file.share.ShareServiceClientBuilder; import com.microsoft.azure.identity.spring.SpringEnvironmentTokenBuilder; import com.microsoft.azure.management.storage.StorageAccount; import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; import com.microsoft.azure.spring.cloud.context.core.api.EnvironmentProvider; import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; -import com.microsoft.azure.spring.cloud.context.core.storage.StorageConnectionStringBuilder; import com.microsoft.azure.spring.cloud.context.core.storage.StorageConnectionStringProvider; +import com.microsoft.azure.spring.cloud.context.core.storage.StorageEndpointStringBuilder; import com.microsoft.azure.spring.cloud.storage.AzureStorageProtocolResolver; import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; @@ -87,10 +97,10 @@ public BlobServiceClientBuilder blobServiceClientBuilder(AzureStorageProperties } else { TokenCredential defaultIdentityCredential = new SpringEnvironmentTokenBuilder().fromEnvironment(environment) .defaultCredential().build(); - String connectionString = StorageConnectionStringBuilder.build(storageProperties.getAccount(), - environmentProvider.getEnvironment(), storageProperties.isSecureTransfer()); + authenticatedClientBuilder = new BlobServiceClientBuilder().credential(defaultIdentityCredential) - .connectionString(connectionString); + .endpoint(StorageEndpointStringBuilder.buildBlobEndpoint(storageProperties.getAccount(), + environmentProvider.getEnvironment(), storageProperties.isSecureTransfer())); } return authenticatedClientBuilder @@ -101,23 +111,42 @@ public BlobServiceClientBuilder blobServiceClientBuilder(AzureStorageProperties @ConditionalOnMissingBean public ShareServiceClientBuilder shareServiceClientBuilder(AzureStorageProperties storageProperties, EnvironmentProvider environmentProvider) { - String connectionString; - String connectionString1; - if (resourceManagerProvider != null) { - String accountName = storageProperties.getAccount(); - StorageAccount storageAccount = resourceManagerProvider.getStorageAccountManager().getOrCreate(accountName); - connectionString1 = StorageConnectionStringProvider.getConnectionString(storageAccount, - environmentProvider.getEnvironment(), storageProperties.isSecureTransfer()); + ShareServiceClientBuilder authenticatedClientBuilder = null; + // Use storage credentials where provided, default identity otherwise. + if (StringUtils.isNotBlank(storageProperties.getAccessKey())) { + String connectionString; + if (resourceManagerProvider != null) { + String accountName = storageProperties.getAccount(); + + StorageAccount storageAccount = resourceManagerProvider.getStorageAccountManager() + .getOrCreate(accountName); + connectionString = StorageConnectionStringProvider.getConnectionString(storageAccount, + environmentProvider.getEnvironment(), storageProperties.isSecureTransfer()); + } else { + connectionString = StorageConnectionStringProvider.getConnectionString(storageProperties.getAccount(), + storageProperties.getAccessKey(), environmentProvider.getEnvironment()); + TelemetryCollector.getInstance().addProperty(STORAGE, ACCOUNT_NAME, storageProperties.getAccount()); + } + authenticatedClientBuilder = new ShareServiceClientBuilder().connectionString(connectionString); } else { - connectionString1 = StorageConnectionStringProvider.getConnectionString(storageProperties.getAccount(), - storageProperties.getAccessKey(), environmentProvider.getEnvironment()); - TelemetryCollector.getInstance().addProperty(STORAGE, ACCOUNT_NAME, storageProperties.getAccount()); - } - connectionString = connectionString1; + TokenCredential defaultIdentityCredential = new SpringEnvironmentTokenBuilder().fromEnvironment(environment) + .defaultCredential().build(); + + String endpoint = StorageEndpointStringBuilder.buildSharesEndpoint(storageProperties.getAccount(), + environmentProvider.getEnvironment(), storageProperties.isSecureTransfer()); + + HttpPipeline pipeline = BuilderHelper.buildPipeline(null, defaultIdentityCredential, null, endpoint, + new RequestRetryOptions(), new HttpLogOptions(), HttpClient.createDefault(), + Collections.emptyList(), new com.azure.core.util.Configuration(), + new ClientLogger(this.getClass())); - return new ShareServiceClientBuilder().connectionString(connectionString) + authenticatedClientBuilder = new ShareServiceClientBuilder().pipeline(pipeline); + + } + + return authenticatedClientBuilder .httpLogOptions(new HttpLogOptions().setApplicationId(SPRING_CLOUD_STORAGE_FILE_SHARE_APPLICATION_ID)); } diff --git a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageProperties.java b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageProperties.java index 948df2c015cd..79917382c77e 100644 --- a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageProperties.java +++ b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageProperties.java @@ -27,6 +27,8 @@ public class AzureStorageProperties { * Either accessKey or credentialFilePath should be provided */ private String accessKey; + + private String resourceGroup; public String getAccount() { return account; @@ -51,4 +53,12 @@ public boolean isSecureTransfer() { public void setSecureTransfer(boolean secureTransfer) { this.secureTransfer = secureTransfer; } + + public String getResourceGroup() { + return resourceGroup; + } + + public void setResourceGroup(String resourceGroup) { + this.resourceGroup = resourceGroup; + } } From 3f7e8acf06a75a904c2d58d205b99a1e7671df93 Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Mon, 14 Sep 2020 14:56:10 -0400 Subject: [PATCH 19/47] XML syntax fix --- sdk/spring/azure-spring-cloud-context/pom.xml | 77 +++++++++---------- 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/sdk/spring/azure-spring-cloud-context/pom.xml b/sdk/spring/azure-spring-cloud-context/pom.xml index 22d8e15ca046..47367c449047 100644 --- a/sdk/spring/azure-spring-cloud-context/pom.xml +++ b/sdk/spring/azure-spring-cloud-context/pom.xml @@ -1,26 +1,24 @@ - - - com.azure - azure-client-sdk-parent - 1.7.0 - ../../parents/azure-client-sdk-parent - - 4.0.0 + + + com.azure + azure-client-sdk-parent + 1.7.0 + ../../parents/azure-client-sdk-parent + + 4.0.0 com.microsoft.azure spring-cloud-azure-context 1.2.8 - Spring Cloud Azure Context - https://github.com/Azure/azure-sdk-for-java + Spring Cloud Azure Context + https://github.com/Azure/azure-sdk-for-java - - 0.10 - 0.15 - + + 0.10 + 0.15 + @@ -34,17 +32,17 @@ 2.3.3.RELEASE - - org.springframework - spring-context-support - 5.2.8.RELEASE - true - - - commons-io - commons-io - 2.5 - + + org.springframework + spring-context-support + 5.2.8.RELEASE + true + + + commons-io + commons-io + 2.5 + com.microsoft.azure @@ -64,10 +62,10 @@ - com.azure - azure-core-management - 1.0.0-beta.2 - + com.azure + azure-core-management + 1.0.0-beta.2 + @@ -80,7 +78,7 @@ org.mockito mockito-core - 3.3.3 + 3.3.3 test @@ -90,15 +88,16 @@ test - - - com.google.code.findbugs - jsr305 - 3.0.2 - provided - + + com.google.code.findbugs + jsr305 + 3.0.2 + provided + + From 670e4a257b4fc415f79fad5fb7d15455465f7063 Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Thu, 17 Sep 2020 19:22:43 -0400 Subject: [PATCH 20/47] Storage resource demo works --- .../azure-spring-boot-sample-storage-resource/pom.xml | 11 ++++++++++- .../src/main/resources/application.properties | 6 ++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/pom.xml b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/pom.xml index 2e255d1546df..37f58cf3a8e5 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/pom.xml +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/pom.xml @@ -19,7 +19,7 @@ com.microsoft.azure spring-starter-azure-storage - 1.2.8-beta.1 + 1.2.8 @@ -55,4 +55,13 @@ + + + + com.google.code.gson + gson + 2.8.6 + + + diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties index f039956ab7b8..b85086f1d31d 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties @@ -10,12 +10,10 @@ # Storage account name length should be between 3 and 24 # and use numbers and lower-case letters only. -spring.cloud.azure.storage.account=ybstorgtest +spring.cloud.azure.storage.account=accountName # Change into your containerName and blobName -blob=azure-blob://tainer/yevblob - -spring.cloud.azure.auto-create-resources=true +blob=azure-blob://containerName/blobName # Default environment is GLOBAL. Provide your own if in another environment # Example environment is China, GLOBAL From cfef36582e61c085bf9b30de2827d2b6e4119d20 Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Wed, 30 Sep 2020 15:04:21 -0400 Subject: [PATCH 21/47] Removing tight Resource Manager Provider coupling --- .../README.adoc | 2 + .../src/main/resources/application.properties | 10 +- .../cache/AzureRedisAutoConfiguration.java | 29 +- .../AzureEventHubAutoConfiguration.java | 64 +-- .../AzureEventHubKafkaAutoConfiguration.java | 38 +- .../AzureServiceBusAutoConfiguration.java | 27 +- ...AzureServiceBusQueueAutoConfiguration.java | 56 ++- ...AzureServiceBusTopicAutoConfiguration.java | 31 +- .../AzureRedisAutoConfigurationTest.java | 23 +- .../AzureContextAutoConfigurationTest.java | 21 +- ...ureEventHubKafkaAutoConfigurationTest.java | 34 +- .../ServiceBusTestConfiguration.java | 20 +- sdk/spring/azure-spring-cloud-context/pom.xml | 353 ++++++++------- .../AzureContextAutoConfiguration.java | 45 +- ...ureResourceManager20AutoConfiguration.java | 43 ++ .../core/api/ResourceManagerProvider.java | 48 -- .../cloud/context/core/impl/AzureManager.java | 12 +- .../impl/AzureResourceManagerProvider.java | 105 ----- .../impl/EventHubConsumerGroupManager.java | 5 +- .../context/core/impl/EventHubManager.java | 5 +- ...ger.java => EventHubNamespaceManager.java} | 14 +- .../context/core/impl/RedisCacheManager.java | 7 +- .../core/impl/ResourceGroupManager.java | 5 +- ...r.java => ServiceBusNamespaceManager.java} | 14 +- .../core/impl/ServiceBusQueueManager.java | 5 +- .../core/impl/ServiceBusTopicManager.java | 4 +- .../ServiceBusTopicSubscriptionManager.java | 10 +- .../core/impl/StorageAccountManager.java | 14 +- .../core/impl/StorageQueueManager.java | 5 +- .../StorageConnectionStringProvider.java | 15 +- .../config/EventHubBinderConfiguration.java | 37 +- ...tHubChannelResourceManagerProvisioner.java | 39 +- .../ServiceBusQueueBinderConfiguration.java | 47 +- ...ueueChannelResourceManagerProvisioner.java | 31 +- .../ServiceBusTopicBinderConfiguration.java | 54 ++- ...opicChannelResourceManagerProvisioner.java | 37 +- sdk/spring/azure-spring-cloud-storage/pom.xml | 418 +++++++++--------- .../AzureStorageAutoConfiguration.java | 21 +- .../AzureStorageQueueAutoConfiguration.java | 49 +- .../AbstractServiceBusSenderFactory.java | 27 +- .../DefaultServiceBusQueueClientFactory.java | 6 +- .../DefaultServiceBusTopicClientFactory.java | 32 +- 42 files changed, 943 insertions(+), 919 deletions(-) create mode 100644 sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureResourceManager20AutoConfiguration.java delete mode 100644 sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/api/ResourceManagerProvider.java delete mode 100644 sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/AzureResourceManagerProvider.java rename sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/{EventHubNamesapceManager.java => EventHubNamespaceManager.java} (76%) rename sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/{ServiceBusNamesapceManager.java => ServiceBusNamespaceManager.java} (77%) diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/README.adoc b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/README.adoc index 4a721ed4e225..977ad8aefed1 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/README.adoc +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/README.adoc @@ -76,6 +76,8 @@ spring.cloud.azure.resource-group=[resource-group] spring.cloud.azure.storage.account=[account-name] .... + + == How to run 5. Update link:src/main/resources/application.properties[application.properties] diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties index b85086f1d31d..9b14237bbb4a 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties @@ -10,13 +10,17 @@ # Storage account name length should be between 3 and 24 # and use numbers and lower-case letters only. -spring.cloud.azure.storage.account=accountName +spring.cloud.azure.storage.account=ybstortst2 + +spring.cloud.azure.resource-group=test # Change into your containerName and blobName -blob=azure-blob://containerName/blobName +blob=azure-blob://ybstrcntnr/testblob.txt # Default environment is GLOBAL. Provide your own if in another environment # Example environment is China, GLOBAL # spring.cloud.azure.environment=[environment] # Example region is westUS, northchina -spring.cloud.azure.region=centralus +spring.cloud.azure.region=eastus2 + +spring.cloud.azure.auto-create-resources=true diff --git a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/cache/AzureRedisAutoConfiguration.java b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/cache/AzureRedisAutoConfiguration.java index 4c888ee1212a..1d821ca74abf 100644 --- a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/cache/AzureRedisAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/cache/AzureRedisAutoConfiguration.java @@ -3,12 +3,11 @@ package com.microsoft.azure.spring.cloud.autoconfigure.cache; -import com.microsoft.azure.management.redis.RedisCache; -import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; -import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; +import java.util.Arrays; + +import javax.annotation.PostConstruct; + import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -19,8 +18,12 @@ import org.springframework.context.annotation.Primary; import org.springframework.data.redis.core.RedisOperations; -import javax.annotation.PostConstruct; -import java.util.Arrays; +import com.microsoft.azure.management.Azure; +import com.microsoft.azure.management.redis.RedisCache; +import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; +import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; +import com.microsoft.azure.spring.cloud.context.core.impl.RedisCacheManager; +import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; /** * An auto-configuration for Spring cache using Azure redis cache @@ -31,7 +34,6 @@ @AutoConfigureAfter(AzureContextAutoConfiguration.class) @ConditionalOnProperty(value = "spring.cloud.azure.redis.enabled", matchIfMissing = true) @ConditionalOnClass(RedisOperations.class) -@ConditionalOnBean(ResourceManagerProvider.class) @EnableConfigurationProperties(AzureRedisProperties.class) public class AzureRedisAutoConfiguration { private static final String REDIS = "Redis"; @@ -41,14 +43,19 @@ public void collectTelemetry() { TelemetryCollector.getInstance().addService(REDIS); } + @ConditionalOnMissingBean + @Bean + public RedisCacheManager redisCacheManager(Azure azure, AzureProperties azureProperties) { + return new RedisCacheManager(azure, azureProperties); + } + @ConditionalOnMissingBean @Primary @Bean - public RedisProperties redisProperties(ResourceManagerProvider resourceManagerProvider, - AzureRedisProperties azureRedisProperties) { + public RedisProperties redisProperties(AzureRedisProperties azureRedisProperties, RedisCacheManager redisCacheManager) { String cacheName = azureRedisProperties.getName(); - RedisCache redisCache = resourceManagerProvider.getRedisCacheManager().getOrCreate(cacheName); + RedisCache redisCache = redisCacheManager.getOrCreate(cacheName); RedisProperties redisProperties = new RedisProperties(); diff --git a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/eventhub/AzureEventHubAutoConfiguration.java b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/eventhub/AzureEventHubAutoConfiguration.java index 2a2b96ba5f34..5c85443c5ad8 100644 --- a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/eventhub/AzureEventHubAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/eventhub/AzureEventHubAutoConfiguration.java @@ -3,12 +3,25 @@ package com.microsoft.azure.spring.cloud.autoconfigure.eventhub; +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.StringUtils; + import com.azure.messaging.eventhubs.EventHubConsumerAsyncClient; +import com.azure.resourcemanager.storage.models.StorageAccount; import com.microsoft.azure.management.eventhub.EventHubNamespace; -import com.microsoft.azure.management.storage.StorageAccount; import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; import com.microsoft.azure.spring.cloud.context.core.api.EnvironmentProvider; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; +import com.microsoft.azure.spring.cloud.context.core.impl.EventHubNamespaceManager; +import com.microsoft.azure.spring.cloud.context.core.impl.StorageAccountManager; import com.microsoft.azure.spring.cloud.context.core.storage.StorageConnectionStringProvider; import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; import com.microsoft.azure.spring.integration.eventhub.api.EventHubClientFactory; @@ -16,17 +29,6 @@ import com.microsoft.azure.spring.integration.eventhub.factory.DefaultEventHubClientFactory; import com.microsoft.azure.spring.integration.eventhub.factory.EventHubConnectionStringProvider; import com.microsoft.azure.spring.integration.eventhub.impl.EventHubTemplate; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.util.StringUtils; - -import javax.annotation.PostConstruct; /** * An auto-configuration for Event Hub, which provides {@link EventHubOperation} @@ -43,7 +45,10 @@ public class AzureEventHubAutoConfiguration { private static final String NAMESPACE = "Namespace"; @Autowired(required = false) - private ResourceManagerProvider resourceManagerProvider; + private EventHubNamespaceManager eventHubNamespaceManager; + + @Autowired(required = false) + private StorageAccountManager storageAccountManager; @PostConstruct public void collectTelemetry() { @@ -59,10 +64,9 @@ public EventHubOperation eventHubOperation(EventHubClientFactory clientFactory) @Bean @ConditionalOnMissingBean public EventHubConnectionStringProvider eventHubConnectionStringProvider( - AzureEventHubProperties eventHubProperties) { - if (resourceManagerProvider != null) { - EventHubNamespace namespace = resourceManagerProvider.getEventHubNamespaceManager() - .getOrCreate(eventHubProperties.getNamespace()); + AzureEventHubProperties eventHubProperties) { + if (eventHubNamespaceManager != null) { + EventHubNamespace namespace = eventHubNamespaceManager.getOrCreate(eventHubProperties.getNamespace()); return new EventHubConnectionStringProvider(namespace); } else { String connectionString = eventHubProperties.getConnectionString(); @@ -71,8 +75,8 @@ public EventHubConnectionStringProvider eventHubConnectionStringProvider( throw new IllegalArgumentException("Event hubs connection string cannot be empty"); } - TelemetryCollector.getInstance() - .addProperty(EVENT_HUB, NAMESPACE, EventHubUtils.getNamespace(connectionString)); + TelemetryCollector.getInstance().addProperty(EVENT_HUB, NAMESPACE, + EventHubUtils.getNamespace(connectionString)); return new EventHubConnectionStringProvider(connectionString); } } @@ -80,20 +84,20 @@ public EventHubConnectionStringProvider eventHubConnectionStringProvider( @Bean @ConditionalOnMissingBean public EventHubClientFactory clientFactory(EventHubConnectionStringProvider connectionStringProvider, - AzureEventHubProperties eventHubProperties, EnvironmentProvider environmentProvider) { + AzureEventHubProperties eventHubProperties, EnvironmentProvider environmentProvider) { String checkpointConnectionString; - if (resourceManagerProvider != null) { - StorageAccount checkpointStorageAccount = resourceManagerProvider.getStorageAccountManager().getOrCreate( - eventHubProperties.getCheckpointStorageAccount()); - checkpointConnectionString = StorageConnectionStringProvider - .getConnectionString(checkpointStorageAccount, environmentProvider.getEnvironment()); + if (storageAccountManager != null) { + StorageAccount checkpointStorageAccount = storageAccountManager + .getOrCreate(eventHubProperties.getCheckpointStorageAccount()); + checkpointConnectionString = StorageConnectionStringProvider.getConnectionString(checkpointStorageAccount, + environmentProvider.getEnvironment()); } else { - checkpointConnectionString = StorageConnectionStringProvider - .getConnectionString(eventHubProperties.getCheckpointStorageAccount(), - eventHubProperties.getCheckpointAccessKey(), environmentProvider.getEnvironment()); + checkpointConnectionString = StorageConnectionStringProvider.getConnectionString( + eventHubProperties.getCheckpointStorageAccount(), eventHubProperties.getCheckpointAccessKey(), + environmentProvider.getEnvironment()); } return new DefaultEventHubClientFactory(connectionStringProvider, checkpointConnectionString, - eventHubProperties.getCheckpointContainer()); + eventHubProperties.getCheckpointContainer()); } } diff --git a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/eventhub/AzureEventHubKafkaAutoConfiguration.java b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/eventhub/AzureEventHubKafkaAutoConfiguration.java index 4183e04b6d7a..e3491a4a9613 100644 --- a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/eventhub/AzureEventHubKafkaAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/eventhub/AzureEventHubKafkaAutoConfiguration.java @@ -3,12 +3,10 @@ package com.microsoft.azure.spring.cloud.autoconfigure.eventhub; -import com.microsoft.azure.management.eventhub.AuthorizationRule; -import com.microsoft.azure.management.eventhub.EventHubAuthorizationKey; -import com.microsoft.azure.management.eventhub.EventHubNamespace; -import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; -import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; +import java.util.Arrays; + +import javax.annotation.PostConstruct; + import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -19,8 +17,12 @@ import org.springframework.context.annotation.Primary; import org.springframework.kafka.core.KafkaTemplate; -import javax.annotation.PostConstruct; -import java.util.Arrays; +import com.microsoft.azure.management.eventhub.AuthorizationRule; +import com.microsoft.azure.management.eventhub.EventHubAuthorizationKey; +import com.microsoft.azure.management.eventhub.EventHubNamespace; +import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; +import com.microsoft.azure.spring.cloud.context.core.impl.EventHubNamespaceManager; +import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; /** * An auto-configuration for Event Hub, which provides {@link KafkaProperties} @@ -36,8 +38,7 @@ public class AzureEventHubKafkaAutoConfiguration { private static final String SECURITY_PROTOCOL = "security.protocol"; private static final String SASL_SSL = "SASL_SSL"; private static final String SASL_JAAS_CONFIG = "sasl.jaas.config"; - private static final String SASL_CONFIG_VALUE = - "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"$ConnectionString\" " + private static final String SASL_CONFIG_VALUE = "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"$ConnectionString\" " + "password=\"%s\";%n"; private static final String SASL_MECHANISM = "sasl.mechanism"; private static final String SASL_MECHANISM_PLAIN = "PLAIN"; @@ -52,22 +53,21 @@ public void collectTelemetry() { @SuppressWarnings("rawtypes") @Primary @Bean - public KafkaProperties kafkaProperties(ResourceManagerProvider resourceManagerProvider, - AzureEventHubProperties eventHubProperties) { + public KafkaProperties kafkaProperties(EventHubNamespaceManager eventHubNamespaceManager, + AzureEventHubProperties eventHubProperties) { KafkaProperties kafkaProperties = new KafkaProperties(); - EventHubNamespace namespace = - resourceManagerProvider.getEventHubNamespaceManager().getOrCreate(eventHubProperties.getNamespace()); - String connectionString = - namespace.listAuthorizationRules().stream().findFirst().map(AuthorizationRule::getKeys) - .map(EventHubAuthorizationKey::primaryConnectionString).orElseThrow(() -> new RuntimeException( - String.format("Failed to fetch connection string of namespace '%s'", namespace), null)); + EventHubNamespace namespace = eventHubNamespaceManager.getOrCreate(eventHubProperties.getNamespace()); + String connectionString = namespace.listAuthorizationRules().stream().findFirst() + .map(AuthorizationRule::getKeys).map(EventHubAuthorizationKey::primaryConnectionString) + .orElseThrow(() -> new RuntimeException( + String.format("Failed to fetch connection string of namespace '%s'", namespace), null)); String endpoint = namespace.serviceBusEndpoint(); String endpointHost = endpoint.substring("https://".length(), endpoint.lastIndexOf(':')); kafkaProperties.setBootstrapServers(Arrays.asList(endpointHost + ":" + PORT)); kafkaProperties.getProperties().put(SECURITY_PROTOCOL, SASL_SSL); kafkaProperties.getProperties().put(SASL_MECHANISM, SASL_MECHANISM_PLAIN); kafkaProperties.getProperties().put(SASL_JAAS_CONFIG, - String.format(SASL_CONFIG_VALUE, connectionString, System.getProperty("line.separator"))); + String.format(SASL_CONFIG_VALUE, connectionString, System.getProperty("line.separator"))); return kafkaProperties; } } diff --git a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusAutoConfiguration.java b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusAutoConfiguration.java index fc90b0061817..b221fc4fb61a 100644 --- a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusAutoConfiguration.java @@ -3,14 +3,8 @@ package com.microsoft.azure.spring.cloud.autoconfigure.servicebus; -import com.microsoft.azure.management.servicebus.AuthorizationKeys; -import com.microsoft.azure.management.servicebus.ServiceBusNamespace; -import com.microsoft.azure.servicebus.IMessage; -import com.microsoft.azure.servicebus.primitives.ConnectionStringBuilder; -import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManager; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; -import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; +import javax.annotation.PostConstruct; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.AutoConfigureAfter; @@ -22,7 +16,14 @@ import org.springframework.context.annotation.Configuration; import org.springframework.util.StringUtils; -import javax.annotation.PostConstruct; +import com.microsoft.azure.management.servicebus.AuthorizationKeys; +import com.microsoft.azure.management.servicebus.ServiceBusNamespace; +import com.microsoft.azure.servicebus.IMessage; +import com.microsoft.azure.servicebus.primitives.ConnectionStringBuilder; +import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; +import com.microsoft.azure.spring.cloud.context.core.api.ResourceManager; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusNamespaceManager; +import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; /** * An auto-configuration for Service Bus @@ -55,15 +56,13 @@ public void collectTelemetry() { } @Bean - @ConditionalOnBean(ResourceManagerProvider.class) - public AzureServiceBusProperties serviceBusProperties(ResourceManagerProvider resourceManagerProvider, + @ConditionalOnBean(ServiceBusNamespaceManager.class) + public AzureServiceBusProperties serviceBusProperties(ServiceBusNamespaceManager serviceBusNamespaceManager, AzureServiceBusProperties serviceBusProperties) { if (!StringUtils.hasText(serviceBusProperties.getConnectionString())) { - ResourceManager serviceBusNamespaceManager = - resourceManagerProvider.getServiceBusNamespaceManager(); serviceBusNamespaceManager.getOrCreate(serviceBusProperties.getNamespace()); serviceBusProperties.setConnectionString( - buildConnectionString(resourceManagerProvider.getServiceBusNamespaceManager(), + buildConnectionString(serviceBusNamespaceManager, serviceBusProperties.getNamespace())); LOG.info("'spring.cloud.azure.servicebus.connection-string' auto configured"); } diff --git a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusQueueAutoConfiguration.java b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusQueueAutoConfiguration.java index 5d8fde00f3f3..b99b1b6ee7bc 100644 --- a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusQueueAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusQueueAutoConfiguration.java @@ -3,14 +3,8 @@ package com.microsoft.azure.spring.cloud.autoconfigure.servicebus; -import com.microsoft.azure.servicebus.QueueClient; -import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; -import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; -import com.microsoft.azure.spring.integration.servicebus.factory.DefaultServiceBusQueueClientFactory; -import com.microsoft.azure.spring.integration.servicebus.factory.ServiceBusQueueClientFactory; -import com.microsoft.azure.spring.integration.servicebus.queue.ServiceBusQueueOperation; -import com.microsoft.azure.spring.integration.servicebus.queue.ServiceBusQueueTemplate; +import javax.annotation.PostConstruct; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -19,7 +13,18 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import javax.annotation.PostConstruct; +import com.microsoft.azure.management.Azure; +import com.microsoft.azure.servicebus.QueueClient; +import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; +import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusNamespaceManager; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusQueueManager; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusTopicManager; +import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; +import com.microsoft.azure.spring.integration.servicebus.factory.DefaultServiceBusQueueClientFactory; +import com.microsoft.azure.spring.integration.servicebus.factory.ServiceBusQueueClientFactory; +import com.microsoft.azure.spring.integration.servicebus.queue.ServiceBusQueueOperation; +import com.microsoft.azure.spring.integration.servicebus.queue.ServiceBusQueueTemplate; /** * An auto-configuration for Service Bus queue @@ -28,14 +33,20 @@ */ @Configuration @AutoConfigureAfter(AzureContextAutoConfiguration.class) -@ConditionalOnClass(value = {QueueClient.class, ServiceBusQueueClientFactory.class}) +@ConditionalOnClass(value = { QueueClient.class, ServiceBusQueueClientFactory.class }) @ConditionalOnProperty(value = "spring.cloud.azure.servicebus.enabled", matchIfMissing = true) public class AzureServiceBusQueueAutoConfiguration { private static final String SERVICE_BUS_QUEUE = "ServiceBusQueue"; private static final String NAMESPACE = "Namespace"; @Autowired(required = false) - private ResourceManagerProvider resourceManagerProvider; + private ServiceBusNamespaceManager serviceBusNamespaceManager; + + @Autowired(required = false) + private ServiceBusQueueManager serviceBusQueueManager; + + @Autowired(required = false) + private ServiceBusTopicManager serviceBusTopicManager; @PostConstruct public void collectTelemetry() { @@ -46,15 +57,16 @@ public void collectTelemetry() { @ConditionalOnMissingBean public ServiceBusQueueClientFactory queueClientFactory(AzureServiceBusProperties serviceBusProperties) { String connectionString = serviceBusProperties.getConnectionString(); - DefaultServiceBusQueueClientFactory clientFactory = - new DefaultServiceBusQueueClientFactory(serviceBusProperties.getConnectionString()); + DefaultServiceBusQueueClientFactory clientFactory = new DefaultServiceBusQueueClientFactory( + serviceBusProperties.getConnectionString()); - if (resourceManagerProvider != null) { - clientFactory.setResourceManagerProvider(resourceManagerProvider); + if (serviceBusNamespaceManager != null && serviceBusQueueManager != null && serviceBusTopicManager != null) { + clientFactory.setServiceBusNamespaceManager(serviceBusNamespaceManager); + clientFactory.setServiceBusQueueManager(serviceBusQueueManager); clientFactory.setNamespace(serviceBusProperties.getNamespace()); } else { TelemetryCollector.getInstance().addProperty(SERVICE_BUS_QUEUE, NAMESPACE, - ServiceBusUtils.getNamespace(connectionString)); + ServiceBusUtils.getNamespace(connectionString)); } return clientFactory; @@ -65,4 +77,16 @@ public ServiceBusQueueClientFactory queueClientFactory(AzureServiceBusProperties public ServiceBusQueueOperation queueOperation(ServiceBusQueueClientFactory factory) { return new ServiceBusQueueTemplate(factory); } + + @Bean + @ConditionalOnMissingBean + public ServiceBusNamespaceManager serviceBusNamespaceManager(Azure azure, AzureProperties azureProperties) { + return new ServiceBusNamespaceManager(azure, azureProperties); + } + + @Bean + @ConditionalOnMissingBean + public ServiceBusQueueManager serviceBusQueueManager(Azure azure, AzureProperties azureProperties) { + return new ServiceBusQueueManager(azure, azureProperties); + } } diff --git a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusTopicAutoConfiguration.java b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusTopicAutoConfiguration.java index 96299a4f39fe..90aaa862a0db 100644 --- a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusTopicAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusTopicAutoConfiguration.java @@ -3,14 +3,8 @@ package com.microsoft.azure.spring.cloud.autoconfigure.servicebus; -import com.microsoft.azure.servicebus.TopicClient; -import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; -import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; -import com.microsoft.azure.spring.integration.servicebus.factory.DefaultServiceBusTopicClientFactory; -import com.microsoft.azure.spring.integration.servicebus.factory.ServiceBusTopicClientFactory; -import com.microsoft.azure.spring.integration.servicebus.topic.ServiceBusTopicOperation; -import com.microsoft.azure.spring.integration.servicebus.topic.ServiceBusTopicTemplate; +import javax.annotation.PostConstruct; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -19,7 +13,15 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import javax.annotation.PostConstruct; +import com.microsoft.azure.servicebus.TopicClient; +import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusNamespaceManager; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusTopicSubscriptionManager; +import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; +import com.microsoft.azure.spring.integration.servicebus.factory.DefaultServiceBusTopicClientFactory; +import com.microsoft.azure.spring.integration.servicebus.factory.ServiceBusTopicClientFactory; +import com.microsoft.azure.spring.integration.servicebus.topic.ServiceBusTopicOperation; +import com.microsoft.azure.spring.integration.servicebus.topic.ServiceBusTopicTemplate; /** * An auto-configuration for Service Bus topic @@ -34,8 +36,12 @@ public class AzureServiceBusTopicAutoConfiguration { private static final String SERVICE_BUS_TOPIC = "ServiceBusTopic"; private static final String NAMESPACE = "Namespace"; + + @Autowired(required = false) + private ServiceBusTopicSubscriptionManager serviceBusTopicSubscriptionManager; + @Autowired(required = false) - private ResourceManagerProvider resourceManagerProvider; + private ServiceBusNamespaceManager serviceBusNamespaceManager; @PostConstruct public void collectTelemetry() { @@ -49,9 +55,10 @@ public ServiceBusTopicClientFactory topicClientFactory(AzureServiceBusProperties DefaultServiceBusTopicClientFactory clientFactory = new DefaultServiceBusTopicClientFactory(serviceBusProperties.getConnectionString()); - if (resourceManagerProvider != null) { + if (serviceBusTopicSubscriptionManager != null && serviceBusNamespaceManager != null) { clientFactory.setNamespace(serviceBusProperties.getNamespace()); - clientFactory.setResourceManagerProvider(resourceManagerProvider); + clientFactory.setServiceBusNamespaceManager(serviceBusNamespaceManager); + clientFactory.setServiceBusTopicSubscriptionManager(serviceBusTopicSubscriptionManager); } else { TelemetryCollector.getInstance().addProperty(SERVICE_BUS_TOPIC, NAMESPACE, ServiceBusUtils.getNamespace(connectionString)); diff --git a/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/cache/AzureRedisAutoConfigurationTest.java b/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/cache/AzureRedisAutoConfigurationTest.java index 5bc87c74eb75..b37a2aa9821f 100644 --- a/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/cache/AzureRedisAutoConfigurationTest.java +++ b/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/cache/AzureRedisAutoConfigurationTest.java @@ -3,10 +3,11 @@ package com.microsoft.azure.spring.cloud.autoconfigure.cache; -import com.microsoft.azure.management.redis.RedisAccessKeys; -import com.microsoft.azure.management.redis.RedisCache; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; -import com.microsoft.azure.spring.cloud.context.core.impl.RedisCacheManager; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.isA; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.data.redis.RedisProperties; @@ -16,10 +17,9 @@ import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.core.RedisOperations; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import com.microsoft.azure.management.redis.RedisAccessKeys; +import com.microsoft.azure.management.redis.RedisCache; +import com.microsoft.azure.spring.cloud.context.core.impl.RedisCacheManager; public class AzureRedisAutoConfigurationTest { private static final String KEY = "KEY"; @@ -66,9 +66,9 @@ public void testAzureRedisPropertiesConfigured() { static class TestConfiguration { @Bean - ResourceManagerProvider resourceManagerProvider() { + RedisCacheManager redisCacheManager() { - ResourceManagerProvider resourceManagerProvider = mock(ResourceManagerProvider.class); + RedisCacheManager redisCacheManager = mock(RedisCacheManager.class); RedisCache redisCache = mock(RedisCache.class); RedisAccessKeys accessKeys = mock(RedisAccessKeys.class); @@ -78,9 +78,8 @@ ResourceManagerProvider resourceManagerProvider() { when(redisCache.sslPort()).thenReturn(PORT); when(redisCache.shardCount()).thenReturn(0); when(redisCache.getKeys()).thenReturn(accessKeys); - when(resourceManagerProvider.getRedisCacheManager()).thenReturn(redisCacheManager); when(redisCacheManager.getOrCreate(isA(String.class))).thenReturn(redisCache); - return resourceManagerProvider; + return redisCacheManager; } } diff --git a/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfigurationTest.java b/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfigurationTest.java index 96391f3cf0d7..49c9d840453d 100644 --- a/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfigurationTest.java +++ b/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfigurationTest.java @@ -3,12 +3,9 @@ package com.microsoft.azure.spring.cloud.autoconfigure.context; -import com.microsoft.azure.AzureEnvironment; -import com.microsoft.azure.credentials.AzureTokenCredentials; -import com.microsoft.azure.management.Azure; -import com.microsoft.azure.spring.cloud.context.core.api.CredentialsProvider; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; -import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.FilteredClassLoader; @@ -16,8 +13,11 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; +import com.microsoft.azure.AzureEnvironment; +import com.microsoft.azure.credentials.AzureTokenCredentials; +import com.microsoft.azure.management.Azure; +import com.microsoft.azure.spring.cloud.context.core.api.CredentialsProvider; +import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; public class AzureContextAutoConfigurationTest { private ApplicationContextRunner contextRunner = @@ -80,11 +80,6 @@ CredentialsProvider credentialsProvider() { return mock(CredentialsProvider.class); } - @Bean - ResourceManagerProvider resourceManagerProvider() { - return mock(ResourceManagerProvider.class); - } - @Bean AzureTokenCredentials credentials() { return mock(AzureTokenCredentials.class); diff --git a/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/eventhub/AzureEventHubKafkaAutoConfigurationTest.java b/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/eventhub/AzureEventHubKafkaAutoConfigurationTest.java index dfbde9dc6048..5bc49ab3706c 100644 --- a/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/eventhub/AzureEventHubKafkaAutoConfigurationTest.java +++ b/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/eventhub/AzureEventHubKafkaAutoConfigurationTest.java @@ -3,13 +3,12 @@ package com.microsoft.azure.spring.cloud.autoconfigure.eventhub; -import com.microsoft.azure.Page; -import com.microsoft.azure.PagedList; -import com.microsoft.azure.management.eventhub.EventHubAuthorizationKey; -import com.microsoft.azure.management.eventhub.EventHubNamespace; -import com.microsoft.azure.management.eventhub.EventHubNamespaceAuthorizationRule; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; -import com.microsoft.rest.RestException; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; + import org.junit.Ignore; import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -20,11 +19,13 @@ import org.springframework.context.annotation.Configuration; import org.springframework.kafka.core.KafkaTemplate; -import java.io.IOException; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import com.microsoft.azure.Page; +import com.microsoft.azure.PagedList; +import com.microsoft.azure.management.eventhub.EventHubAuthorizationKey; +import com.microsoft.azure.management.eventhub.EventHubNamespace; +import com.microsoft.azure.management.eventhub.EventHubNamespaceAuthorizationRule; +import com.microsoft.azure.spring.cloud.context.core.impl.EventHubNamespaceManager; +import com.microsoft.rest.RestException; public class AzureEventHubKafkaAutoConfigurationTest { private ApplicationContextRunner contextRunner = new ApplicationContextRunner() @@ -72,9 +73,9 @@ public void testAzureEventHubPropertiesConfigured() { static class TestConfiguration { @Bean - ResourceManagerProvider resourceManagerProvider() { + EventHubNamespaceManager eventHubNamespaceManager() { - ResourceManagerProvider resourceManagerProvider = mock(ResourceManagerProvider.class); + EventHubNamespace namespace = mock(EventHubNamespace.class); EventHubAuthorizationKey key = mock(EventHubAuthorizationKey.class); when(key.primaryConnectionString()).thenReturn("connectionString1"); @@ -90,7 +91,10 @@ public Page nextPage(String nextPageLink) rules.add(rule); when(namespace.listAuthorizationRules()).thenReturn(rules); when(namespace.serviceBusEndpoint()).thenReturn("localhost"); - return resourceManagerProvider; + EventHubNamespaceManager eventHubNamespaceManager = mock(EventHubNamespaceManager.class); + //This previously returned a ResourceManagerProvider that was in no way connected to any of the objets created above. + //Maintaining similar behavior in refactoring. + return eventHubNamespaceManager; } } diff --git a/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/ServiceBusTestConfiguration.java b/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/ServiceBusTestConfiguration.java index 2df378146e24..97ada1a3c9dd 100644 --- a/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/ServiceBusTestConfiguration.java +++ b/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/ServiceBusTestConfiguration.java @@ -3,24 +3,22 @@ package com.microsoft.azure.spring.cloud.autoconfigure.servicebus; -import com.microsoft.azure.management.servicebus.ServiceBusNamespace; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; -import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusNamesapceManager; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.microsoft.azure.management.servicebus.ServiceBusNamespace; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusNamespaceManager; + @Configuration public class ServiceBusTestConfiguration { @Bean - ResourceManagerProvider resourceManagerProvider() { - ResourceManagerProvider resourceManagerProvider = mock(ResourceManagerProvider.class); - ServiceBusNamesapceManager namespaceManager = mock(ServiceBusNamesapceManager.class); + ServiceBusNamespaceManager namespaceManager() { + ServiceBusNamespaceManager namespaceManager = mock(ServiceBusNamespaceManager.class); when(namespaceManager.getOrCreate(anyString())).thenReturn(mock(ServiceBusNamespace.class)); - when(resourceManagerProvider.getServiceBusNamespaceManager()).thenReturn(namespaceManager); - return resourceManagerProvider; + return namespaceManager; } } diff --git a/sdk/spring/azure-spring-cloud-context/pom.xml b/sdk/spring/azure-spring-cloud-context/pom.xml index 47367c449047..16d28d108e81 100644 --- a/sdk/spring/azure-spring-cloud-context/pom.xml +++ b/sdk/spring/azure-spring-cloud-context/pom.xml @@ -1,185 +1,196 @@ - - - com.azure - azure-client-sdk-parent - 1.7.0 - ../../parents/azure-client-sdk-parent - - 4.0.0 + + + com.azure + azure-client-sdk-parent + 1.7.0 + ../../parents/azure-client-sdk-parent + + 4.0.0 - com.microsoft.azure - spring-cloud-azure-context - 1.2.8 + com.microsoft.azure + spring-cloud-azure-context + 1.2.8 - Spring Cloud Azure Context - https://github.com/Azure/azure-sdk-for-java + Spring Cloud Azure Context + https://github.com/Azure/azure-sdk-for-java - - 0.10 - 0.15 - + + 0.10 + 0.15 + 1.8 + 1.8 + - - - org.springframework - spring-context - 5.2.8.RELEASE - - - org.springframework.boot - spring-boot-starter-aop - 2.3.3.RELEASE - + + + org.springframework + spring-context + 5.2.8.RELEASE + + + org.springframework.boot + spring-boot-starter-aop + 2.3.3.RELEASE + - - org.springframework - spring-context-support - 5.2.8.RELEASE - true - - - commons-io - commons-io - 2.5 - + + org.springframework + spring-context-support + 5.2.8.RELEASE + true + + + commons-io + commons-io + 2.5 + - - com.microsoft.azure - azure - 1.34.0 - - - com.microsoft.azure - spring-cloud-azure-telemetry - 1.2.8 - - - org.springframework.boot - spring-boot-configuration-processor - 2.3.3.RELEASE - true - + + com.microsoft.azure + azure + 1.34.0 + + + com.microsoft.azure + spring-cloud-azure-telemetry + 1.2.8 + + + org.springframework.boot + spring-boot-configuration-processor + 2.3.3.RELEASE + true + - - com.azure - azure-core-management - 1.0.0-beta.2 - + + + com.azure.resourcemanager + azure-resourcemanager + 2.0.0-beta.5 + + + + com.azure + azure-identity-spring-library + 1.0.0-beta.1 + - - - junit - junit - 4.13 - test - - - org.mockito - mockito-core - 3.3.3 - test - - - org.springframework.boot - spring-boot-starter-test - 2.3.3.RELEASE - test - + + + junit + junit + 4.13 + test + + + org.mockito + mockito-core + 3.3.3 + test + + + org.springframework.boot + spring-boot-starter-test + 2.3.3.RELEASE + test + - - - com.google.code.findbugs - jsr305 - 3.0.2 - provided - - - - - - org.apache.maven.plugins - maven-enforcer-plugin - 3.0.0-M3 - - - - - com.microsoft.azure:azure:[1.34.0] - com.microsoft.azure:spring-cloud-azure-telemetry:[1.2.8] - commons-io:commons-io:[2.5] - org.springframework.boot:spring-boot-configuration-processor:[2.3.3.RELEASE] - org.springframework.boot:spring-boot-starter-aop:[2.3.3.RELEASE] - org.springframework:spring-context-support:[5.2.8.RELEASE] - org.springframework:spring-context:[5.2.8.RELEASE] - - - - - - - - - - - annotation-process-for-java-8 - - [1.8,9) - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - - annotation-process-for-java-8 - - compile - - - - -proc:only - - - - - - - - - - annotation-process-for-java-11 - - [11,) - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - - annotation-process-for-java-11 - - compile - - - - -proc:only - - 11 - - - - - - - - + + com.google.code.findbugs + jsr305 + 3.0.2 + provided + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.0.0-M3 + + + + + com.microsoft.azure:azure:[1.34.0] + com.microsoft.azure:spring-cloud-azure-telemetry:[1.2.8] + commons-io:commons-io:[2.5] + org.springframework.boot:spring-boot-configuration-processor:[2.3.3.RELEASE] + org.springframework.boot:spring-boot-starter-aop:[2.3.3.RELEASE] + org.springframework:spring-context-support:[5.2.8.RELEASE] + org.springframework:spring-context:[5.2.8.RELEASE] + + + + + + + + + + + annotation-process-for-java-8 + + [1.8,9) + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + annotation-process-for-java-8 + + compile + + + + -proc:only + + + + + + + + + + annotation-process-for-java-11 + + [11,) + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + annotation-process-for-java-11 + + compile + + + + -proc:only + + 11 + + + + + + + + diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java index 39c1829fe589..3116c23e811d 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java @@ -3,6 +3,15 @@ package com.microsoft.azure.spring.cloud.autoconfigure.context; +import java.io.IOException; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + import com.microsoft.azure.AzureEnvironment; import com.microsoft.azure.AzureResponseBuilder; import com.microsoft.azure.credentials.AzureTokenCredentials; @@ -11,54 +20,42 @@ import com.microsoft.azure.management.resources.fluentcore.utils.ResourceManagerThrottlingInterceptor; import com.microsoft.azure.serializer.AzureJacksonAdapter; import com.microsoft.azure.spring.cloud.context.core.api.CredentialsProvider; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; -import com.microsoft.azure.spring.cloud.context.core.impl.AzureResourceManagerProvider; import com.microsoft.azure.spring.cloud.context.core.impl.DefaultCredentialsProvider; import com.microsoft.rest.RestClient; -import java.io.IOException; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; /** - * Auto-config to provide default {@link CredentialsProvider} for all Azure services + * Auto-config to provide default {@link CredentialsProvider} for all Azure + * services * * @author Warren Zhu */ @Configuration @EnableConfigurationProperties(AzureProperties.class) @ConditionalOnClass(Azure.class) -@ConditionalOnProperty(prefix = "spring.cloud.azure", value = {"resource-group"}) +@ConditionalOnProperty(prefix = "spring.cloud.azure", value = { "resource-group" }) public class AzureContextAutoConfiguration { - private static final String PROJECT_VERSION = - AzureContextAutoConfiguration.class.getPackage().getImplementationVersion(); + private static final String PROJECT_VERSION = AzureContextAutoConfiguration.class.getPackage() + .getImplementationVersion(); private static final String SPRING_CLOUD_USER_AGENT = "spring-cloud-azure/" + PROJECT_VERSION; - @Bean - @ConditionalOnMissingBean - public ResourceManagerProvider resourceManagerProvider(Azure azure, AzureProperties azureProperties) { - return new AzureResourceManagerProvider(azure, azureProperties); - } @Bean @ConditionalOnMissingBean public Azure azure(AzureTokenCredentials credentials) throws IOException { RestClient restClient = new RestClient.Builder() - .withBaseUrl(credentials.environment(), AzureEnvironment.Endpoint.RESOURCE_MANAGER) - .withCredentials(credentials).withSerializerAdapter(new AzureJacksonAdapter()) - .withResponseBuilderFactory(new AzureResponseBuilder.Factory()) - .withInterceptor(new ProviderRegistrationInterceptor(credentials)) - .withInterceptor(new ResourceManagerThrottlingInterceptor()).withUserAgent(SPRING_CLOUD_USER_AGENT) - .build(); + .withBaseUrl(credentials.environment(), AzureEnvironment.Endpoint.RESOURCE_MANAGER) + .withCredentials(credentials).withSerializerAdapter(new AzureJacksonAdapter()) + .withResponseBuilderFactory(new AzureResponseBuilder.Factory()) + .withInterceptor(new ProviderRegistrationInterceptor(credentials)) + .withInterceptor(new ResourceManagerThrottlingInterceptor()).withUserAgent(SPRING_CLOUD_USER_AGENT) + .build(); return Azure.authenticate(restClient, credentials.domain()).withDefaultSubscription(); } + @Bean @ConditionalOnMissingBean public AzureTokenCredentials credentials(AzureProperties azureProperties) { diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureResourceManager20AutoConfiguration.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureResourceManager20AutoConfiguration.java new file mode 100644 index 000000000000..ca022c2f4624 --- /dev/null +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureResourceManager20AutoConfiguration.java @@ -0,0 +1,43 @@ +package com.microsoft.azure.spring.cloud.autoconfigure.context; + +import java.util.Arrays; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; + +import com.azure.core.credential.TokenCredential; +import com.azure.core.management.profile.AzureProfile; +import com.azure.resourcemanager.Azure; +import com.microsoft.azure.AzureEnvironment; +import com.microsoft.azure.identity.spring.SpringEnvironmentTokenBuilder; +import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; + +@Configuration +@EnableConfigurationProperties(AzureProperties.class) +@ConditionalOnClass(Azure.class) +@ConditionalOnProperty(prefix = "spring.cloud.azure", value = { "resource-group" }) +public class AzureResourceManager20AutoConfiguration { + + @Bean + @ConditionalOnMissingBean + public com.azure.resourcemanager.Azure.Authenticated azure20(TokenCredential tokenCredential, + AzureProperties azureProperties) { + AzureEnvironment legacyEnvironment = azureProperties.getEnvironment(); + com.azure.core.management.AzureEnvironment azureEnvironment = Arrays + .stream(com.azure.core.management.AzureEnvironment.knownEnvironments()) + .filter(env -> env.getManagementEndpoint().equals(legacyEnvironment.managementEndpoint())).findFirst() + .get(); + return com.azure.resourcemanager.Azure.authenticate(tokenCredential, new AzureProfile(azureEnvironment)); + } + + @Bean + @ConditionalOnMissingBean + public TokenCredential tokenCredential(Environment environment) { + return new SpringEnvironmentTokenBuilder().fromEnvironment(environment).build(); + } +} diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/api/ResourceManagerProvider.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/api/ResourceManagerProvider.java deleted file mode 100644 index a62d0550ee1f..000000000000 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/api/ResourceManagerProvider.java +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -package com.microsoft.azure.spring.cloud.context.core.api; - -import com.microsoft.azure.management.eventhub.EventHub; -import com.microsoft.azure.management.eventhub.EventHubConsumerGroup; -import com.microsoft.azure.management.eventhub.EventHubNamespace; -import com.microsoft.azure.management.redis.RedisCache; -import com.microsoft.azure.management.resources.ResourceGroup; -import com.microsoft.azure.management.servicebus.Queue; -import com.microsoft.azure.management.servicebus.ServiceBusNamespace; -import com.microsoft.azure.management.servicebus.ServiceBusSubscription; -import com.microsoft.azure.management.servicebus.Topic; -import com.microsoft.azure.management.storage.StorageAccount; -import com.microsoft.azure.spring.cloud.context.core.util.Tuple; -import com.microsoft.azure.storage.CloudStorageAccount; -import com.microsoft.azure.storage.queue.CloudQueue; - -/** - * Interface to provide {@link ResourceManager} - * - * @author Warren Zhu - */ -public interface ResourceManagerProvider { - - ResourceManager> getEventHubManager(); - - ResourceManager> getEventHubConsumerGroupManager(); - - ResourceManager getResourceGroupManager(); - - ResourceManager getEventHubNamespaceManager(); - - ResourceManager getRedisCacheManager(); - - ResourceManager getServiceBusNamespaceManager(); - - ResourceManager> getServiceBusQueueManager(); - - ResourceManager> getServiceBusTopicManager(); - - ResourceManager getStorageAccountManager(); - - ResourceManager> getStorageQueueManager(); - - ResourceManager> getServiceBusTopicSubscriptionManager(); -} diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/AzureManager.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/AzureManager.java index 3383ba3de97c..00c48b356619 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/AzureManager.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/AzureManager.java @@ -3,24 +3,22 @@ package com.microsoft.azure.spring.cloud.context.core.impl; -import com.microsoft.azure.CloudException; -import com.microsoft.azure.management.Azure; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManager; -import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; import org.apache.commons.lang3.time.StopWatch; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.lang.NonNull; +import com.microsoft.azure.CloudException; +import com.microsoft.azure.spring.cloud.context.core.api.ResourceManager; +import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; + public abstract class AzureManager implements ResourceManager { private static final Logger LOGGER = LoggerFactory.getLogger(AzureManager.class); protected final AzureProperties azureProperties; - protected final Azure azure; - public AzureManager(@NonNull Azure azure, @NonNull AzureProperties azureProperties) { - this.azure = azure; + public AzureManager(@NonNull AzureProperties azureProperties) { this.azureProperties = azureProperties; } diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/AzureResourceManagerProvider.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/AzureResourceManagerProvider.java deleted file mode 100644 index d79bfe33e696..000000000000 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/AzureResourceManagerProvider.java +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -package com.microsoft.azure.spring.cloud.context.core.impl; - -import com.microsoft.azure.management.Azure; -import com.microsoft.azure.management.eventhub.EventHub; -import com.microsoft.azure.management.eventhub.EventHubConsumerGroup; -import com.microsoft.azure.management.eventhub.EventHubNamespace; -import com.microsoft.azure.management.redis.RedisCache; -import com.microsoft.azure.management.resources.ResourceGroup; -import com.microsoft.azure.management.servicebus.Queue; -import com.microsoft.azure.management.servicebus.ServiceBusNamespace; -import com.microsoft.azure.management.servicebus.ServiceBusSubscription; -import com.microsoft.azure.management.servicebus.Topic; -import com.microsoft.azure.management.storage.StorageAccount; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManager; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; -import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; -import com.microsoft.azure.spring.cloud.context.core.util.Tuple; -import com.microsoft.azure.spring.cloud.context.core.util.TypeMap; -import com.microsoft.azure.storage.CloudStorageAccount; -import com.microsoft.azure.storage.queue.CloudQueue; -import org.springframework.lang.NonNull; - -public class AzureResourceManagerProvider implements ResourceManagerProvider { - - private TypeMap resourceManagerByType = new TypeMap(); - - public AzureResourceManagerProvider(@NonNull Azure azure, @NonNull AzureProperties azureProperties) { - this.resourceManagerByType - .put(EventHubNamesapceManager.class, new EventHubNamesapceManager(azure, azureProperties)); - this.resourceManagerByType.put(EventHubManager.class, new EventHubManager(azure, azureProperties)); - this.resourceManagerByType - .put(EventHubConsumerGroupManager.class, new EventHubConsumerGroupManager(azure, azureProperties)); - this.resourceManagerByType.put(RedisCacheManager.class, new RedisCacheManager(azure, azureProperties)); - this.resourceManagerByType.put(ResourceGroupManager.class, new ResourceGroupManager(azure, azureProperties)); - this.resourceManagerByType - .put(ServiceBusNamesapceManager.class, new ServiceBusNamesapceManager(azure, azureProperties)); - this.resourceManagerByType - .put(ServiceBusQueueManager.class, new ServiceBusQueueManager(azure, azureProperties)); - this.resourceManagerByType - .put(ServiceBusTopicManager.class, new ServiceBusTopicManager(azure, azureProperties)); - this.resourceManagerByType.put(ServiceBusTopicSubscriptionManager.class, - new ServiceBusTopicSubscriptionManager(azure, azureProperties)); - this.resourceManagerByType.put(StorageAccountManager.class, new StorageAccountManager(azure, azureProperties)); - this.resourceManagerByType.put(StorageQueueManager.class, new StorageQueueManager(azure, azureProperties)); - this.getResourceGroupManager().getOrCreate(azureProperties.getResourceGroup()); - } - - @Override - public ResourceManager> getEventHubManager() { - return this.resourceManagerByType.get(EventHubManager.class); - } - - @Override - public ResourceManager> getEventHubConsumerGroupManager() { - return this.resourceManagerByType.get(EventHubConsumerGroupManager.class); - } - - @Override - public ResourceManager getResourceGroupManager() { - return this.resourceManagerByType.get(ResourceGroupManager.class); - } - - @Override - public ResourceManager getEventHubNamespaceManager() { - return this.resourceManagerByType.get(EventHubNamesapceManager.class); - } - - @Override - public ResourceManager getRedisCacheManager() { - return this.resourceManagerByType.get(RedisCacheManager.class); - } - - @Override - public ResourceManager getServiceBusNamespaceManager() { - return this.resourceManagerByType.get(ServiceBusNamesapceManager.class); - } - - @Override - public ResourceManager> getServiceBusQueueManager() { - return this.resourceManagerByType.get(ServiceBusQueueManager.class); - } - - @Override - public ResourceManager> getServiceBusTopicManager() { - return this.resourceManagerByType.get(ServiceBusTopicManager.class); - } - - @Override - public ResourceManager getStorageAccountManager() { - return this.resourceManagerByType.get(StorageAccountManager.class); - } - - @Override - public ResourceManager> getStorageQueueManager() { - return this.resourceManagerByType.get(StorageQueueManager.class); - } - - @Override - public ResourceManager> getServiceBusTopicSubscriptionManager() { - return this.resourceManagerByType.get(ServiceBusTopicSubscriptionManager.class); - } -} diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/EventHubConsumerGroupManager.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/EventHubConsumerGroupManager.java index b728e89898ff..366dbef667f6 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/EventHubConsumerGroupManager.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/EventHubConsumerGroupManager.java @@ -11,8 +11,11 @@ public class EventHubConsumerGroupManager extends AzureManager> { + private final Azure azure; + public EventHubConsumerGroupManager(Azure azure, AzureProperties azureProperties) { - super(azure, azureProperties); + super(azureProperties); + this.azure = azure; } @Override diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/EventHubManager.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/EventHubManager.java index 11908886383a..1da9da23ed23 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/EventHubManager.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/EventHubManager.java @@ -10,9 +10,12 @@ import com.microsoft.azure.spring.cloud.context.core.util.Tuple; public class EventHubManager extends AzureManager> { + + private final Azure azure; public EventHubManager(Azure azure, AzureProperties azureProperties) { - super(azure, azureProperties); + super(azureProperties); + this.azure = azure; } @Override diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/EventHubNamesapceManager.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/EventHubNamespaceManager.java similarity index 76% rename from sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/EventHubNamesapceManager.java rename to sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/EventHubNamespaceManager.java index 4f635cf19fb0..90721ff764d7 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/EventHubNamesapceManager.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/EventHubNamespaceManager.java @@ -7,10 +7,13 @@ import com.microsoft.azure.management.eventhub.EventHubNamespace; import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; -public class EventHubNamesapceManager extends AzureManager { +public class EventHubNamespaceManager extends AzureManager { - public EventHubNamesapceManager(Azure azure, AzureProperties azureProperties) { - super(azure, azureProperties); + private final Azure azure; + + public EventHubNamespaceManager(Azure azure, AzureProperties azureProperties) { + super(azureProperties); + this.azure = azure; } @Override @@ -28,7 +31,8 @@ public EventHubNamespace internalGet(String namespace) { try { return azure.eventHubNamespaces().getByResourceGroup(azureProperties.getResourceGroup(), namespace); } catch (NullPointerException e) { - // azure management api has no way to determine whether an eventhub namespace exists + // azure management api has no way to determine whether an eventhub namespace + // exists // Workaround for this is by catching NPE return null; } @@ -37,6 +41,6 @@ public EventHubNamespace internalGet(String namespace) { @Override public EventHubNamespace internalCreate(String namespace) { return azure.eventHubNamespaces().define(namespace).withRegion(azureProperties.getRegion()) - .withExistingResourceGroup(azureProperties.getResourceGroup()).create(); + .withExistingResourceGroup(azureProperties.getResourceGroup()).create(); } } diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/RedisCacheManager.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/RedisCacheManager.java index 24d14cf30859..c913c85e7430 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/RedisCacheManager.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/RedisCacheManager.java @@ -9,8 +9,11 @@ public class RedisCacheManager extends AzureManager { + private final Azure azure; + public RedisCacheManager(Azure azure, AzureProperties azureProperties) { - super(azure, azureProperties); + super(azureProperties); + this.azure = azure; } @Override @@ -31,6 +34,6 @@ public RedisCache internalGet(String name) { @Override public RedisCache internalCreate(String name) { return azure.redisCaches().define(name).withRegion(azureProperties.getRegion()) - .withExistingResourceGroup(azureProperties.getResourceGroup()).withBasicSku().create(); + .withExistingResourceGroup(azureProperties.getResourceGroup()).withBasicSku().create(); } } diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ResourceGroupManager.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ResourceGroupManager.java index 480163f72a03..01d5a28145d4 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ResourceGroupManager.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ResourceGroupManager.java @@ -9,8 +9,11 @@ public class ResourceGroupManager extends AzureManager { + private final Azure azure; + public ResourceGroupManager(Azure azure, AzureProperties azureProperties) { - super(azure, azureProperties); + super(azureProperties); + this.azure = azure; } @Override diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusNamesapceManager.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusNamespaceManager.java similarity index 77% rename from sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusNamesapceManager.java rename to sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusNamespaceManager.java index 8d34a2a8b8a7..f9c302de7444 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusNamesapceManager.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusNamespaceManager.java @@ -7,10 +7,13 @@ import com.microsoft.azure.management.servicebus.ServiceBusNamespace; import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; -public class ServiceBusNamesapceManager extends AzureManager { +public class ServiceBusNamespaceManager extends AzureManager { - public ServiceBusNamesapceManager(Azure azure, AzureProperties azureProperties) { - super(azure, azureProperties); + private final Azure azure; + + public ServiceBusNamespaceManager(Azure azure, AzureProperties azureProperties) { + super(azureProperties); + this.azure = azure; } @Override @@ -28,7 +31,8 @@ public ServiceBusNamespace internalGet(String namespace) { try { return azure.serviceBusNamespaces().getByResourceGroup(azureProperties.getResourceGroup(), namespace); } catch (NullPointerException e) { - // azure management api has no way to determine whether an eventhub namespace exists + // azure management api has no way to determine whether an eventhub namespace + // exists // Workaround for this is by catching NPE return null; } @@ -37,6 +41,6 @@ public ServiceBusNamespace internalGet(String namespace) { @Override public ServiceBusNamespace internalCreate(String namespace) { return azure.serviceBusNamespaces().define(namespace).withRegion(azureProperties.getRegion()) - .withExistingResourceGroup(azureProperties.getResourceGroup()).create(); + .withExistingResourceGroup(azureProperties.getResourceGroup()).create(); } } diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusQueueManager.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusQueueManager.java index 569a7b1feba4..c45882470bc9 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusQueueManager.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusQueueManager.java @@ -11,8 +11,11 @@ public class ServiceBusQueueManager extends AzureManager> { + private final Azure azure; + public ServiceBusQueueManager(Azure azure, AzureProperties azureProperties) { - super(azure, azureProperties); + super(azureProperties); + this.azure = azure; } @Override diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusTopicManager.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusTopicManager.java index 36f29cdfb4ec..1844da95ca4f 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusTopicManager.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusTopicManager.java @@ -11,8 +11,10 @@ public class ServiceBusTopicManager extends AzureManager> { + private final Azure azure; public ServiceBusTopicManager(Azure azure, AzureProperties azureProperties) { - super(azure, azureProperties); + super(azureProperties); + this.azure = azure; } @Override diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusTopicSubscriptionManager.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusTopicSubscriptionManager.java index 0856f94ac86f..5f7167a3d4a9 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusTopicSubscriptionManager.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusTopicSubscriptionManager.java @@ -11,8 +11,11 @@ public class ServiceBusTopicSubscriptionManager extends AzureManager> { + private final Azure azure; + public ServiceBusTopicSubscriptionManager(Azure azure, AzureProperties azureProperties) { - super(azure, azureProperties); + super(azureProperties); + this.azure = azure; } @Override @@ -30,7 +33,8 @@ public ServiceBusSubscription internalGet(Tuple topicAndSubscript try { return topicAndSubscriptionName.getFirst().subscriptions().getByName(topicAndSubscriptionName.getSecond()); } catch (NullPointerException ignore) { - // azure management api has no way to determine whether an service bus topic subscription exists + // azure management api has no way to determine whether an service bus topic + // subscription exists // Workaround for this is by catching NPE return null; } @@ -39,6 +43,6 @@ public ServiceBusSubscription internalGet(Tuple topicAndSubscript @Override public ServiceBusSubscription internalCreate(Tuple topicAndSubscriptionName) { return topicAndSubscriptionName.getFirst().subscriptions().define(topicAndSubscriptionName.getSecond()) - .create(); + .create(); } } diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/StorageAccountManager.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/StorageAccountManager.java index b51b7e06f4a8..6f816ec05e7e 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/StorageAccountManager.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/StorageAccountManager.java @@ -3,14 +3,19 @@ package com.microsoft.azure.spring.cloud.context.core.impl; -import com.microsoft.azure.management.Azure; -import com.microsoft.azure.management.storage.StorageAccount; +import javax.annotation.Nonnull; + +import com.azure.resourcemanager.Azure; +import com.azure.resourcemanager.storage.models.StorageAccount; import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; public class StorageAccountManager extends AzureManager { + + private final Azure azure; - public StorageAccountManager(Azure azure, AzureProperties azureProperties) { - super(azure, azureProperties); + public StorageAccountManager(@Nonnull Azure azure, AzureProperties azureProperties) { + super(azureProperties); + this.azure = azure; } @Override @@ -25,6 +30,7 @@ String getResourceType() { @Override public StorageAccount internalGet(String key) { + return azure.storageAccounts().getByResourceGroup(azureProperties.getResourceGroup(), key); } diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/StorageQueueManager.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/StorageQueueManager.java index 888cd107d2fe..4e01838d1c11 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/StorageQueueManager.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/StorageQueueManager.java @@ -14,8 +14,11 @@ public class StorageQueueManager extends AzureManager> { + private final Azure azure; + public StorageQueueManager(Azure azure, AzureProperties azureProperties) { - super(azure, azureProperties); + super(azureProperties); + this.azure = azure; } @Override diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/storage/StorageConnectionStringProvider.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/storage/StorageConnectionStringProvider.java index 48671023b857..df32b465ad7e 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/storage/StorageConnectionStringProvider.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/storage/StorageConnectionStringProvider.java @@ -3,13 +3,13 @@ package com.microsoft.azure.spring.cloud.context.core.storage; +import com.azure.resourcemanager.storage.models.StorageAccount; import com.microsoft.azure.AzureEnvironment; -import com.microsoft.azure.management.storage.StorageAccount; public class StorageConnectionStringProvider { public static String getConnectionString(StorageAccount storageAccount, AzureEnvironment environment, - boolean isSecureTransfer) { + boolean isSecureTransfer) { return buildConnectionString(storageAccount, environment, isSecureTransfer); } @@ -22,14 +22,15 @@ public static String getConnectionString(String storageAccount, String accessKey } public static String getConnectionString(String storageAccount, String accessKey, AzureEnvironment environment, - boolean isSecureTransfer) { + boolean isSecureTransfer) { return StorageConnectionStringBuilder.build(storageAccount, accessKey, environment, isSecureTransfer); } private static String buildConnectionString(StorageAccount storageAccount, AzureEnvironment environment, - boolean isSecureTransfer) { - return storageAccount.getKeys().stream().findFirst().map(key -> StorageConnectionStringBuilder - .build(storageAccount.name(), key.value(), environment, isSecureTransfer)) - .orElseThrow(() -> new RuntimeException("Storage account key is empty.")); + boolean isSecureTransfer) { + return storageAccount + .getKeys().stream().findFirst().map(key -> StorageConnectionStringBuilder.build(storageAccount.name(), + key.value(), environment, isSecureTransfer)) + .orElseThrow(() -> new RuntimeException("Storage account key is empty.")); } } diff --git a/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/config/EventHubBinderConfiguration.java b/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/config/EventHubBinderConfiguration.java index fa76bfeeb7d6..8644ee6e5601 100644 --- a/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/config/EventHubBinderConfiguration.java +++ b/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/config/EventHubBinderConfiguration.java @@ -3,6 +3,16 @@ package com.microsoft.azure.eventhub.stream.binder.config; +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.stream.binder.Binder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + import com.microsoft.azure.eventhub.stream.binder.EventHubMessageChannelBinder; import com.microsoft.azure.eventhub.stream.binder.properties.EventHubExtendedBindingProperties; import com.microsoft.azure.eventhub.stream.binder.provisioning.EventHubChannelProvisioner; @@ -11,18 +21,11 @@ import com.microsoft.azure.spring.cloud.autoconfigure.eventhub.AzureEventHubAutoConfiguration; import com.microsoft.azure.spring.cloud.autoconfigure.eventhub.AzureEventHubProperties; import com.microsoft.azure.spring.cloud.autoconfigure.eventhub.EventHubUtils; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; +import com.microsoft.azure.spring.cloud.context.core.impl.EventHubConsumerGroupManager; +import com.microsoft.azure.spring.cloud.context.core.impl.EventHubManager; +import com.microsoft.azure.spring.cloud.context.core.impl.EventHubNamespaceManager; import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; import com.microsoft.azure.spring.integration.eventhub.api.EventHubOperation; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.stream.binder.Binder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -import javax.annotation.PostConstruct; /** * @author Warren Zhu @@ -36,8 +39,16 @@ public class EventHubBinderConfiguration { private static final String EVENT_HUB_BINDER = "EventHubBinder"; private static final String NAMESPACE = "Namespace"; + @Autowired(required = false) - private ResourceManagerProvider resourceManagerProvider; + private EventHubNamespaceManager eventHubNamespaceManager; + + @Autowired(required=false) + private EventHubManager eventHubManager; + + @Autowired(required=false) + private EventHubConsumerGroupManager eventHubConsumerGroupManager; + @PostConstruct public void collectTelemetry() { @@ -47,8 +58,8 @@ public void collectTelemetry() { @Bean @ConditionalOnMissingBean public EventHubChannelProvisioner eventHubChannelProvisioner(AzureEventHubProperties eventHubProperties) { - if (resourceManagerProvider != null) { - return new EventHubChannelResourceManagerProvisioner(resourceManagerProvider, + if (eventHubNamespaceManager != null && eventHubManager != null && eventHubConsumerGroupManager!=null) { + return new EventHubChannelResourceManagerProvisioner(eventHubNamespaceManager, eventHubManager, eventHubConsumerGroupManager, eventHubProperties.getNamespace()); } else { TelemetryCollector.getInstance().addProperty(EVENT_HUB_BINDER, NAMESPACE, diff --git a/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/provisioning/EventHubChannelResourceManagerProvisioner.java b/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/provisioning/EventHubChannelResourceManagerProvisioner.java index 1e68dedf6bac..ca523ca54480 100644 --- a/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/provisioning/EventHubChannelResourceManagerProvisioner.java +++ b/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/provisioning/EventHubChannelResourceManagerProvisioner.java @@ -3,48 +3,51 @@ package com.microsoft.azure.eventhub.stream.binder.provisioning; -import com.microsoft.azure.management.eventhub.EventHub; -import com.microsoft.azure.management.eventhub.EventHubNamespace; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; -import com.microsoft.azure.spring.cloud.context.core.util.Tuple; import org.springframework.cloud.stream.provisioning.ProvisioningException; import org.springframework.lang.NonNull; import org.springframework.util.Assert; +import com.microsoft.azure.management.eventhub.EventHub; +import com.microsoft.azure.management.eventhub.EventHubNamespace; +import com.microsoft.azure.spring.cloud.context.core.impl.EventHubConsumerGroupManager; +import com.microsoft.azure.spring.cloud.context.core.impl.EventHubManager; +import com.microsoft.azure.spring.cloud.context.core.impl.EventHubNamespaceManager; +import com.microsoft.azure.spring.cloud.context.core.util.Tuple; + /** * @author Warren Zhu */ public class EventHubChannelResourceManagerProvisioner extends EventHubChannelProvisioner { private final String namespace; - private final ResourceManagerProvider resourceManagerProvider; + private final EventHubNamespaceManager eventHubNamespaceManager; + private final EventHubManager eventHubManager; + private final EventHubConsumerGroupManager eventHubConsumerGroupManager; - public EventHubChannelResourceManagerProvisioner(@NonNull ResourceManagerProvider resourceManagerProvider, - @NonNull String namespace) { + public EventHubChannelResourceManagerProvisioner(@NonNull EventHubNamespaceManager eventHubNamespaceManager, + @NonNull EventHubManager eventHubManager, + @NonNull EventHubConsumerGroupManager eventHubConsumerGroupManager, @NonNull String namespace) { Assert.hasText(namespace, "The namespace can't be null or empty"); this.namespace = namespace; - this.resourceManagerProvider = resourceManagerProvider; + this.eventHubNamespaceManager = eventHubNamespaceManager; + this.eventHubManager = eventHubManager; + this.eventHubConsumerGroupManager = eventHubConsumerGroupManager; } @Override protected void validateOrCreateForConsumer(String name, String group) { - EventHubNamespace eventHubNamespace = - this.resourceManagerProvider.getEventHubNamespaceManager().getOrCreate(namespace); - EventHub eventHub = this.resourceManagerProvider.getEventHubManager().get(Tuple.of(eventHubNamespace, name)); + EventHubNamespace eventHubNamespace = eventHubNamespaceManager.getOrCreate(namespace); + EventHub eventHub = eventHubManager.get(Tuple.of(eventHubNamespace, name)); if (eventHub == null) { throw new ProvisioningException( String.format("Event hub with name '%s' in namespace '%s' not existed", name, namespace)); } - this.resourceManagerProvider.getEventHubConsumerGroupManager().getOrCreate(Tuple.of(eventHub, group)); + eventHubConsumerGroupManager.getOrCreate(Tuple.of(eventHub, group)); } @Override protected void validateOrCreateForProducer(String name) { - if (resourceManagerProvider == null) { - return; - } - EventHubNamespace eventHubNamespace = - this.resourceManagerProvider.getEventHubNamespaceManager().getOrCreate(namespace); - this.resourceManagerProvider.getEventHubManager().getOrCreate(Tuple.of(eventHubNamespace, name)); + EventHubNamespace eventHubNamespace = eventHubNamespaceManager.getOrCreate(namespace); + eventHubManager.getOrCreate(Tuple.of(eventHubNamespace, name)); } } diff --git a/sdk/spring/azure-spring-cloud-servicebus-queue-stream-binder/src/main/java/com/microsoft/azure/servicebus/stream/binder/config/ServiceBusQueueBinderConfiguration.java b/sdk/spring/azure-spring-cloud-servicebus-queue-stream-binder/src/main/java/com/microsoft/azure/servicebus/stream/binder/config/ServiceBusQueueBinderConfiguration.java index 2ca0b56dcb74..571aae24b38d 100644 --- a/sdk/spring/azure-spring-cloud-servicebus-queue-stream-binder/src/main/java/com/microsoft/azure/servicebus/stream/binder/config/ServiceBusQueueBinderConfiguration.java +++ b/sdk/spring/azure-spring-cloud-servicebus-queue-stream-binder/src/main/java/com/microsoft/azure/servicebus/stream/binder/config/ServiceBusQueueBinderConfiguration.java @@ -3,6 +3,17 @@ package com.microsoft.azure.servicebus.stream.binder.config; +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.stream.binder.Binder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + import com.microsoft.azure.servicebus.stream.binder.ServiceBusQueueMessageChannelBinder; import com.microsoft.azure.servicebus.stream.binder.properties.ServiceBusQueueExtendedBindingProperties; import com.microsoft.azure.servicebus.stream.binder.provisioning.ServiceBusChannelProvisioner; @@ -11,34 +22,28 @@ import com.microsoft.azure.spring.cloud.autoconfigure.servicebus.AzureServiceBusProperties; import com.microsoft.azure.spring.cloud.autoconfigure.servicebus.AzureServiceBusQueueAutoConfiguration; import com.microsoft.azure.spring.cloud.autoconfigure.servicebus.ServiceBusUtils; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusNamespaceManager; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusQueueManager; import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; import com.microsoft.azure.spring.integration.servicebus.queue.ServiceBusQueueOperation; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.stream.binder.Binder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -import javax.annotation.PostConstruct; /** * @author Warren Zhu */ @Configuration @ConditionalOnMissingBean(Binder.class) -@Import({AzureServiceBusQueueAutoConfiguration.class, AzureEnvironmentAutoConfiguration.class}) -@EnableConfigurationProperties({AzureServiceBusProperties.class, ServiceBusQueueExtendedBindingProperties.class}) +@Import({ AzureServiceBusQueueAutoConfiguration.class, AzureEnvironmentAutoConfiguration.class }) +@EnableConfigurationProperties({ AzureServiceBusProperties.class, ServiceBusQueueExtendedBindingProperties.class }) public class ServiceBusQueueBinderConfiguration { private static final String SERVICE_BUS_QUEUE_BINDER = "ServiceBusQueueBinder"; private static final String NAMESPACE = "Namespace"; @Autowired(required = false) - private ResourceManagerProvider resourceManagerProvider; + private ServiceBusNamespaceManager serviceBusNamespaceManager; + + @Autowired(required = false) + private ServiceBusQueueManager serviceBusQueueManager; @PostConstruct public void collectTelemetry() { @@ -46,12 +51,12 @@ public void collectTelemetry() { } @Bean - @ConditionalOnBean(ResourceManagerProvider.class) + @ConditionalOnBean({ ServiceBusNamespaceManager.class, ServiceBusQueueManager.class }) @ConditionalOnMissingBean public ServiceBusChannelProvisioner serviceBusChannelProvisioner(AzureServiceBusProperties serviceBusProperties) { - if (this.resourceManagerProvider != null) { - return new ServiceBusQueueChannelResourceManagerProvisioner(resourceManagerProvider, - serviceBusProperties.getNamespace()); + if (this.serviceBusNamespaceManager != null && serviceBusQueueManager != null) { + return new ServiceBusQueueChannelResourceManagerProvisioner(serviceBusNamespaceManager, + serviceBusQueueManager, serviceBusProperties.getNamespace()); } else { TelemetryCollector.getInstance().addProperty(SERVICE_BUS_QUEUE_BINDER, NAMESPACE, ServiceBusUtils.getNamespace(serviceBusProperties.getConnectionString())); @@ -60,7 +65,7 @@ public ServiceBusChannelProvisioner serviceBusChannelProvisioner(AzureServiceBus } @Bean - @ConditionalOnMissingBean({ResourceManagerProvider.class, ServiceBusChannelProvisioner.class}) + @ConditionalOnMissingBean(ServiceBusChannelProvisioner.class) public ServiceBusChannelProvisioner serviceBusChannelProvisionerWithResourceManagerProvider() { return new ServiceBusChannelProvisioner(); } @@ -69,8 +74,8 @@ public ServiceBusChannelProvisioner serviceBusChannelProvisionerWithResourceMana public ServiceBusQueueMessageChannelBinder serviceBusQueueBinder( ServiceBusChannelProvisioner queueChannelProvisioner, ServiceBusQueueOperation serviceBusQueueOperation, ServiceBusQueueExtendedBindingProperties bindingProperties) { - ServiceBusQueueMessageChannelBinder binder = - new ServiceBusQueueMessageChannelBinder(null, queueChannelProvisioner, serviceBusQueueOperation); + ServiceBusQueueMessageChannelBinder binder = new ServiceBusQueueMessageChannelBinder(null, + queueChannelProvisioner, serviceBusQueueOperation); binder.setBindingProperties(bindingProperties); return binder; } diff --git a/sdk/spring/azure-spring-cloud-servicebus-queue-stream-binder/src/main/java/com/microsoft/azure/servicebus/stream/binder/provisioning/ServiceBusQueueChannelResourceManagerProvisioner.java b/sdk/spring/azure-spring-cloud-servicebus-queue-stream-binder/src/main/java/com/microsoft/azure/servicebus/stream/binder/provisioning/ServiceBusQueueChannelResourceManagerProvisioner.java index ed60343c779a..d0744749803f 100644 --- a/sdk/spring/azure-spring-cloud-servicebus-queue-stream-binder/src/main/java/com/microsoft/azure/servicebus/stream/binder/provisioning/ServiceBusQueueChannelResourceManagerProvisioner.java +++ b/sdk/spring/azure-spring-cloud-servicebus-queue-stream-binder/src/main/java/com/microsoft/azure/servicebus/stream/binder/provisioning/ServiceBusQueueChannelResourceManagerProvisioner.java @@ -3,34 +3,38 @@ package com.microsoft.azure.servicebus.stream.binder.provisioning; -import com.microsoft.azure.management.servicebus.Queue; -import com.microsoft.azure.management.servicebus.ServiceBusNamespace; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; -import com.microsoft.azure.spring.cloud.context.core.util.Tuple; import org.springframework.cloud.stream.provisioning.ProvisioningException; import org.springframework.lang.NonNull; import org.springframework.util.Assert; +import com.microsoft.azure.management.servicebus.Queue; +import com.microsoft.azure.management.servicebus.ServiceBusNamespace; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusNamespaceManager; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusQueueManager; +import com.microsoft.azure.spring.cloud.context.core.util.Tuple; + /** * @author Warren Zhu */ public class ServiceBusQueueChannelResourceManagerProvisioner extends ServiceBusChannelProvisioner { - private final ResourceManagerProvider resourceManagerProvider; private final String namespace; + private final ServiceBusNamespaceManager serviceBusNamespaceManager; + private final ServiceBusQueueManager serviceBusQueueManager; - public ServiceBusQueueChannelResourceManagerProvisioner(@NonNull ResourceManagerProvider resourceManagerProvider, - @NonNull String namespace) { + public ServiceBusQueueChannelResourceManagerProvisioner( + @NonNull ServiceBusNamespaceManager serviceBusNamespaceManager, + @NonNull ServiceBusQueueManager serviceBusQueueManager, @NonNull String namespace) { Assert.hasText(namespace, "The namespace can't be null or empty"); - this.resourceManagerProvider = resourceManagerProvider; + this.serviceBusNamespaceManager = serviceBusNamespaceManager; + this.serviceBusQueueManager = serviceBusQueueManager; this.namespace = namespace; } @Override protected void validateOrCreateForConsumer(String name, String group) { - ServiceBusNamespace namespace = - this.resourceManagerProvider.getServiceBusNamespaceManager().getOrCreate(this.namespace); - Queue queue = this.resourceManagerProvider.getServiceBusQueueManager().getOrCreate(Tuple.of(namespace, name)); + ServiceBusNamespace namespace = serviceBusNamespaceManager.getOrCreate(this.namespace); + Queue queue = serviceBusQueueManager.getOrCreate(Tuple.of(namespace, name)); if (queue == null) { throw new ProvisioningException( String.format("Event hub with name '%s' in namespace '%s' not existed", name, namespace)); @@ -39,8 +43,7 @@ protected void validateOrCreateForConsumer(String name, String group) { @Override protected void validateOrCreateForProducer(String name) { - ServiceBusNamespace namespace = - this.resourceManagerProvider.getServiceBusNamespaceManager().getOrCreate(this.namespace); - this.resourceManagerProvider.getServiceBusQueueManager().getOrCreate(Tuple.of(namespace, name)); + ServiceBusNamespace namespace = serviceBusNamespaceManager.getOrCreate(this.namespace); + serviceBusQueueManager.getOrCreate(Tuple.of(namespace, name)); } } diff --git a/sdk/spring/azure-spring-cloud-servicebus-topic-stream-binder/src/main/java/com/microsoft/azure/servicebus/stream/binder/config/ServiceBusTopicBinderConfiguration.java b/sdk/spring/azure-spring-cloud-servicebus-topic-stream-binder/src/main/java/com/microsoft/azure/servicebus/stream/binder/config/ServiceBusTopicBinderConfiguration.java index cf4c1c8f9c4c..17396ea7129e 100644 --- a/sdk/spring/azure-spring-cloud-servicebus-topic-stream-binder/src/main/java/com/microsoft/azure/servicebus/stream/binder/config/ServiceBusTopicBinderConfiguration.java +++ b/sdk/spring/azure-spring-cloud-servicebus-topic-stream-binder/src/main/java/com/microsoft/azure/servicebus/stream/binder/config/ServiceBusTopicBinderConfiguration.java @@ -3,6 +3,17 @@ package com.microsoft.azure.servicebus.stream.binder.config; +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.stream.binder.Binder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + import com.microsoft.azure.servicebus.stream.binder.ServiceBusTopicMessageChannelBinder; import com.microsoft.azure.servicebus.stream.binder.properties.ServiceBusTopicExtendedBindingProperties; import com.microsoft.azure.servicebus.stream.binder.provisioning.ServiceBusChannelProvisioner; @@ -11,34 +22,32 @@ import com.microsoft.azure.spring.cloud.autoconfigure.servicebus.AzureServiceBusProperties; import com.microsoft.azure.spring.cloud.autoconfigure.servicebus.AzureServiceBusTopicAutoConfiguration; import com.microsoft.azure.spring.cloud.autoconfigure.servicebus.ServiceBusUtils; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusNamespaceManager; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusTopicManager; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusTopicSubscriptionManager; import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; import com.microsoft.azure.spring.integration.servicebus.topic.ServiceBusTopicOperation; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.stream.binder.Binder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -import javax.annotation.PostConstruct; /** * @author Warren Zhu */ @Configuration @ConditionalOnMissingBean(Binder.class) -@Import({AzureServiceBusTopicAutoConfiguration.class, AzureEnvironmentAutoConfiguration.class}) -@EnableConfigurationProperties({AzureServiceBusProperties.class, ServiceBusTopicExtendedBindingProperties.class}) +@Import({ AzureServiceBusTopicAutoConfiguration.class, AzureEnvironmentAutoConfiguration.class }) +@EnableConfigurationProperties({ AzureServiceBusProperties.class, ServiceBusTopicExtendedBindingProperties.class }) public class ServiceBusTopicBinderConfiguration { private static final String SERVICE_BUS_TOPIC_BINDER = "ServiceBusTopicBinder"; private static final String NAMESPACE = "Namespace"; @Autowired(required = false) - private ResourceManagerProvider resourceManagerProvider; + private ServiceBusNamespaceManager serviceBusNamespaceManager; + + @Autowired(required = false) + private ServiceBusTopicManager serviceBusTopicManager; + + @Autowired(required = false) + private ServiceBusTopicSubscriptionManager serviceBusTopicSubscriptionManager; @PostConstruct public void collectTelemetry() { @@ -46,12 +55,14 @@ public void collectTelemetry() { } @Bean - @ConditionalOnBean(ResourceManagerProvider.class) + @ConditionalOnBean({ ServiceBusNamespaceManager.class, ServiceBusTopicManager.class, + ServiceBusTopicSubscriptionManager.class }) @ConditionalOnMissingBean public ServiceBusChannelProvisioner serviceBusChannelProvisioner(AzureServiceBusProperties serviceBusProperties) { - if (this.resourceManagerProvider != null) { - return new ServiceBusTopicChannelResourceManagerProvisioner(resourceManagerProvider, - serviceBusProperties.getNamespace()); + if (this.serviceBusNamespaceManager != null && this.serviceBusTopicManager != null + && this.serviceBusTopicSubscriptionManager != null) { + return new ServiceBusTopicChannelResourceManagerProvisioner(serviceBusNamespaceManager, + serviceBusTopicManager, serviceBusTopicSubscriptionManager, serviceBusProperties.getNamespace()); } else { TelemetryCollector.getInstance().addProperty(SERVICE_BUS_TOPIC_BINDER, NAMESPACE, ServiceBusUtils.getNamespace(serviceBusProperties.getConnectionString())); @@ -60,7 +71,8 @@ public ServiceBusChannelProvisioner serviceBusChannelProvisioner(AzureServiceBus } @Bean - @ConditionalOnMissingBean({ResourceManagerProvider.class, ServiceBusChannelProvisioner.class}) + @ConditionalOnMissingBean({ ServiceBusNamespaceManager.class, ServiceBusTopicManager.class, + ServiceBusTopicSubscriptionManager.class, ServiceBusChannelProvisioner.class }) public ServiceBusChannelProvisioner serviceBusChannelProvisionerWithResourceManagerProvider() { return new ServiceBusChannelProvisioner(); } @@ -69,8 +81,8 @@ public ServiceBusChannelProvisioner serviceBusChannelProvisionerWithResourceMana public ServiceBusTopicMessageChannelBinder serviceBusTopicBinder( ServiceBusChannelProvisioner topicChannelProvisioner, ServiceBusTopicOperation serviceBusTopicOperation, ServiceBusTopicExtendedBindingProperties bindingProperties) { - ServiceBusTopicMessageChannelBinder binder = - new ServiceBusTopicMessageChannelBinder(null, topicChannelProvisioner, serviceBusTopicOperation); + ServiceBusTopicMessageChannelBinder binder = new ServiceBusTopicMessageChannelBinder(null, + topicChannelProvisioner, serviceBusTopicOperation); binder.setBindingProperties(bindingProperties); return binder; } diff --git a/sdk/spring/azure-spring-cloud-servicebus-topic-stream-binder/src/main/java/com/microsoft/azure/servicebus/stream/binder/provisioning/ServiceBusTopicChannelResourceManagerProvisioner.java b/sdk/spring/azure-spring-cloud-servicebus-topic-stream-binder/src/main/java/com/microsoft/azure/servicebus/stream/binder/provisioning/ServiceBusTopicChannelResourceManagerProvisioner.java index 8c15c34d27eb..a765a2d601eb 100644 --- a/sdk/spring/azure-spring-cloud-servicebus-topic-stream-binder/src/main/java/com/microsoft/azure/servicebus/stream/binder/provisioning/ServiceBusTopicChannelResourceManagerProvisioner.java +++ b/sdk/spring/azure-spring-cloud-servicebus-topic-stream-binder/src/main/java/com/microsoft/azure/servicebus/stream/binder/provisioning/ServiceBusTopicChannelResourceManagerProvisioner.java @@ -3,46 +3,53 @@ package com.microsoft.azure.servicebus.stream.binder.provisioning; -import com.microsoft.azure.management.servicebus.ServiceBusNamespace; -import com.microsoft.azure.management.servicebus.Topic; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; -import com.microsoft.azure.spring.cloud.context.core.util.Tuple; import org.springframework.cloud.stream.provisioning.ProvisioningException; import org.springframework.lang.NonNull; import org.springframework.util.Assert; +import com.microsoft.azure.management.servicebus.ServiceBusNamespace; +import com.microsoft.azure.management.servicebus.Topic; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusNamespaceManager; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusTopicManager; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusTopicSubscriptionManager; +import com.microsoft.azure.spring.cloud.context.core.util.Tuple; + /** * @author Warren Zhu */ public class ServiceBusTopicChannelResourceManagerProvisioner extends ServiceBusChannelProvisioner { - private final ResourceManagerProvider resourceManagerProvider; + private final ServiceBusNamespaceManager serviceBusNamespaceManager; + private final ServiceBusTopicManager serviceBusTopicManager; + private final ServiceBusTopicSubscriptionManager serviceBusTopicSubscriptionManager; private final String namespace; - public ServiceBusTopicChannelResourceManagerProvisioner(@NonNull ResourceManagerProvider resourceManagerProvider, - @NonNull String namespace) { + public ServiceBusTopicChannelResourceManagerProvisioner( + @NonNull ServiceBusNamespaceManager serviceBusNamespaceManager, + @NonNull ServiceBusTopicManager serviceBusTopicManager, + @NonNull ServiceBusTopicSubscriptionManager serviceBusTopicSubscriptionManager, @NonNull String namespace) { Assert.hasText(namespace, "The namespace can't be null or empty"); - this.resourceManagerProvider = resourceManagerProvider; + this.serviceBusNamespaceManager = serviceBusNamespaceManager; + this.serviceBusTopicManager = serviceBusTopicManager; + this.serviceBusTopicSubscriptionManager = serviceBusTopicSubscriptionManager; this.namespace = namespace; } @Override protected void validateOrCreateForConsumer(String name, String group) { - ServiceBusNamespace namespace = - this.resourceManagerProvider.getServiceBusNamespaceManager().getOrCreate(this.namespace); - Topic topic = this.resourceManagerProvider.getServiceBusTopicManager().getOrCreate(Tuple.of(namespace, name)); + ServiceBusNamespace namespace = serviceBusNamespaceManager.getOrCreate(this.namespace); + Topic topic = serviceBusTopicManager.getOrCreate(Tuple.of(namespace, name)); if (topic == null) { throw new ProvisioningException( String.format("Event hub with name '%s' in namespace '%s' not existed", name, namespace)); } - this.resourceManagerProvider.getServiceBusTopicSubscriptionManager().getOrCreate(Tuple.of(topic, group)); + this.serviceBusTopicSubscriptionManager.getOrCreate(Tuple.of(topic, group)); } @Override protected void validateOrCreateForProducer(String name) { - ServiceBusNamespace namespace = - this.resourceManagerProvider.getServiceBusNamespaceManager().getOrCreate(this.namespace); - this.resourceManagerProvider.getServiceBusTopicManager().getOrCreate(Tuple.of(namespace, name)); + ServiceBusNamespace namespace = serviceBusNamespaceManager.getOrCreate(this.namespace); + serviceBusTopicManager.getOrCreate(Tuple.of(namespace, name)); } } diff --git a/sdk/spring/azure-spring-cloud-storage/pom.xml b/sdk/spring/azure-spring-cloud-storage/pom.xml index dfc22eee99af..73708ff7da0e 100644 --- a/sdk/spring/azure-spring-cloud-storage/pom.xml +++ b/sdk/spring/azure-spring-cloud-storage/pom.xml @@ -1,223 +1,223 @@ - - com.azure - azure-client-sdk-parent - 1.7.0 - ../../parents/azure-client-sdk-parent - - 4.0.0 - - com.microsoft.azure - spring-cloud-azure-storage - 1.2.8 - - Azure Spring Cloud Storage - - - - com.microsoft.azure - spring-cloud-azure-context - 1.2.8 - - - - com.azure - azure-storage-blob - 12.8.0 - - - - com.azure - azure-storage-file-share - 12.6.0 - - - - org.springframework.boot - spring-boot-configuration-processor - 2.3.3.RELEASE - true - - - - - com.azure - azure-storage-queue - 12.6.0 - true - + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + com.azure + azure-client-sdk-parent + 1.7.0 + ../../parents/azure-client-sdk-parent + + 4.0.0 + + com.microsoft.azure + spring-cloud-azure-storage + 1.2.8 + + Azure Spring Cloud Storage + + + + com.microsoft.azure + spring-cloud-azure-context + 1.2.8 + + + + com.azure + azure-storage-blob + 12.8.0 + + + + com.azure + azure-storage-file-share + 12.6.0 + + + + org.springframework.boot + spring-boot-configuration-processor + 2.3.3.RELEASE + true + + + + + com.azure + azure-storage-queue + 12.6.0 + true + com.azure.resourcemanager azure-resourcemanager-storage - 2.0.0-beta.3 + 2.0.0-beta.5 - - - com.microsoft.azure - spring-integration-storage-queue - 1.2.8 - true - + + + com.microsoft.azure + spring-integration-storage-queue + 1.2.8 + true + - + com.azure azure-identity-spring-library 1.0.0-beta.1 - - - - - org.springframework.boot - spring-boot-actuator-autoconfigure - 2.3.3.RELEASE - true - - - - org.hibernate.validator - hibernate-validator - 6.1.5.Final - - - - org.springframework.boot - spring-boot-starter-logging - 2.3.3.RELEASE - - - - org.springframework.boot - spring-boot-starter-test - 2.3.3.RELEASE - test - - - - junit - junit - 4.13 - test - - - - org.mockito - mockito-core - 3.3.3 - test - - - - org.powermock - powermock-api-mockito2 - 2.0.2 - test - - - - org.powermock - powermock-module-junit4 - 2.0.2 - test - - - - - com.google.code.findbugs - jsr305 - 3.0.2 - provided - - - - - - - org.apache.maven.plugins - maven-enforcer-plugin - 3.0.0-M3 - - - - - com.microsoft.azure:spring-cloud-azure-context:[1.2.8] - com.microsoft.azure:spring-integration-storage-queue:[1.2.8] - org.hibernate.validator:hibernate-validator:[6.1.5.Final] - org.springframework.boot:spring-boot-actuator-autoconfigure:[2.3.3.RELEASE] - org.springframework.boot:spring-boot-configuration-processor:[2.3.3.RELEASE] - org.springframework.boot:spring-boot-starter-logging:[2.3.3.RELEASE] - - - - - - - - - - - annotation-process-for-java-8 - - [1.8,9) - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - - annotation-process-for-java-8 - - compile - - - - -proc:only - - - - - - - - - - annotation-process-for-java-11 - - [11,) - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - - annotation-process-for-java-11 - - compile - - - - -proc:only - - 11 - - - - - - - - + + + + + org.springframework.boot + spring-boot-actuator-autoconfigure + 2.3.3.RELEASE + true + + + + org.hibernate.validator + hibernate-validator + 6.1.5.Final + + + + org.springframework.boot + spring-boot-starter-logging + 2.3.3.RELEASE + + + + org.springframework.boot + spring-boot-starter-test + 2.3.3.RELEASE + test + + + + junit + junit + 4.13 + test + + + + org.mockito + mockito-core + 3.3.3 + test + + + + org.powermock + powermock-api-mockito2 + 2.0.2 + test + + + + org.powermock + powermock-module-junit4 + 2.0.2 + test + + + + + com.google.code.findbugs + jsr305 + 3.0.2 + provided + + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.0.0-M3 + + + + + com.microsoft.azure:spring-cloud-azure-context:[1.2.8] + com.microsoft.azure:spring-integration-storage-queue:[1.2.8] + org.hibernate.validator:hibernate-validator:[6.1.5.Final] + org.springframework.boot:spring-boot-actuator-autoconfigure:[2.3.3.RELEASE] + org.springframework.boot:spring-boot-configuration-processor:[2.3.3.RELEASE] + org.springframework.boot:spring-boot-starter-logging:[2.3.3.RELEASE] + + + + + + + + + + + annotation-process-for-java-8 + + [1.8,9) + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + annotation-process-for-java-8 + + compile + + + + -proc:only + + + + + + + + + + annotation-process-for-java-11 + + [11,) + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + annotation-process-for-java-11 + + compile + + + + -proc:only + + 11 + + + + + + + + diff --git a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java index a41482f72e22..2507d09b428b 100644 --- a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java @@ -29,18 +29,15 @@ import com.azure.core.http.HttpPipeline; import com.azure.core.http.policy.HttpLogOptions; import com.azure.core.util.logging.ClientLogger; -import com.azure.resourcemanager.storage.StorageManagementClient; -import com.azure.resourcemanager.storage.StorageManagementClientBuilder; -import com.azure.resourcemanager.storage.fluent.StorageAccountsClient; +import com.azure.resourcemanager.storage.models.StorageAccount; import com.azure.storage.blob.BlobServiceClientBuilder; import com.azure.storage.blob.implementation.util.BuilderHelper; import com.azure.storage.common.policy.RequestRetryOptions; import com.azure.storage.file.share.ShareServiceClientBuilder; import com.microsoft.azure.identity.spring.SpringEnvironmentTokenBuilder; -import com.microsoft.azure.management.storage.StorageAccount; import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; import com.microsoft.azure.spring.cloud.context.core.api.EnvironmentProvider; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; +import com.microsoft.azure.spring.cloud.context.core.impl.StorageAccountManager; import com.microsoft.azure.spring.cloud.context.core.storage.StorageConnectionStringProvider; import com.microsoft.azure.spring.cloud.context.core.storage.StorageEndpointStringBuilder; import com.microsoft.azure.spring.cloud.storage.AzureStorageProtocolResolver; @@ -62,7 +59,7 @@ public class AzureStorageAutoConfiguration { private static final String ACCOUNT_NAME = "AccountName"; @Autowired(required = false) - private ResourceManagerProvider resourceManagerProvider; + private StorageAccountManager storageAccountManager; @PostConstruct public void collectTelemetry() { @@ -82,9 +79,8 @@ public BlobServiceClientBuilder blobServiceClientBuilder(AzureStorageProperties // Use storage credentials where provided, default identity otherwise. if (StringUtils.isNotBlank(storageProperties.getAccessKey())) { String connectionString = null; - if (resourceManagerProvider != null) { - StorageAccount storageAccount = resourceManagerProvider.getStorageAccountManager() - .getOrCreate(storageProperties.getAccount()); + if (storageAccountManager != null) { + StorageAccount storageAccount = storageAccountManager.getOrCreate(storageProperties.getAccount()); connectionString = StorageConnectionStringProvider.getConnectionString(storageAccount, environmentProvider.getEnvironment(), storageProperties.isSecureTransfer()); } else { @@ -116,11 +112,10 @@ public ShareServiceClientBuilder shareServiceClientBuilder(AzureStoragePropertie // Use storage credentials where provided, default identity otherwise. if (StringUtils.isNotBlank(storageProperties.getAccessKey())) { String connectionString; - if (resourceManagerProvider != null) { + if (storageAccountManager != null) { String accountName = storageProperties.getAccount(); - StorageAccount storageAccount = resourceManagerProvider.getStorageAccountManager() - .getOrCreate(accountName); + StorageAccount storageAccount = storageAccountManager.getOrCreate(accountName); connectionString = StorageConnectionStringProvider.getConnectionString(storageAccount, environmentProvider.getEnvironment(), storageProperties.isSecureTransfer()); } else { @@ -143,7 +138,7 @@ public ShareServiceClientBuilder shareServiceClientBuilder(AzureStoragePropertie new ClientLogger(this.getClass())); authenticatedClientBuilder = new ShareServiceClientBuilder().pipeline(pipeline); - + } return authenticatedClientBuilder diff --git a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageQueueAutoConfiguration.java b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageQueueAutoConfiguration.java index 482fea994694..3d719521b8e5 100644 --- a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageQueueAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageQueueAutoConfiguration.java @@ -3,32 +3,33 @@ package com.microsoft.azure.spring.cloud.autoconfigure.storage; +import javax.annotation.PostConstruct; + +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.azure.resourcemanager.storage.models.StorageAccount; import com.azure.storage.queue.QueueServiceClient; -import com.microsoft.azure.management.storage.StorageAccount; import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureEnvironmentAutoConfiguration; import com.microsoft.azure.spring.cloud.context.core.api.EnvironmentProvider; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; +import com.microsoft.azure.spring.cloud.context.core.impl.StorageAccountManager; import com.microsoft.azure.spring.cloud.context.core.storage.StorageConnectionStringProvider; import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; import com.microsoft.azure.spring.integration.storage.queue.StorageQueueOperation; import com.microsoft.azure.spring.integration.storage.queue.StorageQueueTemplate; import com.microsoft.azure.spring.integration.storage.queue.factory.DefaultStorageQueueClientFactory; import com.microsoft.azure.spring.integration.storage.queue.factory.StorageQueueClientFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import javax.annotation.PostConstruct; @Configuration -@AutoConfigureAfter({AzureContextAutoConfiguration.class, AzureEnvironmentAutoConfiguration.class}) -@ConditionalOnClass({QueueServiceClient.class, StorageQueueClientFactory.class}) +@AutoConfigureAfter({ AzureContextAutoConfiguration.class, AzureEnvironmentAutoConfiguration.class, + AzureStorageAutoConfiguration.class }) +@ConditionalOnClass({ QueueServiceClient.class, StorageQueueClientFactory.class }) @ConditionalOnProperty(name = "spring.cloud.azure.storage.account") @EnableConfigurationProperties(AzureStorageProperties.class) public class AzureStorageQueueAutoConfiguration { @@ -37,9 +38,6 @@ public class AzureStorageQueueAutoConfiguration { private static final String STORAGE = "Storage"; private static final String ACCOUNT_NAME = "AccountName"; - @Autowired(required = false) - private ResourceManagerProvider resourceManagerProvider; - @PostConstruct public void collectTelemetry() { TelemetryCollector.getInstance().addService(STORAGE_QUEUE); @@ -48,23 +46,16 @@ public void collectTelemetry() { @Bean @ConditionalOnMissingBean StorageQueueClientFactory storageQueueClientFactory(AzureStorageProperties storageProperties, - EnvironmentProvider environmentProvider) { + StorageAccountManager storageAccountManager, EnvironmentProvider environmentProvider) { String connectionString; - if (resourceManagerProvider != null) { - String accountName = storageProperties.getAccount(); + String accountName = storageProperties.getAccount(); - StorageAccount storageAccount = resourceManagerProvider.getStorageAccountManager().getOrCreate(accountName); + StorageAccount storageAccount = storageAccountManager.getOrCreate(accountName); - connectionString = StorageConnectionStringProvider - .getConnectionString(storageAccount, environmentProvider.getEnvironment(), - storageProperties.isSecureTransfer()); - } else { - connectionString = StorageConnectionStringProvider - .getConnectionString(storageProperties.getAccount(), storageProperties.getAccessKey(), - environmentProvider.getEnvironment()); - } + connectionString = StorageConnectionStringProvider.getConnectionString(storageAccount, + environmentProvider.getEnvironment(), storageProperties.isSecureTransfer()); return new DefaultStorageQueueClientFactory(connectionString); } diff --git a/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/AbstractServiceBusSenderFactory.java b/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/AbstractServiceBusSenderFactory.java index 6456448ab65f..781e4c1f5e22 100644 --- a/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/AbstractServiceBusSenderFactory.java +++ b/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/AbstractServiceBusSenderFactory.java @@ -3,7 +3,10 @@ package com.microsoft.azure.spring.integration.servicebus.factory; -import com.microsoft.azure.spring.cloud.context.core.api.ResourceManagerProvider; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusNamespaceManager; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusQueueManager; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusTopicManager; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusTopicSubscriptionManager; /** * Base class of service bus client factory to provide connection string @@ -12,15 +15,31 @@ */ abstract class AbstractServiceBusSenderFactory implements ServiceBusSenderFactory { protected final String connectionString; + protected ServiceBusNamespaceManager serviceBusNamespaceManager; + protected ServiceBusQueueManager serviceBusQueueManager; + protected ServiceBusTopicManager serviceBusTopicManager; + protected ServiceBusTopicSubscriptionManager serviceBusTopicSubscriptionManager; protected String namespace; - protected ResourceManagerProvider resourceManagerProvider; AbstractServiceBusSenderFactory(String connectionString) { this.connectionString = connectionString; } - public void setResourceManagerProvider(ResourceManagerProvider resourceManagerProvider) { - this.resourceManagerProvider = resourceManagerProvider; + public void setServiceBusNamespaceManager(ServiceBusNamespaceManager serviceBusNamespaceManager) { + this.serviceBusNamespaceManager = serviceBusNamespaceManager; + } + + public void setServiceBusQueueManager(ServiceBusQueueManager serviceBusQueueManager) { + this.serviceBusQueueManager = serviceBusQueueManager; + } + + public void setServiceBusTopicManager(ServiceBusTopicManager serviceBusTopicManager) { + this.serviceBusTopicManager = serviceBusTopicManager; + } + + public void setServiceBusTopicSubscriptionManager( + ServiceBusTopicSubscriptionManager serviceBusTopicSubscriptionManager) { + this.serviceBusTopicSubscriptionManager = serviceBusTopicSubscriptionManager; } public void setNamespace(String namespace) { diff --git a/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/DefaultServiceBusQueueClientFactory.java b/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/DefaultServiceBusQueueClientFactory.java index 4b633c4000ef..9c121d92005e 100644 --- a/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/DefaultServiceBusQueueClientFactory.java +++ b/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/DefaultServiceBusQueueClientFactory.java @@ -33,10 +33,10 @@ public DefaultServiceBusQueueClientFactory(String connectionString) { } private IQueueClient createQueueClient(String destination) { - if (resourceManagerProvider != null && StringUtils.hasText(namespace)) { + if (StringUtils.hasText(namespace)) { ServiceBusNamespace serviceBusNamespace = - resourceManagerProvider.getServiceBusNamespaceManager().getOrCreate(namespace); - resourceManagerProvider.getServiceBusQueueManager().getOrCreate(Tuple.of(serviceBusNamespace, destination)); + serviceBusNamespaceManager.getOrCreate(namespace); + serviceBusQueueManager.getOrCreate(Tuple.of(serviceBusNamespace, destination)); } try { diff --git a/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/DefaultServiceBusTopicClientFactory.java b/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/DefaultServiceBusTopicClientFactory.java index 983149ce72d4..98141bdadeb7 100644 --- a/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/DefaultServiceBusTopicClientFactory.java +++ b/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/DefaultServiceBusTopicClientFactory.java @@ -12,6 +12,8 @@ import com.microsoft.azure.servicebus.TopicClient; import com.microsoft.azure.servicebus.primitives.ConnectionStringBuilder; import com.microsoft.azure.servicebus.primitives.ServiceBusException; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusNamespaceManager; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusTopicSubscriptionManager; import com.microsoft.azure.spring.cloud.context.core.util.Memoizer; import com.microsoft.azure.spring.cloud.context.core.util.Tuple; import com.microsoft.azure.spring.integration.servicebus.ServiceBusRuntimeException; @@ -21,46 +23,44 @@ import java.util.function.Function; /** - * Default implementation of {@link ServiceBusTopicClientFactory}. - * Client will be cached to improve performance + * Default implementation of {@link ServiceBusTopicClientFactory}. Client will + * be cached to improve performance * * @author Warren Zhu */ public class DefaultServiceBusTopicClientFactory extends AbstractServiceBusSenderFactory - implements ServiceBusTopicClientFactory { + implements ServiceBusTopicClientFactory { private static final String SUBSCRIPTION_PATH = "%s/subscriptions/%s"; - private final BiFunction subscriptionClientCreator = - Memoizer.memoize(this::createSubscriptionClient); + private final BiFunction subscriptionClientCreator = Memoizer + .memoize(this::createSubscriptionClient); private final Function sendCreator = Memoizer.memoize(this::createTopicClient); + public DefaultServiceBusTopicClientFactory(String connectionString) { super(connectionString); } private ISubscriptionClient createSubscriptionClient(String topicName, String subscription) { - if (resourceManagerProvider != null && StringUtils.hasText(namespace)) { - ServiceBusNamespace serviceBusNamespace = - resourceManagerProvider.getServiceBusNamespaceManager().getOrCreate(namespace); - Topic topic = resourceManagerProvider.getServiceBusTopicManager() - .getOrCreate(Tuple.of(serviceBusNamespace, topicName)); - resourceManagerProvider.getServiceBusTopicSubscriptionManager().getOrCreate(Tuple.of(topic, subscription)); + if (StringUtils.hasText(namespace)) { + ServiceBusNamespace serviceBusNamespace = serviceBusNamespaceManager.getOrCreate(namespace); + Topic topic = serviceBusTopicManager.getOrCreate(Tuple.of(serviceBusNamespace, topicName)); + serviceBusTopicSubscriptionManager.getOrCreate(Tuple.of(topic, subscription)); } String subscriptionPath = String.format(SUBSCRIPTION_PATH, topicName, subscription); try { return new SubscriptionClient(new ConnectionStringBuilder(connectionString, subscriptionPath), - ReceiveMode.PEEKLOCK); + ReceiveMode.PEEKLOCK); } catch (InterruptedException | ServiceBusException e) { throw new ServiceBusRuntimeException("Failed to create service bus subscription client", e); } } private IMessageSender createTopicClient(String topicName) { - if (resourceManagerProvider != null && StringUtils.hasText(namespace)) { - ServiceBusNamespace serviceBusNamespace = - resourceManagerProvider.getServiceBusNamespaceManager().getOrCreate(namespace); - resourceManagerProvider.getServiceBusTopicManager().getOrCreate(Tuple.of(serviceBusNamespace, topicName)); + if (serviceBusNamespaceManager != null && serviceBusTopicManager != null && StringUtils.hasText(namespace)) { + ServiceBusNamespace serviceBusNamespace = serviceBusNamespaceManager.getOrCreate(namespace); + serviceBusTopicManager.getOrCreate(Tuple.of(serviceBusNamespace, topicName)); } try { From 9662b857cb61b05274b1f413b75f5b14c3455995 Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Sat, 3 Oct 2020 01:06:46 -0400 Subject: [PATCH 22/47] Fixing autoconfiguration for legacy resource management to not kick in and break when attmepting to use 2.0 version of resource management --- .../pom.xml | 102 +++++++++--------- .../AzureContextAutoConfiguration.java | 2 + .../main/resources/META-INF/spring.factories | 3 +- 3 files changed, 56 insertions(+), 51 deletions(-) diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/pom.xml b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/pom.xml index 37f58cf3a8e5..8a772c9f1894 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/pom.xml +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/pom.xml @@ -1,59 +1,61 @@ - - - com.azure - azure-spring-boot-service - 1.0.0 - ../.. - - 4.0.0 - - 1.8 - 1.8 - 2.3.3.RELEASE - + + + com.azure + azure-spring-boot-service + 1.0.0 + ../.. + + 4.0.0 + + 1.8 + 1.8 + 2.3.3.RELEASE + - azure-spring-boot-sample-storage-resource - Spring Cloud Azure Storage Resource Sample - - - com.microsoft.azure - spring-starter-azure-storage - 1.2.8 - + azure-spring-boot-sample-storage-resource + Spring Cloud Azure Storage Resource Sample + + + com.microsoft.azure + spring-cloud-azure-storage + 1.3.0-beta.1 + - - org.springframework.boot - spring-boot-starter - ${spring.boot.version} - + + org.springframework.boot + spring-boot-starter + ${spring.boot.version} + - - org.springframework.boot - spring-boot-starter-web - ${spring.boot.version} - + + org.springframework.boot + spring-boot-starter-web + ${spring.boot.version} + - - junit - junit - 4.12 - test - - - org.springframework.boot - spring-boot-starter-test - ${spring.boot.version} - test - - - org.junit.vintage - junit-vintage-engine - - - + + junit + junit + 4.12 + test + + + org.springframework.boot + spring-boot-starter-test + ${spring.boot.version} + test + + + org.junit.vintage + junit-vintage-engine + + + - + diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java index 8704ccfb2bdd..c95f14fb6024 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java @@ -6,6 +6,7 @@ import java.io.IOException; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -34,6 +35,7 @@ @EnableConfigurationProperties(AzureProperties.class) @ConditionalOnClass(Azure.class) @ConditionalOnProperty(prefix = "spring.cloud.azure", value = { "resource-group" }) +@ConditionalOnExpression("#{ ${spring.cloud.azure.msi-enabled:false} or !'${spring.cloud.azure.credential-file-path:}'.isEmpty() }") public class AzureContextAutoConfiguration { private static final String PROJECT_VERSION = AzureContextAutoConfiguration.class.getPackage() diff --git a/sdk/spring/azure-spring-cloud-context/src/main/resources/META-INF/spring.factories b/sdk/spring/azure-spring-cloud-context/src/main/resources/META-INF/spring.factories index a1ad00a4728f..44b714358c03 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/resources/META-INF/spring.factories +++ b/sdk/spring/azure-spring-cloud-context/src/main/resources/META-INF/spring.factories @@ -1,3 +1,4 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration,\ -com.microsoft.azure.spring.cloud.autoconfigure.context.AzureEnvironmentAutoConfiguration +com.microsoft.azure.spring.cloud.autoconfigure.context.AzureEnvironmentAutoConfiguration,\ +com.microsoft.azure.spring.cloud.autoconfigure.context.AzureResourceManager20AutoConfiguration From ef3f807699f8e7ba1a80be2ca155d0bb750a8263 Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Wed, 14 Oct 2020 20:11:16 -0400 Subject: [PATCH 23/47] Resource demo works with file legacy file credentail' --- .../spring/SpringEnvironmentTokenBuilder.java | 258 ++++++++++-------- .../pom.xml | 155 ++++++----- .../java/com/example/StorageApplication.java | 6 + ...ureResourceManager20AutoConfiguration.java | 13 +- .../context/LegacyTokenCredentialAdapter.java | 51 ++++ .../AzureStorageAutoConfiguration.java | 23 +- 6 files changed, 297 insertions(+), 209 deletions(-) create mode 100644 sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/LegacyTokenCredentialAdapter.java diff --git a/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/SpringEnvironmentTokenBuilder.java b/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/SpringEnvironmentTokenBuilder.java index 08c023e418d9..48702ab16f85 100644 --- a/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/SpringEnvironmentTokenBuilder.java +++ b/sdk/spring/azure-identity-spring-library/src/main/java/com/microsoft/azure/identity/spring/SpringEnvironmentTokenBuilder.java @@ -8,6 +8,8 @@ import org.springframework.core.env.Environment; import com.azure.core.credential.TokenCredential; +import com.azure.identity.ChainedTokenCredential; +import com.azure.identity.ChainedTokenCredentialBuilder; import com.azure.identity.ClientCertificateCredentialBuilder; import com.azure.identity.ClientSecretCredentialBuilder; import com.azure.identity.DefaultAzureCredentialBuilder; @@ -54,121 +56,143 @@ */ public class SpringEnvironmentTokenBuilder { - /** - * Defines the AZURE_CREDENTIAL_PREFIX. - */ - private static final String AZURE_CREDENTIAL_PREFIX = "azure.credential."; - - /** - * Stores the named credentials. - */ - private final HashMap credentials; - - /** - * Stores the name of the credential to be returned. If omitted, the default - * credential will be returned. - */ - private String name = ""; - - /** - * Constructor. - */ - public SpringEnvironmentTokenBuilder() { - credentials = new HashMap<>(); - credentials.put("", new DefaultAzureCredentialBuilder().build()); - } - - /** - * Populate from Environment. - * - * @param environment the environment. - */ - public SpringEnvironmentTokenBuilder fromEnvironment(Environment environment) { - populateNamedCredential(environment, ""); - String credentialNamesKey = AZURE_CREDENTIAL_PREFIX + "names"; - if (environment.containsProperty(credentialNamesKey)) { - String[] credentialNames = environment.getProperty(credentialNamesKey).split(","); - for (int i = 0; i < credentialNames.length; i++) { - populateNamedCredential(environment, credentialNames[i]); - } - } - return this; - } - - /** - * Populate a named credential. - * - * @param environment the environment - * @param name the name. - */ - private void populateNamedCredential(Environment environment, String name) { - String standardizedName = name; - - if (!standardizedName.equals("") && !standardizedName.endsWith(".")) { - standardizedName = standardizedName + "."; - } - - String tenantIdKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "tenantId"; - String clientIdKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "clientId"; - String clientSecretKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "clientSecret"; - - String tenantId = environment.getProperty(tenantIdKey); - String clientId = environment.getProperty(clientIdKey); - String clientSecret = environment.getProperty(clientSecretKey); - - if (tenantId != null && clientId != null && clientSecret != null) { - TokenCredential credential = new ClientSecretCredentialBuilder().tenantId(tenantId).clientId(clientId) - .clientSecret(clientSecret).build(); - credentials.put(name, credential); - return; - } - - String clientCertificateKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "clientCertificate"; - String clientCertificatePath = environment.getProperty(clientCertificateKey); - - if (tenantId != null && clientId != null && clientCertificatePath != null) { - TokenCredential credential = new ClientCertificateCredentialBuilder().tenantId(tenantId).clientId(clientId) - .pemCertificate(clientCertificatePath).build(); - credentials.put(name, credential); - return; - } - - if (!name.equals("")) { - throw new IllegalStateException("Configuration for azure.credential." + name + " is incomplete"); - } - } - - /** - * Sets the builder to return a credential named name - * - * @param name - * @return - */ - public SpringEnvironmentTokenBuilder namedCredential(String name) { - this.name = name; - return this; - } - - /** - * Sets the builder to return the default credential. - */ - public SpringEnvironmentTokenBuilder defaultCredential() { - return namedCredential(""); - } - - /** - * Builds an Azure TokenCredendial. - * - * @throws IllegalArgumentException if attempting to retrieve a named credential - * not defined in the environment. - */ - public TokenCredential build() { - TokenCredential result = credentials.get(name); - if (result == null) { - throw new IllegalArgumentException( - "Attempting to retrieve Azure credential not configured in the environment. (name=" + name + ")"); - } else { - return result; - } - } + /** + * Defines the AZURE_CREDENTIAL_PREFIX. + */ + private static final String AZURE_CREDENTIAL_PREFIX = "azure.credential."; + + /** + * Stores the named credentials. + */ + private final HashMap credentials; + + /** + * Stores the name of the credential to be returned. If omitted, the default + * credential will be returned. + */ + private String name = ""; + + /** + * Constructor. + */ + public SpringEnvironmentTokenBuilder() { + credentials = new HashMap<>(); + credentials.put("", new DefaultAzureCredentialBuilder().build()); + } + + /** + * Populate from Environment. + * + * @param environment the environment. + */ + public SpringEnvironmentTokenBuilder fromEnvironment(Environment environment) { + populateNamedCredential(environment, ""); + String credentialNamesKey = AZURE_CREDENTIAL_PREFIX + "names"; + if (environment.containsProperty(credentialNamesKey)) { + String[] credentialNames = environment.getProperty(credentialNamesKey).split(","); + for (int i = 0; i < credentialNames.length; i++) { + populateNamedCredential(environment, credentialNames[i]); + } + } + return this; + } + + /** + * Sets a credential to override a named credential. If this credential fails to produce a token, + * the original token credential will be used. + * + * @param name + * @param credential + * @return + */ + public SpringEnvironmentTokenBuilder overrideNamedCredential(String name, TokenCredential credential) { + TokenCredential currentCredential = credentials.get(name); + if (currentCredential == null) { + credentials.put(name, credential); + } else { + ChainedTokenCredentialBuilder builder = new ChainedTokenCredentialBuilder(); + builder.addFirst(credential); + builder.addLast(currentCredential); + credentials.put(name, builder.build()); + } + + return this; + } + + /** + * Populate a named credential. + * + * @param environment the environment + * @param name the name. + */ + private void populateNamedCredential(Environment environment, String name) { + String standardizedName = name; + + if (!standardizedName.equals("") && !standardizedName.endsWith(".")) { + standardizedName = standardizedName + "."; + } + + String tenantIdKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "tenantId"; + String clientIdKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "clientId"; + String clientSecretKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "clientSecret"; + + String tenantId = environment.getProperty(tenantIdKey); + String clientId = environment.getProperty(clientIdKey); + String clientSecret = environment.getProperty(clientSecretKey); + + if (tenantId != null && clientId != null && clientSecret != null) { + TokenCredential credential = new ClientSecretCredentialBuilder().tenantId(tenantId).clientId(clientId) + .clientSecret(clientSecret).build(); + credentials.put(name, credential); + return; + } + + String clientCertificateKey = AZURE_CREDENTIAL_PREFIX + standardizedName + "clientCertificate"; + String clientCertificatePath = environment.getProperty(clientCertificateKey); + + if (tenantId != null && clientId != null && clientCertificatePath != null) { + TokenCredential credential = new ClientCertificateCredentialBuilder().tenantId(tenantId).clientId(clientId) + .pemCertificate(clientCertificatePath).build(); + credentials.put(name, credential); + return; + } + + if (!name.equals("")) { + throw new IllegalStateException("Configuration for azure.credential." + name + " is incomplete"); + } + } + + /** + * Sets the builder to return a credential named name + * + * @param name + * @return + */ + public SpringEnvironmentTokenBuilder namedCredential(String name) { + this.name = name; + return this; + } + + /** + * Sets the builder to return the default credential. + */ + public SpringEnvironmentTokenBuilder defaultCredential() { + return namedCredential(""); + } + + /** + * Builds an Azure TokenCredendial. + * + * @throws IllegalArgumentException if attempting to retrieve a named credential + * not defined in the environment. + */ + public TokenCredential build() { + TokenCredential result = credentials.get(name); + if (result == null) { + throw new IllegalArgumentException( + "Attempting to retrieve Azure credential not configured in the environment. (name=" + name + ")"); + } else { + return result; + } + } } diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-cloud-storage-resource-sample/pom.xml b/sdk/spring/azure-spring-boot-samples/azure-spring-cloud-storage-resource-sample/pom.xml index c1b1d5827cf7..3f3274c69636 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-cloud-storage-resource-sample/pom.xml +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-cloud-storage-resource-sample/pom.xml @@ -1,79 +1,88 @@ - - org.springframework.boot - spring-boot-starter-parent - 2.3.3.RELEASE - - 4.0.0 + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + org.springframework.boot + spring-boot-starter-parent + 2.3.3.RELEASE + + 4.0.0 - storage-resource-sample - com.microsoft.azure - 1.2.8-beta.1 - Azure Spring Cloud Storage Sample + storage-resource-sample + com.microsoft.azure + 1.3.0-beta.1 + Azure Spring Cloud Storage Sample - - - - org.springframework.cloud - spring-cloud-dependencies - Hoxton.SR7 - pom - import - - - + jar + + + + org.springframework.cloud + spring-cloud-dependencies + Hoxton.SR7 + pom + import + + + - - - com.microsoft.azure - spring-starter-azure-storage - 1.3.0-beta.1 - - - org.springframework.boot - spring-boot-starter - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-logging - - - junit - junit - test - - - org.mockito - mockito-core - test - - - org.powermock - powermock-api-mockito2 - 2.0.2 - test - - - org.powermock - powermock-module-junit4 - 2.0.2 - test - - - org.hibernate.validator - hibernate-validator - - - org.springframework.boot - spring-boot-starter-test - test - - + + + com.microsoft.azure + spring-starter-azure-storage + 1.3.0-beta.1 + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + junit + junit + test + + + org.mockito + mockito-core + test + + + org.powermock + powermock-api-mockito2 + 2.0.2 + test + + + org.powermock + powermock-module-junit4 + 2.0.2 + test + + + org.hibernate.validator + hibernate-validator + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-cloud-storage-resource-sample/src/main/java/com/example/StorageApplication.java b/sdk/spring/azure-spring-boot-samples/azure-spring-cloud-storage-resource-sample/src/main/java/com/example/StorageApplication.java index 7d79326d75eb..e7c9710799b0 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-cloud-storage-resource-sample/src/main/java/com/example/StorageApplication.java +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-cloud-storage-resource-sample/src/main/java/com/example/StorageApplication.java @@ -3,6 +3,8 @@ package com.example; +import java.nio.file.FileSystems; + import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -13,6 +15,10 @@ public class StorageApplication { public static void main(String[] args) { + System.out.println("Running in " + FileSystems.getDefault().getPath("").toAbsolutePath().toString()); + System.getenv().forEach((key, val) -> { + System.err.println(key + ":" + val); + }); SpringApplication.run(StorageApplication.class, args); } } diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureResourceManager20AutoConfiguration.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureResourceManager20AutoConfiguration.java index ca022c2f4624..3ee610221838 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureResourceManager20AutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureResourceManager20AutoConfiguration.java @@ -1,7 +1,10 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. package com.microsoft.azure.spring.cloud.autoconfigure.context; import java.util.Arrays; +import org.apache.commons.lang3.StringUtils; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -14,6 +17,7 @@ import com.azure.core.management.profile.AzureProfile; import com.azure.resourcemanager.Azure; import com.microsoft.azure.AzureEnvironment; +import com.microsoft.azure.credentials.AzureTokenCredentials; import com.microsoft.azure.identity.spring.SpringEnvironmentTokenBuilder; import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; @@ -37,7 +41,12 @@ public com.azure.resourcemanager.Azure.Authenticated azure20(TokenCredential tok @Bean @ConditionalOnMissingBean - public TokenCredential tokenCredential(Environment environment) { - return new SpringEnvironmentTokenBuilder().fromEnvironment(environment).build(); + public TokenCredential tokenCredential(AzureTokenCredentials credentials, Environment environment, + AzureProperties azureProperties) { + SpringEnvironmentTokenBuilder builder = new SpringEnvironmentTokenBuilder().fromEnvironment(environment); + if (!StringUtils.isBlank(azureProperties.getCredentialFilePath())) { + builder.overrideNamedCredential("", new LegacyTokenCredentialAdapter(credentials)); + } + return builder.build(); } } diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/LegacyTokenCredentialAdapter.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/LegacyTokenCredentialAdapter.java new file mode 100644 index 000000000000..52a15117605e --- /dev/null +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/LegacyTokenCredentialAdapter.java @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.microsoft.azure.spring.cloud.autoconfigure.context; + +import java.io.IOException; +import java.time.OffsetDateTime; + +import com.azure.core.credential.AccessToken; +import com.azure.core.credential.TokenCredential; +import com.azure.core.credential.TokenRequestContext; +import com.azure.core.util.logging.ClientLogger; +import com.azure.identity.implementation.ScopeUtil; +import com.microsoft.azure.credentials.AzureTokenCredentials; + +import reactor.core.publisher.Mono; + +public class LegacyTokenCredentialAdapter implements TokenCredential { + private final ClientLogger logger = new ClientLogger(LegacyTokenCredentialAdapter.class); + + private final AzureTokenCredentials azureTokenCredentials; + + public LegacyTokenCredentialAdapter(AzureTokenCredentials azureTokenCredentials) { + this.azureTokenCredentials = azureTokenCredentials; + } + + @Override + public Mono getToken(TokenRequestContext request) { + String resource = ScopeUtil.scopesToResource(request.getScopes()); + try { + return Mono.just(new AccessToken(azureTokenCredentials.getToken(resource), OffsetDateTime.MAX)); + } catch (IOException e) { + throw new CredentialUnavailableException(e); + } + } + + /** + * Thrown on failure to obtain a credential for the requested resource. + * @author yebronsh + * + */ + public static final class CredentialUnavailableException extends RuntimeException { + /** + * + */ + private static final long serialVersionUID = -5389931452186532039L; + + public CredentialUnavailableException(Throwable cause) { + super(cause); + } + } +} diff --git a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java index 2507d09b428b..9a829d504643 100644 --- a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java @@ -22,7 +22,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.core.env.Environment; import com.azure.core.credential.TokenCredential; import com.azure.core.http.HttpClient; @@ -34,8 +33,7 @@ import com.azure.storage.blob.implementation.util.BuilderHelper; import com.azure.storage.common.policy.RequestRetryOptions; import com.azure.storage.file.share.ShareServiceClientBuilder; -import com.microsoft.azure.identity.spring.SpringEnvironmentTokenBuilder; -import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; +import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureResourceManager20AutoConfiguration; import com.microsoft.azure.spring.cloud.context.core.api.EnvironmentProvider; import com.microsoft.azure.spring.cloud.context.core.impl.StorageAccountManager; import com.microsoft.azure.spring.cloud.context.core.storage.StorageConnectionStringProvider; @@ -49,7 +47,7 @@ * @author Warren Zhu */ @Configuration -@AutoConfigureAfter(AzureContextAutoConfiguration.class) +@AutoConfigureAfter(AzureResourceManager20AutoConfiguration.class) @ConditionalOnClass({ BlobServiceClientBuilder.class, ShareServiceClientBuilder.class }) @ConditionalOnProperty(name = "spring.cloud.azure.storage.account") @EnableConfigurationProperties(AzureStorageProperties.class) @@ -66,13 +64,10 @@ public void collectTelemetry() { TelemetryCollector.getInstance().addService(STORAGE); } - @Autowired - private Environment environment; - @Bean @ConditionalOnMissingBean public BlobServiceClientBuilder blobServiceClientBuilder(AzureStorageProperties storageProperties, - EnvironmentProvider environmentProvider) { + EnvironmentProvider environmentProvider, TokenCredential tokenCredential) { BlobServiceClientBuilder authenticatedClientBuilder = null; @@ -91,10 +86,7 @@ public BlobServiceClientBuilder blobServiceClientBuilder(AzureStorageProperties authenticatedClientBuilder = new BlobServiceClientBuilder().connectionString(connectionString); } else { - TokenCredential defaultIdentityCredential = new SpringEnvironmentTokenBuilder().fromEnvironment(environment) - .defaultCredential().build(); - - authenticatedClientBuilder = new BlobServiceClientBuilder().credential(defaultIdentityCredential) + authenticatedClientBuilder = new BlobServiceClientBuilder().credential(tokenCredential) .endpoint(StorageEndpointStringBuilder.buildBlobEndpoint(storageProperties.getAccount(), environmentProvider.getEnvironment(), storageProperties.isSecureTransfer())); } @@ -106,7 +98,7 @@ public BlobServiceClientBuilder blobServiceClientBuilder(AzureStorageProperties @Bean @ConditionalOnMissingBean public ShareServiceClientBuilder shareServiceClientBuilder(AzureStorageProperties storageProperties, - EnvironmentProvider environmentProvider) { + EnvironmentProvider environmentProvider, TokenCredential tokenCredential) { ShareServiceClientBuilder authenticatedClientBuilder = null; // Use storage credentials where provided, default identity otherwise. @@ -126,13 +118,10 @@ public ShareServiceClientBuilder shareServiceClientBuilder(AzureStoragePropertie authenticatedClientBuilder = new ShareServiceClientBuilder().connectionString(connectionString); } else { - TokenCredential defaultIdentityCredential = new SpringEnvironmentTokenBuilder().fromEnvironment(environment) - .defaultCredential().build(); - String endpoint = StorageEndpointStringBuilder.buildSharesEndpoint(storageProperties.getAccount(), environmentProvider.getEnvironment(), storageProperties.isSecureTransfer()); - HttpPipeline pipeline = BuilderHelper.buildPipeline(null, defaultIdentityCredential, null, endpoint, + HttpPipeline pipeline = BuilderHelper.buildPipeline(null, tokenCredential, null, endpoint, new RequestRetryOptions(), new HttpLogOptions(), HttpClient.createDefault(), Collections.emptyList(), new com.azure.core.util.Configuration(), new ClientLogger(this.getClass())); From 525c5b466ab18ade3ab893e218c17461b7fb7840 Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Wed, 14 Oct 2020 21:12:51 -0400 Subject: [PATCH 24/47] Resource sample works with environment parameters --- .../src/main/java/com/example/StorageApplication.java | 4 ---- .../autoconfigure/context/AzureContextAutoConfiguration.java | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-cloud-storage-resource-sample/src/main/java/com/example/StorageApplication.java b/sdk/spring/azure-spring-boot-samples/azure-spring-cloud-storage-resource-sample/src/main/java/com/example/StorageApplication.java index e7c9710799b0..3315f445aaeb 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-cloud-storage-resource-sample/src/main/java/com/example/StorageApplication.java +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-cloud-storage-resource-sample/src/main/java/com/example/StorageApplication.java @@ -15,10 +15,6 @@ public class StorageApplication { public static void main(String[] args) { - System.out.println("Running in " + FileSystems.getDefault().getPath("").toAbsolutePath().toString()); - System.getenv().forEach((key, val) -> { - System.err.println(key + ":" + val); - }); SpringApplication.run(StorageApplication.class, args); } } diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java index c95f14fb6024..431d5691c7a4 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java @@ -35,7 +35,7 @@ @EnableConfigurationProperties(AzureProperties.class) @ConditionalOnClass(Azure.class) @ConditionalOnProperty(prefix = "spring.cloud.azure", value = { "resource-group" }) -@ConditionalOnExpression("#{ ${spring.cloud.azure.msi-enabled:false} or !'${spring.cloud.azure.credential-file-path:}'.isEmpty() }") +@ConditionalOnExpression("#{ ${spring.cloud.azure.msi-enabled:true} or !'${spring.cloud.azure.credential-file-path:}'.isEmpty() }") public class AzureContextAutoConfiguration { private static final String PROJECT_VERSION = AzureContextAutoConfiguration.class.getPackage() From 7d7adb15320f0c0483682a90f9bd9746bdae06cc Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Wed, 14 Oct 2020 23:04:58 -0400 Subject: [PATCH 25/47] Removing debugging code --- .../src/main/java/com/example/StorageApplication.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-cloud-storage-resource-sample/src/main/java/com/example/StorageApplication.java b/sdk/spring/azure-spring-boot-samples/azure-spring-cloud-storage-resource-sample/src/main/java/com/example/StorageApplication.java index 3315f445aaeb..7d79326d75eb 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-cloud-storage-resource-sample/src/main/java/com/example/StorageApplication.java +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-cloud-storage-resource-sample/src/main/java/com/example/StorageApplication.java @@ -3,8 +3,6 @@ package com.example; -import java.nio.file.FileSystems; - import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; From 80a9e2009714bae2a30e9630bc5ad37a39d76808 Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Thu, 15 Oct 2020 18:39:11 -0400 Subject: [PATCH 26/47] Fixing SPEL expression to omit legacy auto-config when using Spring environment --- .../context/AzureContextAutoConfiguration.java | 2 +- .../AzureResourceManager20AutoConfiguration.java | 15 +++++++++++++-- sdk/spring/azure-spring-cloud-storage/pom.xml | 7 ------- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java index 431d5691c7a4..fbd622ec9b96 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java @@ -35,7 +35,7 @@ @EnableConfigurationProperties(AzureProperties.class) @ConditionalOnClass(Azure.class) @ConditionalOnProperty(prefix = "spring.cloud.azure", value = { "resource-group" }) -@ConditionalOnExpression("#{ ${spring.cloud.azure.msi-enabled:true} or !'${spring.cloud.azure.credential-file-path:}'.isEmpty() }") +@ConditionalOnExpression("#{ ${spring.cloud.azure.msi-enabled:false} or ('${spring.cloud.azure.credential-file-path:}' > '') }") public class AzureContextAutoConfiguration { private static final String PROJECT_VERSION = AzureContextAutoConfiguration.class.getPackage() diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureResourceManager20AutoConfiguration.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureResourceManager20AutoConfiguration.java index 3ee610221838..cf5b91c20de1 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureResourceManager20AutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureResourceManager20AutoConfiguration.java @@ -5,6 +5,10 @@ import java.util.Arrays; import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -27,6 +31,11 @@ @ConditionalOnProperty(prefix = "spring.cloud.azure", value = { "resource-group" }) public class AzureResourceManager20AutoConfiguration { + private static Logger logger = LoggerFactory.getLogger(AzureResourceManager20AutoConfiguration.class); + + @Autowired(required = false) + private AzureTokenCredentials credentials; + @Bean @ConditionalOnMissingBean public com.azure.resourcemanager.Azure.Authenticated azure20(TokenCredential tokenCredential, @@ -41,10 +50,12 @@ public com.azure.resourcemanager.Azure.Authenticated azure20(TokenCredential tok @Bean @ConditionalOnMissingBean - public TokenCredential tokenCredential(AzureTokenCredentials credentials, Environment environment, - AzureProperties azureProperties) { + public TokenCredential tokenCredential(Environment environment, AzureProperties azureProperties) { SpringEnvironmentTokenBuilder builder = new SpringEnvironmentTokenBuilder().fromEnvironment(environment); if (!StringUtils.isBlank(azureProperties.getCredentialFilePath())) { + if (credentials == null) { + logger.error("Legacy azure credentials not initialized though credential-file-path was provided"); + } builder.overrideNamedCredential("", new LegacyTokenCredentialAdapter(credentials)); } return builder.build(); diff --git a/sdk/spring/azure-spring-cloud-storage/pom.xml b/sdk/spring/azure-spring-cloud-storage/pom.xml index cd06fab1f183..cd0278facb37 100644 --- a/sdk/spring/azure-spring-cloud-storage/pom.xml +++ b/sdk/spring/azure-spring-cloud-storage/pom.xml @@ -40,13 +40,6 @@ true - - - com.azure - azure-identity-spring-library - 1.0.0-beta.1 - - com.azure From 9277d718190243b9bf17b35abe63fb8028c0a1f3 Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Fri, 16 Oct 2020 21:15:05 -0400 Subject: [PATCH 27/47] checkstyle appeasement --- .../context/AzureResourceManager20AutoConfiguration.java | 1 - .../cloud/context/core/impl/ServiceBusQueueManager.java | 5 +---- .../cloud/context/core/impl/ServiceBusTopicManager.java | 5 +---- .../core/impl/ServiceBusTopicSubscriptionManager.java | 5 +---- .../cloud/context/core/impl/StorageQueueManager.java | 9 +++------ .../factory/DefaultServiceBusTopicClientFactory.java | 2 -- 6 files changed, 6 insertions(+), 21 deletions(-) diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureResourceManager20AutoConfiguration.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureResourceManager20AutoConfiguration.java index cf5b91c20de1..1406346b894f 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureResourceManager20AutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureResourceManager20AutoConfiguration.java @@ -8,7 +8,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusQueueManager.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusQueueManager.java index c45882470bc9..6e4a45e6fe2e 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusQueueManager.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusQueueManager.java @@ -3,7 +3,6 @@ package com.microsoft.azure.spring.cloud.context.core.impl; -import com.microsoft.azure.management.Azure; import com.microsoft.azure.management.servicebus.Queue; import com.microsoft.azure.management.servicebus.ServiceBusNamespace; import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; @@ -11,11 +10,9 @@ public class ServiceBusQueueManager extends AzureManager> { - private final Azure azure; - public ServiceBusQueueManager(Azure azure, AzureProperties azureProperties) { + public ServiceBusQueueManager(AzureProperties azureProperties) { super(azureProperties); - this.azure = azure; } @Override diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusTopicManager.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusTopicManager.java index 1844da95ca4f..b03cb35ecc95 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusTopicManager.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusTopicManager.java @@ -3,7 +3,6 @@ package com.microsoft.azure.spring.cloud.context.core.impl; -import com.microsoft.azure.management.Azure; import com.microsoft.azure.management.servicebus.ServiceBusNamespace; import com.microsoft.azure.management.servicebus.Topic; import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; @@ -11,10 +10,8 @@ public class ServiceBusTopicManager extends AzureManager> { - private final Azure azure; - public ServiceBusTopicManager(Azure azure, AzureProperties azureProperties) { + public ServiceBusTopicManager(AzureProperties azureProperties) { super(azureProperties); - this.azure = azure; } @Override diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusTopicSubscriptionManager.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusTopicSubscriptionManager.java index 5f7167a3d4a9..7419b2d90c77 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusTopicSubscriptionManager.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/ServiceBusTopicSubscriptionManager.java @@ -3,7 +3,6 @@ package com.microsoft.azure.spring.cloud.context.core.impl; -import com.microsoft.azure.management.Azure; import com.microsoft.azure.management.servicebus.ServiceBusSubscription; import com.microsoft.azure.management.servicebus.Topic; import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; @@ -11,11 +10,9 @@ public class ServiceBusTopicSubscriptionManager extends AzureManager> { - private final Azure azure; - public ServiceBusTopicSubscriptionManager(Azure azure, AzureProperties azureProperties) { + public ServiceBusTopicSubscriptionManager(AzureProperties azureProperties) { super(azureProperties); - this.azure = azure; } @Override diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/StorageQueueManager.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/StorageQueueManager.java index 4e01838d1c11..53551e66e502 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/StorageQueueManager.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/StorageQueueManager.java @@ -3,22 +3,19 @@ package com.microsoft.azure.spring.cloud.context.core.impl; -import com.microsoft.azure.management.Azure; +import java.net.URISyntaxException; + import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; import com.microsoft.azure.spring.cloud.context.core.util.Tuple; import com.microsoft.azure.storage.CloudStorageAccount; import com.microsoft.azure.storage.StorageException; import com.microsoft.azure.storage.queue.CloudQueue; import com.microsoft.azure.storage.queue.CloudQueueClient; -import java.net.URISyntaxException; public class StorageQueueManager extends AzureManager> { - private final Azure azure; - - public StorageQueueManager(Azure azure, AzureProperties azureProperties) { + public StorageQueueManager(AzureProperties azureProperties) { super(azureProperties); - this.azure = azure; } @Override diff --git a/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/DefaultServiceBusTopicClientFactory.java b/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/DefaultServiceBusTopicClientFactory.java index 98141bdadeb7..a9ad13b8cfd0 100644 --- a/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/DefaultServiceBusTopicClientFactory.java +++ b/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/DefaultServiceBusTopicClientFactory.java @@ -12,8 +12,6 @@ import com.microsoft.azure.servicebus.TopicClient; import com.microsoft.azure.servicebus.primitives.ConnectionStringBuilder; import com.microsoft.azure.servicebus.primitives.ServiceBusException; -import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusNamespaceManager; -import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusTopicSubscriptionManager; import com.microsoft.azure.spring.cloud.context.core.util.Memoizer; import com.microsoft.azure.spring.cloud.context.core.util.Tuple; import com.microsoft.azure.spring.integration.servicebus.ServiceBusRuntimeException; From e4608d5e02ee8a9235a9bcf51d4efc08b6c42345 Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Mon, 19 Oct 2020 19:30:29 -0400 Subject: [PATCH 28/47] Checktyle appeasement, version fixing --- .../pom.xml | 2 +- ...AzureServiceBusQueueAutoConfiguration.java | 4 ++-- .../config/EventHubBinderConfiguration.java | 24 +++++++++---------- sdk/spring/azure-spring-cloud-storage/pom.xml | 2 +- .../AbstractServiceBusSenderFactory.java | 8 +++++++ .../DefaultServiceBusQueueClientFactory.java | 7 +++--- 6 files changed, 27 insertions(+), 20 deletions(-) diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-servicebus/pom.xml b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-servicebus/pom.xml index 8ea3a74da065..39508b0cb9bc 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-servicebus/pom.xml +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-servicebus/pom.xml @@ -31,7 +31,7 @@ com.azure azure-messaging-servicebus - 7.0.0-beta.7 + 7.0.0-beta.6 diff --git a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusQueueAutoConfiguration.java b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusQueueAutoConfiguration.java index b99b1b6ee7bc..9f0005f5af36 100644 --- a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusQueueAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusQueueAutoConfiguration.java @@ -86,7 +86,7 @@ public ServiceBusNamespaceManager serviceBusNamespaceManager(Azure azure, AzureP @Bean @ConditionalOnMissingBean - public ServiceBusQueueManager serviceBusQueueManager(Azure azure, AzureProperties azureProperties) { - return new ServiceBusQueueManager(azure, azureProperties); + public ServiceBusQueueManager serviceBusQueueManager(AzureProperties azureProperties) { + return new ServiceBusQueueManager(azureProperties); } } diff --git a/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/config/EventHubBinderConfiguration.java b/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/config/EventHubBinderConfiguration.java index 8644ee6e5601..5926ddd76ab9 100644 --- a/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/config/EventHubBinderConfiguration.java +++ b/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/config/EventHubBinderConfiguration.java @@ -32,23 +32,21 @@ */ @Configuration @ConditionalOnMissingBean(Binder.class) -@Import({AzureEventHubAutoConfiguration.class, AzureEnvironmentAutoConfiguration.class}) -@EnableConfigurationProperties({AzureEventHubProperties.class, EventHubExtendedBindingProperties.class}) +@Import({ AzureEventHubAutoConfiguration.class, AzureEnvironmentAutoConfiguration.class }) +@EnableConfigurationProperties({ AzureEventHubProperties.class, EventHubExtendedBindingProperties.class }) public class EventHubBinderConfiguration { private static final String EVENT_HUB_BINDER = "EventHubBinder"; private static final String NAMESPACE = "Namespace"; - @Autowired(required = false) private EventHubNamespaceManager eventHubNamespaceManager; - - @Autowired(required=false) + + @Autowired(required = false) private EventHubManager eventHubManager; - - @Autowired(required=false) + + @Autowired(required = false) private EventHubConsumerGroupManager eventHubConsumerGroupManager; - @PostConstruct public void collectTelemetry() { @@ -58,9 +56,9 @@ public void collectTelemetry() { @Bean @ConditionalOnMissingBean public EventHubChannelProvisioner eventHubChannelProvisioner(AzureEventHubProperties eventHubProperties) { - if (eventHubNamespaceManager != null && eventHubManager != null && eventHubConsumerGroupManager!=null) { - return new EventHubChannelResourceManagerProvisioner(eventHubNamespaceManager, eventHubManager, eventHubConsumerGroupManager, - eventHubProperties.getNamespace()); + if (eventHubNamespaceManager != null && eventHubManager != null && eventHubConsumerGroupManager != null) { + return new EventHubChannelResourceManagerProvisioner(eventHubNamespaceManager, eventHubManager, + eventHubConsumerGroupManager, eventHubProperties.getNamespace()); } else { TelemetryCollector.getInstance().addProperty(EVENT_HUB_BINDER, NAMESPACE, EventHubUtils.getNamespace(eventHubProperties.getConnectionString())); @@ -73,8 +71,8 @@ public EventHubChannelProvisioner eventHubChannelProvisioner(AzureEventHubProper @ConditionalOnMissingBean public EventHubMessageChannelBinder eventHubBinder(EventHubChannelProvisioner eventHubChannelProvisioner, EventHubOperation eventHubOperation, EventHubExtendedBindingProperties bindingProperties) { - EventHubMessageChannelBinder binder = - new EventHubMessageChannelBinder(null, eventHubChannelProvisioner, eventHubOperation); + EventHubMessageChannelBinder binder = new EventHubMessageChannelBinder(null, eventHubChannelProvisioner, + eventHubOperation); binder.setBindingProperties(bindingProperties); return binder; } diff --git a/sdk/spring/azure-spring-cloud-storage/pom.xml b/sdk/spring/azure-spring-cloud-storage/pom.xml index cd0278facb37..1d29bfc26d64 100644 --- a/sdk/spring/azure-spring-cloud-storage/pom.xml +++ b/sdk/spring/azure-spring-cloud-storage/pom.xml @@ -51,7 +51,7 @@ com.azure.resourcemanager azure-resourcemanager-storage - 2.0.0-beta.5 + 2.0.0 diff --git a/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/AbstractServiceBusSenderFactory.java b/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/AbstractServiceBusSenderFactory.java index 781e4c1f5e22..d4695f0da7ce 100644 --- a/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/AbstractServiceBusSenderFactory.java +++ b/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/AbstractServiceBusSenderFactory.java @@ -3,6 +3,8 @@ package com.microsoft.azure.spring.integration.servicebus.factory; +import javax.annotation.Nullable; + import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusNamespaceManager; import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusQueueManager; import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusTopicManager; @@ -15,10 +17,16 @@ */ abstract class AbstractServiceBusSenderFactory implements ServiceBusSenderFactory { protected final String connectionString; + + @Nullable protected ServiceBusNamespaceManager serviceBusNamespaceManager; + @Nullable protected ServiceBusQueueManager serviceBusQueueManager; + @Nullable protected ServiceBusTopicManager serviceBusTopicManager; + @Nullable protected ServiceBusTopicSubscriptionManager serviceBusTopicSubscriptionManager; + @Nullable protected String namespace; AbstractServiceBusSenderFactory(String connectionString) { diff --git a/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/DefaultServiceBusQueueClientFactory.java b/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/DefaultServiceBusQueueClientFactory.java index 9c121d92005e..6acfc10f254a 100644 --- a/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/DefaultServiceBusQueueClientFactory.java +++ b/sdk/spring/azure-spring-integration-servicebus/src/main/java/com/microsoft/azure/spring/integration/servicebus/factory/DefaultServiceBusQueueClientFactory.java @@ -3,6 +3,10 @@ package com.microsoft.azure.spring.integration.servicebus.factory; +import java.util.function.Function; + +import org.springframework.util.StringUtils; + import com.microsoft.azure.management.servicebus.ServiceBusNamespace; import com.microsoft.azure.servicebus.IMessageSender; import com.microsoft.azure.servicebus.IQueueClient; @@ -13,9 +17,6 @@ import com.microsoft.azure.spring.cloud.context.core.util.Memoizer; import com.microsoft.azure.spring.cloud.context.core.util.Tuple; import com.microsoft.azure.spring.integration.servicebus.ServiceBusRuntimeException; -import org.springframework.util.StringUtils; - -import java.util.function.Function; /** * Default implementation of {@link ServiceBusQueueClientFactory}. From 42d5e502207c2dc1a32bf8a38049294180d920b2 Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Tue, 20 Oct 2020 19:59:32 -0400 Subject: [PATCH 29/47] Adding mock token credentail to Actuator test config to ward off unearned failure --- .../BlobStorageHealthIndicatorTest.java | 52 ++++++++++++------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/sdk/spring/azure-spring-cloud-storage/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/actuator/BlobStorageHealthIndicatorTest.java b/sdk/spring/azure-spring-cloud-storage/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/actuator/BlobStorageHealthIndicatorTest.java index 163c7a8af327..6fae48f6d720 100644 --- a/sdk/spring/azure-spring-cloud-storage/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/actuator/BlobStorageHealthIndicatorTest.java +++ b/sdk/spring/azure-spring-cloud-storage/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/actuator/BlobStorageHealthIndicatorTest.java @@ -16,12 +16,14 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import com.azure.core.credential.TokenCredential; import com.azure.storage.blob.BlobServiceAsyncClient; import com.azure.storage.blob.BlobServiceClientBuilder; import com.azure.storage.blob.models.AccountKind; import com.azure.storage.blob.models.SkuName; import com.azure.storage.blob.models.StorageAccountInfo; import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureEnvironmentAutoConfiguration; +import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureResourceManager20AutoConfiguration; import com.microsoft.azure.spring.cloud.autoconfigure.storage.AzureStorageAutoConfiguration; import reactor.core.publisher.Mono; @@ -31,10 +33,9 @@ public class BlobStorageHealthIndicatorTest { @Test(expected = IllegalStateException.class) public void testWithNoStorageConfiguration() { - ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withAllowBeanDefinitionOverriding(true) - .withBean(BlobServiceClientBuilder.class) - .withConfiguration(AutoConfigurations.of(AzureStorageActuatorAutoConfiguration.class)); + ApplicationContextRunner contextRunner = new ApplicationContextRunner().withAllowBeanDefinitionOverriding(true) + .withBean(BlobServiceClientBuilder.class) + .withConfiguration(AutoConfigurations.of(AzureStorageActuatorAutoConfiguration.class)); contextRunner.run(context -> { context.getBean(BlobStorageHealthIndicator.class).getHealth(true); @@ -43,15 +44,16 @@ public void testWithNoStorageConfiguration() { @Test public void testWithStorageConfigurationWithConnectionUp() { - ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withAllowBeanDefinitionOverriding(true) - .withConfiguration(AutoConfigurations.of(AzureEnvironmentAutoConfiguration.class, - AzureStorageAutoConfiguration.class, AzureStorageActuatorAutoConfiguration.class)) - .withUserConfiguration(TestConfigurationConnectionUp.class) - .withPropertyValues("spring.cloud.azure.storage.account=acc1") - .withBean(BlobStorageHealthIndicator.class); + ApplicationContextRunner contextRunner = new ApplicationContextRunner().withAllowBeanDefinitionOverriding(true) + .withConfiguration(AutoConfigurations.of(AzureEnvironmentAutoConfiguration.class, MockTokenCredentialConfiguration.class, + AzureStorageAutoConfiguration.class, AzureStorageActuatorAutoConfiguration.class)) + .withUserConfiguration(TestConfigurationConnectionUp.class) + .withPropertyValues("spring.cloud.azure.storage.account=acc1") + .withPropertyValues("spring.cloud.azure.resource-group=myrg") + .withBean(BlobStorageHealthIndicator.class); contextRunner.run(context -> { - Health health = context.getBean("blobStorageHealthIndicator", BlobStorageHealthIndicator.class).getHealth(true); + Health health = context.getBean("blobStorageHealthIndicator", BlobStorageHealthIndicator.class) + .getHealth(true); Assert.assertEquals(Status.UP, health.getStatus()); Assert.assertEquals(MOCK_URL, health.getDetails().get(AzureStorageActuatorConstants.URL_FIELD)); }); @@ -59,15 +61,16 @@ public void testWithStorageConfigurationWithConnectionUp() { @Test public void testWithStorageConfigurationWithConnectionDown() { - ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withAllowBeanDefinitionOverriding(true) - .withConfiguration(AutoConfigurations.of(AzureEnvironmentAutoConfiguration.class, - AzureStorageAutoConfiguration.class, AzureStorageActuatorAutoConfiguration.class)) - .withUserConfiguration(TestConfigurationConnectionDown.class) - .withPropertyValues("spring.cloud.azure.storage.account=acc1") - .withBean(BlobStorageHealthIndicator.class); + ApplicationContextRunner contextRunner = new ApplicationContextRunner().withAllowBeanDefinitionOverriding(true) + .withConfiguration(AutoConfigurations.of(AzureEnvironmentAutoConfiguration.class, + MockTokenCredentialConfiguration.class, AzureResourceManager20AutoConfiguration.class, + AzureStorageAutoConfiguration.class, AzureStorageActuatorAutoConfiguration.class)) + .withUserConfiguration(TestConfigurationConnectionDown.class) + .withPropertyValues("spring.cloud.azure.storage.account=acc1") + .withBean(BlobStorageHealthIndicator.class); contextRunner.run(context -> { - Health health = context.getBean("blobStorageHealthIndicator", BlobStorageHealthIndicator.class).getHealth(true); + Health health = context.getBean("blobStorageHealthIndicator", BlobStorageHealthIndicator.class) + .getHealth(true); Assert.assertEquals(Status.DOWN, health.getStatus()); Assert.assertEquals(MOCK_URL, health.getDetails().get(AzureStorageActuatorConstants.URL_FIELD)); }); @@ -104,4 +107,13 @@ BlobServiceClientBuilder blobServiceClientBuilder() { return mockClientBuilder; } } + + @Configuration + static class MockTokenCredentialConfiguration { + + @Bean + TokenCredential tokenCredential() { + return mock(TokenCredential.class); + } + } } From 29beabc0e455b429776f2d8f78a592e27495339e Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Tue, 20 Oct 2020 21:01:16 -0400 Subject: [PATCH 30/47] Adding mock token credentail to Actuator test config to ward off unearned failure --- .../FileStorageHealthIndicatorTest.java | 47 +++++++++++-------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/sdk/spring/azure-spring-cloud-storage/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/actuator/FileStorageHealthIndicatorTest.java b/sdk/spring/azure-spring-cloud-storage/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/actuator/FileStorageHealthIndicatorTest.java index 6e9789169f1c..bc65cff9879f 100644 --- a/sdk/spring/azure-spring-cloud-storage/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/actuator/FileStorageHealthIndicatorTest.java +++ b/sdk/spring/azure-spring-cloud-storage/src/test/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/actuator/FileStorageHealthIndicatorTest.java @@ -17,6 +17,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import com.azure.core.credential.TokenCredential; import com.azure.core.http.rest.Response; import com.azure.storage.file.share.ShareServiceAsyncClient; import com.azure.storage.file.share.ShareServiceClientBuilder; @@ -31,10 +32,9 @@ public class FileStorageHealthIndicatorTest { @Test(expected = IllegalStateException.class) public void testWithNoStorageConfiguration() { - ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withAllowBeanDefinitionOverriding(true) - .withBean(ShareServiceClientBuilder.class) - .withConfiguration(AutoConfigurations.of(AzureStorageActuatorAutoConfiguration.class)); + ApplicationContextRunner contextRunner = new ApplicationContextRunner().withAllowBeanDefinitionOverriding(true) + .withBean(ShareServiceClientBuilder.class) + .withConfiguration(AutoConfigurations.of(AzureStorageActuatorAutoConfiguration.class)); contextRunner.withBean(FileStorageHealthIndicator.class).run(context -> { context.getBean(FileStorageHealthIndicator.class).getHealth(true); @@ -43,13 +43,13 @@ public void testWithNoStorageConfiguration() { @Test public void testWithStorageConfigurationWithConnectionUp() { - ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withAllowBeanDefinitionOverriding(true) - .withConfiguration(AutoConfigurations.of(AzureEnvironmentAutoConfiguration.class, - AzureStorageAutoConfiguration.class, AzureStorageActuatorAutoConfiguration.class)) - .withUserConfiguration(TestConfigurationConnectionUp.class) - .withPropertyValues("spring.cloud.azure.storage.account=acc1") - .withBean(FileStorageHealthIndicator.class); + ApplicationContextRunner contextRunner = new ApplicationContextRunner().withAllowBeanDefinitionOverriding(true) + .withConfiguration(AutoConfigurations.of(AzureEnvironmentAutoConfiguration.class, + MockTokenCredentialConfiguration.class, AzureStorageAutoConfiguration.class, + AzureStorageActuatorAutoConfiguration.class)) + .withUserConfiguration(TestConfigurationConnectionUp.class) + .withPropertyValues("spring.cloud.azure.storage.account=acc1") + .withBean(FileStorageHealthIndicator.class); contextRunner.run(context -> { Health health = context.getBean(FileStorageHealthIndicator.class).getHealth(true); Assert.assertEquals(Status.UP, health.getStatus()); @@ -59,13 +59,13 @@ public void testWithStorageConfigurationWithConnectionUp() { @Test public void testWithStorageConfigurationWithConnectionDown() { - ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withAllowBeanDefinitionOverriding(true) - .withConfiguration(AutoConfigurations.of(AzureEnvironmentAutoConfiguration.class, - AzureStorageAutoConfiguration.class, AzureStorageActuatorAutoConfiguration.class)) - .withUserConfiguration(TestConfigurationConnectionDown.class) - .withPropertyValues("spring.cloud.azure.storage.account=acc1") - .withBean(BlobStorageHealthIndicator.class); + ApplicationContextRunner contextRunner = new ApplicationContextRunner().withAllowBeanDefinitionOverriding(true) + .withConfiguration(AutoConfigurations.of(AzureEnvironmentAutoConfiguration.class, + MockTokenCredentialConfiguration.class, AzureStorageAutoConfiguration.class, + AzureStorageActuatorAutoConfiguration.class)) + .withUserConfiguration(TestConfigurationConnectionDown.class) + .withPropertyValues("spring.cloud.azure.storage.account=acc1") + .withBean(BlobStorageHealthIndicator.class); contextRunner.run(context -> { Health health = context.getBean(FileStorageHealthIndicator.class).getHealth(true); Assert.assertEquals(Status.DOWN, health.getStatus()); @@ -80,8 +80,8 @@ static class TestConfigurationConnectionUp { ShareServiceClientBuilder shareServiceClientBuilder() { ShareServiceClientBuilder mockClientBuilder = mock(ShareServiceClientBuilder.class); ShareServiceAsyncClient mockAsyncClient = mock(ShareServiceAsyncClient.class); - @SuppressWarnings("unchecked") + Response mockResponse = (Response) Mockito .mock(Response.class); @@ -109,4 +109,13 @@ ShareServiceClientBuilder shareServiceClientBuilder() { } } + + @Configuration + static class MockTokenCredentialConfiguration { + + @Bean + TokenCredential tokenCredential() { + return mock(TokenCredential.class); + } + } } From 969353e4777ec463908b6d58d6f085eda367e7ed Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Thu, 22 Oct 2020 14:02:50 -0400 Subject: [PATCH 31/47] Removing topic manager dependency from queue autoconfig --- .../servicebus/AzureServiceBusQueueAutoConfiguration.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusQueueAutoConfiguration.java b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusQueueAutoConfiguration.java index 9f0005f5af36..4f3fe094553f 100644 --- a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusQueueAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusQueueAutoConfiguration.java @@ -45,8 +45,6 @@ public class AzureServiceBusQueueAutoConfiguration { @Autowired(required = false) private ServiceBusQueueManager serviceBusQueueManager; - @Autowired(required = false) - private ServiceBusTopicManager serviceBusTopicManager; @PostConstruct public void collectTelemetry() { @@ -60,7 +58,7 @@ public ServiceBusQueueClientFactory queueClientFactory(AzureServiceBusProperties DefaultServiceBusQueueClientFactory clientFactory = new DefaultServiceBusQueueClientFactory( serviceBusProperties.getConnectionString()); - if (serviceBusNamespaceManager != null && serviceBusQueueManager != null && serviceBusTopicManager != null) { + if (serviceBusNamespaceManager != null && serviceBusQueueManager != null) { clientFactory.setServiceBusNamespaceManager(serviceBusNamespaceManager); clientFactory.setServiceBusQueueManager(serviceBusQueueManager); clientFactory.setNamespace(serviceBusProperties.getNamespace()); From bbc811e2092d181a61a98087a709a4227187cf31 Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Thu, 22 Oct 2020 17:34:41 -0400 Subject: [PATCH 32/47] Fixing autoconfig dependencies for Topic binders --- ...AzureServiceBusTopicAutoConfiguration.java | 38 +++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusTopicAutoConfiguration.java b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusTopicAutoConfiguration.java index 90aaa862a0db..6fad1de5b643 100644 --- a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusTopicAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusTopicAutoConfiguration.java @@ -13,9 +13,12 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import com.microsoft.azure.management.Azure; import com.microsoft.azure.servicebus.TopicClient; import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; +import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusNamespaceManager; +import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusTopicManager; import com.microsoft.azure.spring.cloud.context.core.impl.ServiceBusTopicSubscriptionManager; import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; import com.microsoft.azure.spring.integration.servicebus.factory.DefaultServiceBusTopicClientFactory; @@ -36,13 +39,15 @@ public class AzureServiceBusTopicAutoConfiguration { private static final String SERVICE_BUS_TOPIC = "ServiceBusTopic"; private static final String NAMESPACE = "Namespace"; - - @Autowired(required = false) - private ServiceBusTopicSubscriptionManager serviceBusTopicSubscriptionManager; - @Autowired(required = false) private ServiceBusNamespaceManager serviceBusNamespaceManager; + @Autowired(required = false) + private ServiceBusTopicManager serviceBusTopicManager; + + @Autowired(required = false) + private ServiceBusTopicSubscriptionManager serviceBusTopicSubscriptionManager; + @PostConstruct public void collectTelemetry() { TelemetryCollector.getInstance().addService(SERVICE_BUS_TOPIC); @@ -52,24 +57,43 @@ public void collectTelemetry() { @ConditionalOnMissingBean public ServiceBusTopicClientFactory topicClientFactory(AzureServiceBusProperties serviceBusProperties) { String connectionString = serviceBusProperties.getConnectionString(); - DefaultServiceBusTopicClientFactory clientFactory = - new DefaultServiceBusTopicClientFactory(serviceBusProperties.getConnectionString()); + DefaultServiceBusTopicClientFactory clientFactory = new DefaultServiceBusTopicClientFactory( + serviceBusProperties.getConnectionString()); if (serviceBusTopicSubscriptionManager != null && serviceBusNamespaceManager != null) { clientFactory.setNamespace(serviceBusProperties.getNamespace()); clientFactory.setServiceBusNamespaceManager(serviceBusNamespaceManager); + clientFactory.setServiceBusTopicManager(serviceBusTopicManager); clientFactory.setServiceBusTopicSubscriptionManager(serviceBusTopicSubscriptionManager); } else { TelemetryCollector.getInstance().addProperty(SERVICE_BUS_TOPIC, NAMESPACE, - ServiceBusUtils.getNamespace(connectionString)); + ServiceBusUtils.getNamespace(connectionString)); } return clientFactory; } + @Bean + @ConditionalOnMissingBean + public ServiceBusNamespaceManager serviceBusNamespaceManager(Azure azure, AzureProperties azureProperties) { + return new ServiceBusNamespaceManager(azure, azureProperties); + } + + @Bean + @ConditionalOnMissingBean + public ServiceBusTopicSubscriptionManager serviceBusTopicSubscriptionManager(AzureProperties azureProperties) { + return new ServiceBusTopicSubscriptionManager(azureProperties); + } + @Bean @ConditionalOnMissingBean public ServiceBusTopicOperation topicOperation(ServiceBusTopicClientFactory factory) { return new ServiceBusTopicTemplate(factory); } + + @Bean + @ConditionalOnMissingBean + public ServiceBusTopicManager serviceBusTopicManager(AzureProperties azureProperties) { + return new ServiceBusTopicManager(azureProperties); + } } From 01b13786d1b5ad06b0ed1133bc8cb47e89749839 Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Tue, 27 Oct 2020 23:19:38 -0400 Subject: [PATCH 33/47] Fixing startup failure when namespace is provided instead of connection string. --- .../stream/binder/config/EventHubBinderConfiguration.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/config/EventHubBinderConfiguration.java b/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/config/EventHubBinderConfiguration.java index 5926ddd76ab9..35bc80a9c3d2 100644 --- a/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/config/EventHubBinderConfiguration.java +++ b/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/config/EventHubBinderConfiguration.java @@ -60,8 +60,9 @@ public EventHubChannelProvisioner eventHubChannelProvisioner(AzureEventHubProper return new EventHubChannelResourceManagerProvisioner(eventHubNamespaceManager, eventHubManager, eventHubConsumerGroupManager, eventHubProperties.getNamespace()); } else { - TelemetryCollector.getInstance().addProperty(EVENT_HUB_BINDER, NAMESPACE, - EventHubUtils.getNamespace(eventHubProperties.getConnectionString())); + String namespace = eventHubProperties.getNamespace() != null ? eventHubProperties.getNamespace() + : EventHubUtils.getNamespace(eventHubProperties.getConnectionString()); + TelemetryCollector.getInstance().addProperty(EVENT_HUB_BINDER, NAMESPACE, namespace); } return new EventHubChannelProvisioner(); From cc74b408901467055c0afc8567fb747b0c014edc Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Tue, 27 Oct 2020 23:22:12 -0400 Subject: [PATCH 34/47] Updating to incorporate upstream library signature changes --- .../pom.xml | 174 +++++++++--------- .../AzureEventHubAutoConfiguration.java | 12 +- sdk/spring/azure-spring-cloud-context/pom.xml | 9 +- ...ureResourceManager20AutoConfiguration.java | 14 +- .../context/core/api/EnvironmentProvider.java | 2 +- .../core/impl/StorageAccountManager.java | 18 +- .../AzureStorageAutoConfiguration.java | 8 + 7 files changed, 130 insertions(+), 107 deletions(-) diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-cloud-eventhubs-binder-sample/pom.xml b/sdk/spring/azure-spring-boot-samples/azure-spring-cloud-eventhubs-binder-sample/pom.xml index cd15d4bddd4b..d694ac193b76 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-cloud-eventhubs-binder-sample/pom.xml +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-cloud-eventhubs-binder-sample/pom.xml @@ -1,90 +1,98 @@ - - org.springframework.boot - spring-boot-starter-parent - 2.3.3.RELEASE - - 4.0.0 + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + org.springframework.boot + spring-boot-starter-parent + 2.3.3.RELEASE + + 4.0.0 - eventhubs-binder-sample - com.microsoft.azure - 1.2.8-beta.1 - Azure Spring Cloud Event Hub Binder Sample + eventhubs-binder-sample + com.microsoft.azure + 1.2.8-beta.1 + Azure Spring Cloud Event Hub Binder Sample - - - - org.springframework.cloud - spring-cloud-dependencies - Hoxton.SR7 - pom - import - - - + + + + org.springframework.cloud + spring-cloud-dependencies + Hoxton.SR7 + pom + import + + + - - - org.springframework.boot - spring-boot-starter-web - - - com.microsoft.azure - spring-cloud-azure-eventhubs-stream-binder - 1.3.0-beta.1 - - - org.springframework.boot - spring-boot-starter-logging - - - junit - junit - test - - - org.mockito - mockito-core - test - - - org.powermock - powermock-api-mockito2 - 2.0.2 - test - - - org.powermock - powermock-module-junit4 - 2.0.2 - test - - - org.hibernate.validator - hibernate-validator - - - org.springframework.boot - spring-boot-starter-test - test - - + + + org.springframework.boot + spring-boot-starter-web + + + com.microsoft.azure + spring-cloud-azure-eventhubs-stream-binder + 1.3.0-beta.1 + + + + + com.microsoft.azure + spring-cloud-azure-storage + 1.3.0-beta.1 + - - - - org.springframework.boot - spring-boot-maven-plugin - - - - com.microsoft.azure - azure-webapp-maven-plugin - 1.10.0 - - - + + org.springframework.boot + spring-boot-starter-logging + + + junit + junit + test + + + org.mockito + mockito-core + test + + + org.powermock + powermock-api-mockito2 + 2.0.2 + test + + + org.powermock + powermock-module-junit4 + 2.0.2 + test + + + org.hibernate.validator + hibernate-validator + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + com.microsoft.azure + azure-webapp-maven-plugin + 1.10.0 + + + diff --git a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/eventhub/AzureEventHubAutoConfiguration.java b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/eventhub/AzureEventHubAutoConfiguration.java index 5c85443c5ad8..4f313b56320b 100644 --- a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/eventhub/AzureEventHubAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/eventhub/AzureEventHubAutoConfiguration.java @@ -17,9 +17,10 @@ import com.azure.messaging.eventhubs.EventHubConsumerAsyncClient; import com.azure.resourcemanager.storage.models.StorageAccount; +import com.microsoft.azure.management.Azure; import com.microsoft.azure.management.eventhub.EventHubNamespace; -import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration; import com.microsoft.azure.spring.cloud.context.core.api.EnvironmentProvider; +import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; import com.microsoft.azure.spring.cloud.context.core.impl.EventHubNamespaceManager; import com.microsoft.azure.spring.cloud.context.core.impl.StorageAccountManager; import com.microsoft.azure.spring.cloud.context.core.storage.StorageConnectionStringProvider; @@ -36,7 +37,7 @@ * @author Warren Zhu */ @Configuration -@AutoConfigureAfter(AzureContextAutoConfiguration.class) +@AutoConfigureAfter(name = {"com.microsoft.azure.spring.cloud.autoconfigure.storage.AzureStorageAutoConfiguration", "com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration"}) @ConditionalOnClass(EventHubConsumerAsyncClient.class) @ConditionalOnProperty(value = "spring.cloud.azure.eventhub.enabled", matchIfMissing = true) @EnableConfigurationProperties(AzureEventHubProperties.class) @@ -100,4 +101,11 @@ public EventHubClientFactory clientFactory(EventHubConnectionStringProvider conn return new DefaultEventHubClientFactory(connectionStringProvider, checkpointConnectionString, eventHubProperties.getCheckpointContainer()); } + + @Bean + @ConditionalOnMissingBean + public EventHubNamespaceManager eventHubNamespaceManager(Azure azure, AzureProperties azureProperties) { + return new EventHubNamespaceManager(azure, azureProperties); + } + } diff --git a/sdk/spring/azure-spring-cloud-context/pom.xml b/sdk/spring/azure-spring-cloud-context/pom.xml index f1f82523b855..a44ddb58a5f0 100644 --- a/sdk/spring/azure-spring-cloud-context/pom.xml +++ b/sdk/spring/azure-spring-cloud-context/pom.xml @@ -62,16 +62,17 @@ + - com.azure.resourcemanager - azure-resourcemanager - 2.0.0-beta.4 + com.azure.resourcemanager + azure-resourcemanager + 2.0.0 com.azure.resourcemanager azure-resourcemanager-storage - 2.0.0-beta.4 + 2.0.0 diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureResourceManager20AutoConfiguration.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureResourceManager20AutoConfiguration.java index 1406346b894f..4af1665d166e 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureResourceManager20AutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/context/AzureResourceManager20AutoConfiguration.java @@ -2,8 +2,6 @@ // Licensed under the MIT License. package com.microsoft.azure.spring.cloud.autoconfigure.context; -import java.util.Arrays; - import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -18,7 +16,7 @@ import com.azure.core.credential.TokenCredential; import com.azure.core.management.profile.AzureProfile; -import com.azure.resourcemanager.Azure; +import com.azure.resourcemanager.AzureResourceManager; import com.microsoft.azure.AzureEnvironment; import com.microsoft.azure.credentials.AzureTokenCredentials; import com.microsoft.azure.identity.spring.SpringEnvironmentTokenBuilder; @@ -26,7 +24,7 @@ @Configuration @EnableConfigurationProperties(AzureProperties.class) -@ConditionalOnClass(Azure.class) +@ConditionalOnClass(AzureResourceManager.class) @ConditionalOnProperty(prefix = "spring.cloud.azure", value = { "resource-group" }) public class AzureResourceManager20AutoConfiguration { @@ -37,14 +35,14 @@ public class AzureResourceManager20AutoConfiguration { @Bean @ConditionalOnMissingBean - public com.azure.resourcemanager.Azure.Authenticated azure20(TokenCredential tokenCredential, + public AzureResourceManager.Authenticated azure20(TokenCredential tokenCredential, AzureProperties azureProperties) { AzureEnvironment legacyEnvironment = azureProperties.getEnvironment(); - com.azure.core.management.AzureEnvironment azureEnvironment = Arrays - .stream(com.azure.core.management.AzureEnvironment.knownEnvironments()) + com.azure.core.management.AzureEnvironment azureEnvironment = + com.azure.core.management.AzureEnvironment.knownEnvironments().stream() .filter(env -> env.getManagementEndpoint().equals(legacyEnvironment.managementEndpoint())).findFirst() .get(); - return com.azure.resourcemanager.Azure.authenticate(tokenCredential, new AzureProfile(azureEnvironment)); + return AzureResourceManager.authenticate(tokenCredential, new AzureProfile(azureEnvironment)); } @Bean diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/api/EnvironmentProvider.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/api/EnvironmentProvider.java index ac0a775b2260..7c21ebc4d739 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/api/EnvironmentProvider.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/api/EnvironmentProvider.java @@ -21,7 +21,7 @@ public interface EnvironmentProvider { * com.azure.core.management SDK. */ default com.azure.core.management.AzureEnvironment getCoreEnvironment() { - return Arrays.stream(com.azure.core.management.AzureEnvironment.knownEnvironments()) + return com.azure.core.management.AzureEnvironment.knownEnvironments().stream() .filter(coreEnvironment -> getEnvironment().managementEndpoint() .equals(coreEnvironment.getManagementEndpoint())) .findAny().get(); diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/StorageAccountManager.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/StorageAccountManager.java index 6f816ec05e7e..071d3c0e8dc5 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/StorageAccountManager.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/microsoft/azure/spring/cloud/context/core/impl/StorageAccountManager.java @@ -5,17 +5,17 @@ import javax.annotation.Nonnull; -import com.azure.resourcemanager.Azure; +import com.azure.resourcemanager.AzureResourceManager; import com.azure.resourcemanager.storage.models.StorageAccount; import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; public class StorageAccountManager extends AzureManager { - - private final Azure azure; - public StorageAccountManager(@Nonnull Azure azure, AzureProperties azureProperties) { + private final AzureResourceManager azureResourceManager; + + public StorageAccountManager(@Nonnull AzureResourceManager azureResourceManager, AzureProperties azureProperties) { super(azureProperties); - this.azure = azure; + this.azureResourceManager = azureResourceManager; } @Override @@ -30,13 +30,13 @@ String getResourceType() { @Override public StorageAccount internalGet(String key) { - - return azure.storageAccounts().getByResourceGroup(azureProperties.getResourceGroup(), key); + + return azureResourceManager.storageAccounts().getByResourceGroup(azureProperties.getResourceGroup(), key); } @Override public StorageAccount internalCreate(String key) { - return azure.storageAccounts().define(key).withRegion(azureProperties.getRegion()) - .withExistingResourceGroup(azureProperties.getResourceGroup()).create(); + return azureResourceManager.storageAccounts().define(key).withRegion(azureProperties.getRegion()) + .withExistingResourceGroup(azureProperties.getResourceGroup()).create(); } } diff --git a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java index 9a829d504643..2b2cc9461145 100644 --- a/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-storage/src/main/java/com/microsoft/azure/spring/cloud/autoconfigure/storage/AzureStorageAutoConfiguration.java @@ -28,6 +28,7 @@ import com.azure.core.http.HttpPipeline; import com.azure.core.http.policy.HttpLogOptions; import com.azure.core.util.logging.ClientLogger; +import com.azure.resourcemanager.AzureResourceManager; import com.azure.resourcemanager.storage.models.StorageAccount; import com.azure.storage.blob.BlobServiceClientBuilder; import com.azure.storage.blob.implementation.util.BuilderHelper; @@ -35,6 +36,7 @@ import com.azure.storage.file.share.ShareServiceClientBuilder; import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureResourceManager20AutoConfiguration; import com.microsoft.azure.spring.cloud.context.core.api.EnvironmentProvider; +import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; import com.microsoft.azure.spring.cloud.context.core.impl.StorageAccountManager; import com.microsoft.azure.spring.cloud.context.core.storage.StorageConnectionStringProvider; import com.microsoft.azure.spring.cloud.context.core.storage.StorageEndpointStringBuilder; @@ -139,4 +141,10 @@ public ShareServiceClientBuilder shareServiceClientBuilder(AzureStoragePropertie @Import(AzureStorageProtocolResolver.class) static class StorageResourceConfiguration { } + + @Bean + @ConditionalOnMissingBean + public StorageAccountManager storageAccountManager(AzureResourceManager azureResourceManagement, AzureProperties azureProperties) { + return new StorageAccountManager(azureResourceManagement, azureProperties); + } } From bccd6e27a25018aa72f095ca15958ddac9581e7e Mon Sep 17 00:00:00 2001 From: Xiaolu Dai Date: Wed, 28 Oct 2020 17:35:00 +0800 Subject: [PATCH 35/47] include version tag should be on the same line --- sdk/spring/azure-spring-cloud-storage/pom.xml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/sdk/spring/azure-spring-cloud-storage/pom.xml b/sdk/spring/azure-spring-cloud-storage/pom.xml index 965b8e164395..81ff38ae31c1 100644 --- a/sdk/spring/azure-spring-cloud-storage/pom.xml +++ b/sdk/spring/azure-spring-cloud-storage/pom.xml @@ -141,12 +141,9 @@ org.hibernate.validator:hibernate-validator:[6.1.5.Final] - org.springframework.boot:spring-boot-actuator-autoconfigure:[2.3.4.RELEASE] - - org.springframework.boot:spring-boot-configuration-processor:[2.3.4.RELEASE] - - org.springframework.boot:spring-boot-starter-logging:[2.3.4.RELEASE] - + org.springframework.boot:spring-boot-actuator-autoconfigure:[2.3.4.RELEASE] + org.springframework.boot:spring-boot-configuration-processor:[2.3.4.RELEASE] + org.springframework.boot:spring-boot-starter-logging:[2.3.4.RELEASE] From 9a206f1377b099fa9722a831c1f325d3555741f3 Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Wed, 28 Oct 2020 16:49:22 -0400 Subject: [PATCH 36/47] Spring Cloud Stream - Event Hub binder demo now works --- .../config/EventHubBinderConfiguration.java | 17 +++++++++++++++++ ...entHubChannelResourceManagerProvisioner.java | 6 ++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/config/EventHubBinderConfiguration.java b/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/config/EventHubBinderConfiguration.java index 35bc80a9c3d2..9de32a3d3092 100644 --- a/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/config/EventHubBinderConfiguration.java +++ b/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/config/EventHubBinderConfiguration.java @@ -17,10 +17,12 @@ import com.microsoft.azure.eventhub.stream.binder.properties.EventHubExtendedBindingProperties; import com.microsoft.azure.eventhub.stream.binder.provisioning.EventHubChannelProvisioner; import com.microsoft.azure.eventhub.stream.binder.provisioning.EventHubChannelResourceManagerProvisioner; +import com.microsoft.azure.management.Azure; import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureEnvironmentAutoConfiguration; import com.microsoft.azure.spring.cloud.autoconfigure.eventhub.AzureEventHubAutoConfiguration; import com.microsoft.azure.spring.cloud.autoconfigure.eventhub.AzureEventHubProperties; import com.microsoft.azure.spring.cloud.autoconfigure.eventhub.EventHubUtils; +import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; import com.microsoft.azure.spring.cloud.context.core.impl.EventHubConsumerGroupManager; import com.microsoft.azure.spring.cloud.context.core.impl.EventHubManager; import com.microsoft.azure.spring.cloud.context.core.impl.EventHubNamespaceManager; @@ -56,6 +58,9 @@ public void collectTelemetry() { @Bean @ConditionalOnMissingBean public EventHubChannelProvisioner eventHubChannelProvisioner(AzureEventHubProperties eventHubProperties) { + // TODO: With the previous ResourceManagerProvider architecture, eventHubManager + // and eventHubConsumerGroup manager were created unconditionally. + // Now, they are not created at all. Should they be? if (eventHubNamespaceManager != null && eventHubManager != null && eventHubConsumerGroupManager != null) { return new EventHubChannelResourceManagerProvisioner(eventHubNamespaceManager, eventHubManager, eventHubConsumerGroupManager, eventHubProperties.getNamespace()); @@ -77,4 +82,16 @@ public EventHubMessageChannelBinder eventHubBinder(EventHubChannelProvisioner ev binder.setBindingProperties(bindingProperties); return binder; } + + @Bean + @ConditionalOnMissingBean + public EventHubManager eventHubManager(Azure azure, AzureProperties azureProperties) { + return new EventHubManager(azure, azureProperties); + } + + @Bean + @ConditionalOnMissingBean + public EventHubConsumerGroupManager eventHubConsumerGroupManager(Azure azure, AzureProperties azureProperties) { + return new EventHubConsumerGroupManager(azure, azureProperties); + } } diff --git a/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/provisioning/EventHubChannelResourceManagerProvisioner.java b/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/provisioning/EventHubChannelResourceManagerProvisioner.java index ca523ca54480..a52854eab824 100644 --- a/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/provisioning/EventHubChannelResourceManagerProvisioner.java +++ b/sdk/spring/azure-spring-cloud-eventhubs-stream-binder/src/main/java/com/microsoft/azure/eventhub/stream/binder/provisioning/EventHubChannelResourceManagerProvisioner.java @@ -36,10 +36,12 @@ public EventHubChannelResourceManagerProvisioner(@NonNull EventHubNamespaceManag @Override protected void validateOrCreateForConsumer(String name, String group) { EventHubNamespace eventHubNamespace = eventHubNamespaceManager.getOrCreate(namespace); - EventHub eventHub = eventHubManager.get(Tuple.of(eventHubNamespace, name)); + //If the consumer is created before the producer, we need to create the event hub with it. + //Otherwise, this method will fail and the startup of a distributed application, where no order of operations can be imposed, will fail with it. + EventHub eventHub = eventHubManager.getOrCreate(Tuple.of(eventHubNamespace, name)); if (eventHub == null) { throw new ProvisioningException( - String.format("Event hub with name '%s' in namespace '%s' not existed", name, namespace)); + String.format("Event hub with name '%s' in namespace '%s' could not be created", name, namespace)); } eventHubConsumerGroupManager.getOrCreate(Tuple.of(eventHub, group)); From 7bec93506131bdb3a37be8b282a24e1c0920202a Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Thu, 29 Oct 2020 17:33:58 -0400 Subject: [PATCH 37/47] Fixing build failures --- .../config/EventHubBinderConfiguration.java | 15 +-------------- ...EventHubChannelResourceManagerProvisioner.java | 13 +++++++------ 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/sdk/spring/azure-spring-cloud-stream-binder-eventhubs/src/main/java/com/azure/spring/eventhub/stream/binder/config/EventHubBinderConfiguration.java b/sdk/spring/azure-spring-cloud-stream-binder-eventhubs/src/main/java/com/azure/spring/eventhub/stream/binder/config/EventHubBinderConfiguration.java index cba1eb610c53..8c14e4e7c33d 100644 --- a/sdk/spring/azure-spring-cloud-stream-binder-eventhubs/src/main/java/com/azure/spring/eventhub/stream/binder/config/EventHubBinderConfiguration.java +++ b/sdk/spring/azure-spring-cloud-stream-binder-eventhubs/src/main/java/com/azure/spring/eventhub/stream/binder/config/EventHubBinderConfiguration.java @@ -7,6 +7,7 @@ import com.azure.spring.cloud.autoconfigure.eventhub.AzureEventHubAutoConfiguration; import com.azure.spring.cloud.autoconfigure.eventhub.AzureEventHubProperties; import com.azure.spring.cloud.autoconfigure.eventhub.EventHubUtils; +import com.azure.spring.cloud.context.core.config.AzureProperties; import com.azure.spring.cloud.context.core.impl.EventHubConsumerGroupManager; import com.azure.spring.cloud.context.core.impl.EventHubManager; import com.azure.spring.cloud.context.core.impl.EventHubNamespaceManager; @@ -24,21 +25,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import com.microsoft.azure.eventhub.stream.binder.EventHubMessageChannelBinder; -import com.microsoft.azure.eventhub.stream.binder.properties.EventHubExtendedBindingProperties; -import com.microsoft.azure.eventhub.stream.binder.provisioning.EventHubChannelProvisioner; -import com.microsoft.azure.eventhub.stream.binder.provisioning.EventHubChannelResourceManagerProvisioner; import com.microsoft.azure.management.Azure; -import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureEnvironmentAutoConfiguration; -import com.microsoft.azure.spring.cloud.autoconfigure.eventhub.AzureEventHubAutoConfiguration; -import com.microsoft.azure.spring.cloud.autoconfigure.eventhub.AzureEventHubProperties; -import com.microsoft.azure.spring.cloud.autoconfigure.eventhub.EventHubUtils; -import com.microsoft.azure.spring.cloud.context.core.config.AzureProperties; -import com.microsoft.azure.spring.cloud.context.core.impl.EventHubConsumerGroupManager; -import com.microsoft.azure.spring.cloud.context.core.impl.EventHubManager; -import com.microsoft.azure.spring.cloud.context.core.impl.EventHubNamespaceManager; -import com.microsoft.azure.spring.cloud.telemetry.TelemetryCollector; -import com.microsoft.azure.spring.integration.eventhub.api.EventHubOperation; import javax.annotation.PostConstruct; diff --git a/sdk/spring/azure-spring-cloud-stream-binder-eventhubs/src/main/java/com/azure/spring/eventhub/stream/binder/provisioning/EventHubChannelResourceManagerProvisioner.java b/sdk/spring/azure-spring-cloud-stream-binder-eventhubs/src/main/java/com/azure/spring/eventhub/stream/binder/provisioning/EventHubChannelResourceManagerProvisioner.java index 9a155e5854e4..de416b40b6f1 100644 --- a/sdk/spring/azure-spring-cloud-stream-binder-eventhubs/src/main/java/com/azure/spring/eventhub/stream/binder/provisioning/EventHubChannelResourceManagerProvisioner.java +++ b/sdk/spring/azure-spring-cloud-stream-binder-eventhubs/src/main/java/com/azure/spring/eventhub/stream/binder/provisioning/EventHubChannelResourceManagerProvisioner.java @@ -23,9 +23,8 @@ public class EventHubChannelResourceManagerProvisioner extends EventHubChannelPr private final EventHubConsumerGroupManager eventHubConsumerGroupManager; public EventHubChannelResourceManagerProvisioner(@NonNull EventHubNamespaceManager eventHubNamespaceManager, - @NonNull EventHubManager eventHubManager, - @NonNull EventHubConsumerGroupManager eventHubConsumerGroupManager, - @NonNull String namespace) { + @NonNull EventHubManager eventHubManager, + @NonNull EventHubConsumerGroupManager eventHubConsumerGroupManager, @NonNull String namespace) { Assert.hasText(namespace, "The namespace can't be null or empty"); this.namespace = namespace; this.eventHubNamespaceManager = eventHubNamespaceManager; @@ -36,13 +35,15 @@ public EventHubChannelResourceManagerProvisioner(@NonNull EventHubNamespaceManag @Override protected void validateOrCreateForConsumer(String name, String group) { EventHubNamespace eventHubNamespace = eventHubNamespaceManager.getOrCreate(namespace); - //If the consumer is created before the producer, we need to create the event hub with it. - //Otherwise, this method will fail and the startup of a distributed application, where no order of operations can be imposed, will fail with it. + // If the consumer is created before the producer, we need to create the event + // hub with it. + // Otherwise, this method will fail and the startup of a distributed + // application, where no order of operations can be imposed, will fail with it. EventHub eventHub = eventHubManager.getOrCreate(Tuple.of(eventHubNamespace, name)); if (eventHub == null) { throw new ProvisioningException( String.format("Event hub with name '%s' in namespace '%s' could not be created", name, namespace)); - + } eventHubConsumerGroupManager.getOrCreate(Tuple.of(eventHub, group)); } From 456d383c3de2956f7e2e7dd59ecb4d66f617e6c9 Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Fri, 30 Oct 2020 14:45:32 -0400 Subject: [PATCH 38/47] Preventing reliance on resource management bean when resource group parameter not set (i.e. that bean would not be initialized) --- .../AzureEventHubAutoConfiguration.java | 1 + ...AzureServiceBusQueueAutoConfiguration.java | 1 + .../config/EventHubBinderConfiguration.java | 32 ++++++++++--------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/eventhub/AzureEventHubAutoConfiguration.java b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/eventhub/AzureEventHubAutoConfiguration.java index b5d379b14fd2..0f3b13efffd6 100644 --- a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/eventhub/AzureEventHubAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/eventhub/AzureEventHubAutoConfiguration.java @@ -112,6 +112,7 @@ public EventHubClientFactory clientFactory(EventHubConnectionStringProvider conn @Bean @ConditionalOnMissingBean + @ConditionalOnProperty("spring.cloud.azure.resource-group") public EventHubNamespaceManager eventHubNamespaceManager(Azure azure, AzureProperties azureProperties) { return new EventHubNamespaceManager(azure, azureProperties); } diff --git a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusQueueAutoConfiguration.java b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusQueueAutoConfiguration.java index 78405e86b69d..dab2d89b1430 100644 --- a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusQueueAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusQueueAutoConfiguration.java @@ -76,6 +76,7 @@ public ServiceBusQueueOperation queueOperation(ServiceBusQueueClientFactory fact @Bean @ConditionalOnMissingBean + @ConditionalOnProperty("spring.cloud.azure.resource-group") public ServiceBusNamespaceManager serviceBusNamespaceManager(Azure azure, AzureProperties azureProperties) { return new ServiceBusNamespaceManager(azure, azureProperties); } diff --git a/sdk/spring/azure-spring-cloud-stream-binder-eventhubs/src/main/java/com/azure/spring/eventhub/stream/binder/config/EventHubBinderConfiguration.java b/sdk/spring/azure-spring-cloud-stream-binder-eventhubs/src/main/java/com/azure/spring/eventhub/stream/binder/config/EventHubBinderConfiguration.java index 8c14e4e7c33d..88b319b743dc 100644 --- a/sdk/spring/azure-spring-cloud-stream-binder-eventhubs/src/main/java/com/azure/spring/eventhub/stream/binder/config/EventHubBinderConfiguration.java +++ b/sdk/spring/azure-spring-cloud-stream-binder-eventhubs/src/main/java/com/azure/spring/eventhub/stream/binder/config/EventHubBinderConfiguration.java @@ -3,6 +3,17 @@ package com.azure.spring.eventhub.stream.binder.config; +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.stream.binder.Binder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + import com.azure.spring.cloud.autoconfigure.context.AzureEnvironmentAutoConfiguration; import com.azure.spring.cloud.autoconfigure.eventhub.AzureEventHubAutoConfiguration; import com.azure.spring.cloud.autoconfigure.eventhub.AzureEventHubProperties; @@ -17,18 +28,8 @@ import com.azure.spring.eventhub.stream.binder.provisioning.EventHubChannelProvisioner; import com.azure.spring.eventhub.stream.binder.provisioning.EventHubChannelResourceManagerProvisioner; import com.azure.spring.integration.eventhub.api.EventHubOperation; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.stream.binder.Binder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - import com.microsoft.azure.management.Azure; -import javax.annotation.PostConstruct; - /** * @author Warren Zhu */ @@ -63,10 +64,10 @@ public EventHubChannelProvisioner eventHubChannelProvisioner(AzureEventHubProper // Now, they are not created at all. Should they be? if (eventHubNamespaceManager != null && eventHubManager != null && eventHubConsumerGroupManager != null) { return new EventHubChannelResourceManagerProvisioner(eventHubNamespaceManager, eventHubManager, - eventHubConsumerGroupManager, eventHubProperties.getNamespace()); + eventHubConsumerGroupManager, eventHubProperties.getNamespace()); } else { String namespace = eventHubProperties.getNamespace() != null ? eventHubProperties.getNamespace() - : EventHubUtils.getNamespace(eventHubProperties.getConnectionString()); + : EventHubUtils.getNamespace(eventHubProperties.getConnectionString()); TelemetryCollector.getInstance().addProperty(EVENT_HUB_BINDER, NAMESPACE, namespace); } @@ -76,22 +77,23 @@ public EventHubChannelProvisioner eventHubChannelProvisioner(AzureEventHubProper @Bean @ConditionalOnMissingBean public EventHubMessageChannelBinder eventHubBinder(EventHubChannelProvisioner eventHubChannelProvisioner, - EventHubOperation eventHubOperation, - EventHubExtendedBindingProperties bindingProperties) { + EventHubOperation eventHubOperation, EventHubExtendedBindingProperties bindingProperties) { EventHubMessageChannelBinder binder = new EventHubMessageChannelBinder(null, eventHubChannelProvisioner, - eventHubOperation); + eventHubOperation); binder.setBindingProperties(bindingProperties); return binder; } @Bean @ConditionalOnMissingBean + @ConditionalOnProperty("spring.cloud.azure.resource-group") public EventHubManager eventHubManager(Azure azure, AzureProperties azureProperties) { return new EventHubManager(azure, azureProperties); } @Bean @ConditionalOnMissingBean + @ConditionalOnProperty("spring.cloud.azure.resource-group") public EventHubConsumerGroupManager eventHubConsumerGroupManager(Azure azure, AzureProperties azureProperties) { return new EventHubConsumerGroupManager(azure, azureProperties); } From fcb8bc81dca769b5700dbe4352422fa9d2b75a54 Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Fri, 30 Oct 2020 17:01:25 -0400 Subject: [PATCH 39/47] Fixing NPE in auto-configuration --- .../AzureContextAutoConfigurationTest.java | 92 +++++++++++++------ .../AzureContextAutoConfiguration.java | 11 ++- 2 files changed, 74 insertions(+), 29 deletions(-) diff --git a/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfigurationTest.java b/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfigurationTest.java index ab485ffd3942..01c97fee1e62 100644 --- a/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfigurationTest.java +++ b/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfigurationTest.java @@ -3,67 +3,105 @@ package com.azure.spring.cloud.autoconfigure.context; -import com.azure.spring.cloud.context.core.api.CredentialsProvider; -import com.azure.spring.cloud.context.core.config.AzureProperties; -import com.microsoft.azure.AzureEnvironment; -import com.microsoft.azure.credentials.AzureTokenCredentials; -import com.microsoft.azure.management.Azure; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.IOException; + import org.junit.Test; +import org.mockito.Mockito; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; +import com.azure.spring.cloud.context.core.api.CredentialsProvider; +import com.azure.spring.cloud.context.core.config.AzureProperties; +import com.microsoft.azure.AzureEnvironment; +import com.microsoft.azure.credentials.AzureTokenCredentials; +import com.microsoft.azure.management.Azure; public class AzureContextAutoConfigurationTest { - private ApplicationContextRunner contextRunner = - new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(AzureContextAutoConfiguration.class)) + private ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(AzureContextAutoConfiguration.class)) .withUserConfiguration(TestConfiguration.class); @Test public void testAzurePropertiesConfigured() { this.contextRunner.withPropertyValues("spring.cloud.azure.credentialFilePath=credential") - .withPropertyValues("spring.cloud.azure.resourceGroup=group1") - .withPropertyValues("spring.cloud.azure.region=westUS").run(context -> { - assertThat(context).hasSingleBean(AzureProperties.class); - assertThat(context.getBean(AzureProperties.class).getCredentialFilePath()).isEqualTo("credential"); - assertThat(context.getBean(AzureProperties.class).getResourceGroup()).isEqualTo("group1"); - assertThat(context.getBean(AzureProperties.class).getRegion()).isEqualTo("westUS"); - assertThat(context.getBean(AzureProperties.class).getEnvironment()).isEqualTo(AzureEnvironment.AZURE); - }); + .withPropertyValues("spring.cloud.azure.resourceGroup=group1") + .withPropertyValues("spring.cloud.azure.region=westUS").run(context -> { + assertThat(context).hasSingleBean(AzureProperties.class); + assertThat(context.getBean(AzureProperties.class).getCredentialFilePath()).isEqualTo("credential"); + assertThat(context.getBean(AzureProperties.class).getResourceGroup()).isEqualTo("group1"); + assertThat(context.getBean(AzureProperties.class).getRegion()).isEqualTo("westUS"); + assertThat(context.getBean(AzureProperties.class).getEnvironment()) + .isEqualTo(AzureEnvironment.AZURE); + }); } @Test public void testRequiredAzureProperties() { this.contextRunner.withPropertyValues("spring.cloud.azure.credentialFilePath=credential") - .withPropertyValues("spring.cloud.azure.resourceGroup=group1").run(context -> { - assertThat(context).hasSingleBean(AzureProperties.class); - assertThat(context.getBean(AzureProperties.class).getCredentialFilePath()).isEqualTo("credential"); - assertThat(context.getBean(AzureProperties.class).getResourceGroup()).isEqualTo("group1"); - }); + .withPropertyValues("spring.cloud.azure.resourceGroup=group1").run(context -> { + assertThat(context).hasSingleBean(AzureProperties.class); + assertThat(context.getBean(AzureProperties.class).getCredentialFilePath()).isEqualTo("credential"); + assertThat(context.getBean(AzureProperties.class).getResourceGroup()).isEqualTo("group1"); + }); } @Test public void testAzureDisabled() { this.contextRunner.withPropertyValues("spring.cloud.azure.enabled=false") - .run(context -> assertThat(context).doesNotHaveBean(AzureProperties.class)); + .run(context -> assertThat(context).doesNotHaveBean(AzureProperties.class)); } @Test public void testWithoutAzureClass() { this.contextRunner.withClassLoader(new FilteredClassLoader(Azure.class)) - .run(context -> assertThat(context).doesNotHaveBean(AzureProperties.class)); + .run(context -> assertThat(context).doesNotHaveBean(AzureProperties.class)); } @Test(expected = IllegalStateException.class) public void testLocationRequiredWhenAutoCreateResources() { this.contextRunner.withPropertyValues("spring.cloud.azure.credentialFilePath=credential") - .withPropertyValues("spring.cloud.azure.resourceGroup=group1") - .withPropertyValues("spring.cloud.azure.auto-create-resources=true") - .run(context -> context.getBean(AzureProperties.class)); + .withPropertyValues("spring.cloud.azure.resourceGroup=group1") + .withPropertyValues("spring.cloud.azure.auto-create-resources=true") + .run(context -> context.getBean(AzureProperties.class)); + } + + @Test + // Ensure a default subscription ID is correctly used when not specified in the + // properties + public void testDefaultSubscriptionId() throws IOException { + AzureProperties azureProperties = new AzureProperties(); + String expectedSubscriptionId = "non-default-subscription-id"; + + //Mock credentials + AzureTokenCredentials mockCredentials = mock(AzureTokenCredentials.class); + when(mockCredentials.domain()).thenReturn("testdomain"); + when(mockCredentials.environment()).thenReturn(AzureEnvironment.AZURE); + when(mockCredentials.defaultSubscriptionId()).thenReturn(expectedSubscriptionId); + + //Call real auto-config logic with stubbed-out connectivity + AzureContextAutoConfiguration mockAutoConfig = mock(AzureContextAutoConfiguration.class); + when(mockAutoConfig.azure(any(), any())).thenCallRealMethod(); + when(mockAutoConfig.authenticateToAzure(any(), anyString(), any())).then(invocation -> { + assertEquals(expectedSubscriptionId, invocation.getArgument(1)); + return mock(Azure.class); + }); + mockAutoConfig.azure(mockCredentials, azureProperties); + verify(mockAutoConfig, times(1)).authenticateToAzure(any(), eq(expectedSubscriptionId), any()); + } @Configuration diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java index 1aa6692abe52..203424500782 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java @@ -6,6 +6,7 @@ import com.azure.spring.cloud.context.core.api.CredentialsProvider; import com.azure.spring.cloud.context.core.config.AzureProperties; import com.azure.spring.cloud.context.core.impl.DefaultCredentialsProvider; +import com.google.common.annotations.VisibleForTesting; import com.microsoft.azure.AzureEnvironment; import com.microsoft.azure.AzureResponseBuilder; import com.microsoft.azure.credentials.AzureTokenCredentials; @@ -62,10 +63,16 @@ public Azure azure(AzureTokenCredentials credentials, AzureProperties azurePrope .withInterceptor(new ResourceManagerThrottlingInterceptor()).withUserAgent(SPRING_CLOUD_USER_AGENT) .build(); - String subscriptionId = Optional.of(azureProperties.getSubscriptionId()) + String subscriptionId = Optional.ofNullable(azureProperties.getSubscriptionId()) .orElseGet(credentials::defaultSubscriptionId); + + return authenticateToAzure(restClient, subscriptionId, credentials); + } + + @VisibleForTesting + protected Azure authenticateToAzure(RestClient restClient, String subscriptionId, AzureTokenCredentials credentials) { return Azure.authenticate(restClient, credentials.domain()) - .withSubscription(subscriptionId); + .withSubscription(subscriptionId); } @Bean From a6cfcfe7e78f6a629c07e714b3a58c6172bc39af Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Fri, 30 Oct 2020 17:01:25 -0400 Subject: [PATCH 40/47] Fixing NPE in auto-configuration --- .../AzureContextAutoConfigurationTest.java | 90 +++++++++++++------ .../AzureContextAutoConfiguration.java | 11 ++- 2 files changed, 73 insertions(+), 28 deletions(-) diff --git a/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfigurationTest.java b/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfigurationTest.java index 066e09b29772..c968ddc7867c 100644 --- a/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfigurationTest.java +++ b/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfigurationTest.java @@ -3,68 +3,106 @@ package com.azure.spring.cloud.autoconfigure.context; -import com.microsoft.azure.AzureEnvironment; -import com.microsoft.azure.credentials.AzureTokenCredentials; -import com.microsoft.azure.management.Azure; -import com.azure.spring.cloud.context.core.api.CredentialsProvider; -import com.azure.spring.cloud.context.core.api.ResourceManagerProvider; -import com.azure.spring.cloud.context.core.config.AzureProperties; +import java.io.IOException; + import org.junit.Test; +import org.mockito.Mockito; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import com.azure.spring.cloud.context.core.api.CredentialsProvider; +import com.azure.spring.cloud.context.core.config.AzureProperties; +import com.microsoft.azure.AzureEnvironment; +import com.microsoft.azure.credentials.AzureTokenCredentials; +import com.microsoft.azure.management.Azure; + import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + public class AzureContextAutoConfigurationTest { - private ApplicationContextRunner contextRunner = - new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(AzureContextAutoConfiguration.class)) + private ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(AzureContextAutoConfiguration.class)) .withUserConfiguration(TestConfiguration.class); @Test public void testAzurePropertiesConfigured() { this.contextRunner.withPropertyValues("spring.cloud.azure.credentialFilePath=credential") - .withPropertyValues("spring.cloud.azure.resourceGroup=group1") - .withPropertyValues("spring.cloud.azure.region=westUS").run(context -> { - assertThat(context).hasSingleBean(AzureProperties.class); - assertThat(context.getBean(AzureProperties.class).getCredentialFilePath()).isEqualTo("credential"); - assertThat(context.getBean(AzureProperties.class).getResourceGroup()).isEqualTo("group1"); - assertThat(context.getBean(AzureProperties.class).getRegion()).isEqualTo("westUS"); - assertThat(context.getBean(AzureProperties.class).getEnvironment()).isEqualTo(AzureEnvironment.AZURE); - }); + .withPropertyValues("spring.cloud.azure.resourceGroup=group1") + .withPropertyValues("spring.cloud.azure.region=westUS").run(context -> { + assertThat(context).hasSingleBean(AzureProperties.class); + assertThat(context.getBean(AzureProperties.class).getCredentialFilePath()).isEqualTo("credential"); + assertThat(context.getBean(AzureProperties.class).getResourceGroup()).isEqualTo("group1"); + assertThat(context.getBean(AzureProperties.class).getRegion()).isEqualTo("westUS"); + assertThat(context.getBean(AzureProperties.class).getEnvironment()) + .isEqualTo(AzureEnvironment.AZURE); + }); } @Test public void testRequiredAzureProperties() { this.contextRunner.withPropertyValues("spring.cloud.azure.credentialFilePath=credential") - .withPropertyValues("spring.cloud.azure.resourceGroup=group1").run(context -> { - assertThat(context).hasSingleBean(AzureProperties.class); - assertThat(context.getBean(AzureProperties.class).getCredentialFilePath()).isEqualTo("credential"); - assertThat(context.getBean(AzureProperties.class).getResourceGroup()).isEqualTo("group1"); - }); + .withPropertyValues("spring.cloud.azure.resourceGroup=group1").run(context -> { + assertThat(context).hasSingleBean(AzureProperties.class); + assertThat(context.getBean(AzureProperties.class).getCredentialFilePath()).isEqualTo("credential"); + assertThat(context.getBean(AzureProperties.class).getResourceGroup()).isEqualTo("group1"); + }); } @Test public void testAzureDisabled() { this.contextRunner.withPropertyValues("spring.cloud.azure.enabled=false") - .run(context -> assertThat(context).doesNotHaveBean(AzureProperties.class)); + .run(context -> assertThat(context).doesNotHaveBean(AzureProperties.class)); } @Test public void testWithoutAzureClass() { this.contextRunner.withClassLoader(new FilteredClassLoader(Azure.class)) - .run(context -> assertThat(context).doesNotHaveBean(AzureProperties.class)); + .run(context -> assertThat(context).doesNotHaveBean(AzureProperties.class)); } @Test(expected = IllegalStateException.class) public void testLocationRequiredWhenAutoCreateResources() { this.contextRunner.withPropertyValues("spring.cloud.azure.credentialFilePath=credential") - .withPropertyValues("spring.cloud.azure.resourceGroup=group1") - .withPropertyValues("spring.cloud.azure.auto-create-resources=true") - .run(context -> context.getBean(AzureProperties.class)); + .withPropertyValues("spring.cloud.azure.resourceGroup=group1") + .withPropertyValues("spring.cloud.azure.auto-create-resources=true") + .run(context -> context.getBean(AzureProperties.class)); + } + + @Test + // Ensure a default subscription ID is correctly used when not specified in the + // properties + public void testDefaultSubscriptionId() throws IOException { + AzureProperties azureProperties = new AzureProperties(); + String expectedSubscriptionId = "non-default-subscription-id"; + + //Mock credentials + AzureTokenCredentials mockCredentials = mock(AzureTokenCredentials.class); + when(mockCredentials.domain()).thenReturn("testdomain"); + when(mockCredentials.environment()).thenReturn(AzureEnvironment.AZURE); + when(mockCredentials.defaultSubscriptionId()).thenReturn(expectedSubscriptionId); + + //Call real auto-config logic with stubbed-out connectivity + AzureContextAutoConfiguration mockAutoConfig = mock(AzureContextAutoConfiguration.class); + when(mockAutoConfig.azure(any(), any())).thenCallRealMethod(); + when(mockAutoConfig.authenticateToAzure(any(), anyString(), any())).then(invocation -> { + assertEquals(expectedSubscriptionId, invocation.getArgument(1)); + return mock(Azure.class); + }); + mockAutoConfig.azure(mockCredentials, azureProperties); + verify(mockAutoConfig, times(1)).authenticateToAzure(any(), eq(expectedSubscriptionId), any()); + } @Configuration diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java index 24685625b58e..a47f784f9bd5 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java @@ -8,6 +8,7 @@ import com.azure.spring.cloud.context.core.config.AzureProperties; import com.azure.spring.cloud.context.core.impl.AzureResourceManagerProvider; import com.azure.spring.cloud.context.core.impl.DefaultCredentialsProvider; +import com.google.common.annotations.VisibleForTesting; import com.microsoft.azure.AzureEnvironment; import com.microsoft.azure.AzureResponseBuilder; import com.microsoft.azure.credentials.AzureTokenCredentials; @@ -65,10 +66,16 @@ public Azure azure(AzureTokenCredentials credentials, AzureProperties azurePrope .withInterceptor(new ResourceManagerThrottlingInterceptor()).withUserAgent(SPRING_CLOUD_USER_AGENT) .build(); - String subscriptionId = Optional.of(azureProperties.getSubscriptionId()) + String subscriptionId = Optional.ofNullable(azureProperties.getSubscriptionId()) .orElseGet(credentials::defaultSubscriptionId); + + return authenticateToAzure(restClient, subscriptionId, credentials); + } + + @VisibleForTesting + protected Azure authenticateToAzure(RestClient restClient, String subscriptionId, AzureTokenCredentials credentials) { return Azure.authenticate(restClient, credentials.domain()) - .withSubscription(subscriptionId); + .withSubscription(subscriptionId); } @Bean From 8277c8949aeb78d2b8ee6fc9dad35b2466c3f30f Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Fri, 30 Oct 2020 17:28:13 -0400 Subject: [PATCH 41/47] Fixing package names broken in merge --- .../autoconfigure/context/AzureContextAutoConfigurationTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfigurationTest.java b/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfigurationTest.java index c968ddc7867c..37ea7f5e199a 100644 --- a/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfigurationTest.java +++ b/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfigurationTest.java @@ -14,6 +14,7 @@ import org.springframework.context.annotation.Configuration; import com.azure.spring.cloud.context.core.api.CredentialsProvider; +import com.azure.spring.cloud.context.core.api.ResourceManagerProvider; import com.azure.spring.cloud.context.core.config.AzureProperties; import com.microsoft.azure.AzureEnvironment; import com.microsoft.azure.credentials.AzureTokenCredentials; From 005e67fcdaf8ec8027bf9a4cab233349ee677086 Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Fri, 30 Oct 2020 18:26:00 -0400 Subject: [PATCH 42/47] Checkstyle appeasement --- .../AzureContextAutoConfigurationTest.java | 31 +++++------ .../AzureContextAutoConfiguration.java | 53 ++++++++++--------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfigurationTest.java b/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfigurationTest.java index 37ea7f5e199a..af90d30f2143 100644 --- a/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfigurationTest.java +++ b/sdk/spring/azure-spring-cloud-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfigurationTest.java @@ -3,10 +3,19 @@ package com.azure.spring.cloud.autoconfigure.context; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import java.io.IOException; import org.junit.Test; -import org.mockito.Mockito; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -20,18 +29,6 @@ import com.microsoft.azure.credentials.AzureTokenCredentials; import com.microsoft.azure.management.Azure; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - - public class AzureContextAutoConfigurationTest { private ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(AzureContextAutoConfiguration.class)) @@ -87,14 +84,14 @@ public void testLocationRequiredWhenAutoCreateResources() { public void testDefaultSubscriptionId() throws IOException { AzureProperties azureProperties = new AzureProperties(); String expectedSubscriptionId = "non-default-subscription-id"; - - //Mock credentials + + // Mock credentials AzureTokenCredentials mockCredentials = mock(AzureTokenCredentials.class); when(mockCredentials.domain()).thenReturn("testdomain"); when(mockCredentials.environment()).thenReturn(AzureEnvironment.AZURE); when(mockCredentials.defaultSubscriptionId()).thenReturn(expectedSubscriptionId); - - //Call real auto-config logic with stubbed-out connectivity + + // Call real auto-config logic with stubbed-out connectivity AzureContextAutoConfiguration mockAutoConfig = mock(AzureContextAutoConfiguration.class); when(mockAutoConfig.azure(any(), any())).thenCallRealMethod(); when(mockAutoConfig.authenticateToAzure(any(), anyString(), any())).then(invocation -> { diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java index a47f784f9bd5..8eede7d0944a 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java @@ -3,6 +3,16 @@ package com.azure.spring.cloud.autoconfigure.context; +import java.io.IOException; +import java.util.Optional; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + import com.azure.spring.cloud.context.core.api.CredentialsProvider; import com.azure.spring.cloud.context.core.api.ResourceManagerProvider; import com.azure.spring.cloud.context.core.config.AzureProperties; @@ -17,18 +27,10 @@ import com.microsoft.azure.management.resources.fluentcore.utils.ResourceManagerThrottlingInterceptor; import com.microsoft.azure.serializer.AzureJacksonAdapter; import com.microsoft.rest.RestClient; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import java.io.IOException; -import java.util.Optional; /** - * Auto-config to provide default {@link CredentialsProvider} for all Azure services + * Auto-config to provide default {@link CredentialsProvider} for all Azure + * services * * @author Warren Zhu */ @@ -38,8 +40,8 @@ @ConditionalOnProperty(prefix = "spring.cloud.azure", value = { "resource-group" }) public class AzureContextAutoConfiguration { - private static final String PROJECT_VERSION = - AzureContextAutoConfiguration.class.getPackage().getImplementationVersion(); + private static final String PROJECT_VERSION = AzureContextAutoConfiguration.class.getPackage() + .getImplementationVersion(); private static final String SPRING_CLOUD_USER_AGENT = "spring-cloud-azure/" + PROJECT_VERSION; @Bean @@ -50,7 +52,8 @@ public ResourceManagerProvider resourceManagerProvider(Azure azure, AzurePropert /** * Create an {@link Azure} bean. - * @param credentials The credential to connect to Azure. + * + * @param credentials The credential to connect to Azure. * @param azureProperties The configured Azure properties. * @return An Azure object. * @throws IOException When IOException happens. @@ -59,23 +62,23 @@ public ResourceManagerProvider resourceManagerProvider(Azure azure, AzurePropert @ConditionalOnMissingBean public Azure azure(AzureTokenCredentials credentials, AzureProperties azureProperties) throws IOException { RestClient restClient = new RestClient.Builder() - .withBaseUrl(credentials.environment(), AzureEnvironment.Endpoint.RESOURCE_MANAGER) - .withCredentials(credentials).withSerializerAdapter(new AzureJacksonAdapter()) - .withResponseBuilderFactory(new AzureResponseBuilder.Factory()) - .withInterceptor(new ProviderRegistrationInterceptor(credentials)) - .withInterceptor(new ResourceManagerThrottlingInterceptor()).withUserAgent(SPRING_CLOUD_USER_AGENT) - .build(); + .withBaseUrl(credentials.environment(), AzureEnvironment.Endpoint.RESOURCE_MANAGER) + .withCredentials(credentials).withSerializerAdapter(new AzureJacksonAdapter()) + .withResponseBuilderFactory(new AzureResponseBuilder.Factory()) + .withInterceptor(new ProviderRegistrationInterceptor(credentials)) + .withInterceptor(new ResourceManagerThrottlingInterceptor()).withUserAgent(SPRING_CLOUD_USER_AGENT) + .build(); String subscriptionId = Optional.ofNullable(azureProperties.getSubscriptionId()) - .orElseGet(credentials::defaultSubscriptionId); - + .orElseGet(credentials::defaultSubscriptionId); + return authenticateToAzure(restClient, subscriptionId, credentials); } - + @VisibleForTesting - protected Azure authenticateToAzure(RestClient restClient, String subscriptionId, AzureTokenCredentials credentials) { - return Azure.authenticate(restClient, credentials.domain()) - .withSubscription(subscriptionId); + protected Azure authenticateToAzure(RestClient restClient, String subscriptionId, + AzureTokenCredentials credentials) { + return Azure.authenticate(restClient, credentials.domain()).withSubscription(subscriptionId); } @Bean From 552af0cee091b762f8e79fde9ca5fa8ae55efe4f Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Fri, 30 Oct 2020 19:20:51 -0400 Subject: [PATCH 43/47] Checkstyle appeasement --- .../autoconfigure/context/AzureContextAutoConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java index 8eede7d0944a..3d4125b8356d 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java @@ -53,7 +53,7 @@ public ResourceManagerProvider resourceManagerProvider(Azure azure, AzurePropert /** * Create an {@link Azure} bean. * - * @param credentials The credential to connect to Azure. + * @param credentials The credential to connect to Azure. * @param azureProperties The configured Azure properties. * @return An Azure object. * @throws IOException When IOException happens. From 85583758604153633695e0975460811b09d027b8 Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Fri, 30 Oct 2020 21:19:33 -0400 Subject: [PATCH 44/47] Eliminating ServiceBus ARM dependency when not pulled in thorugh settings --- .../AzureServiceBusQueueAutoConfiguration.java | 1 + .../AzureServiceBusTopicAutoConfiguration.java | 14 +++++++++----- .../context/AzureContextAutoConfiguration.java | 1 + 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusQueueAutoConfiguration.java b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusQueueAutoConfiguration.java index dab2d89b1430..09eccc9956c7 100644 --- a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusQueueAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusQueueAutoConfiguration.java @@ -83,6 +83,7 @@ public ServiceBusNamespaceManager serviceBusNamespaceManager(Azure azure, AzureP @Bean @ConditionalOnMissingBean + @ConditionalOnProperty("spring.cloud.azure.resource-group") public ServiceBusQueueManager serviceBusQueueManager(AzureProperties azureProperties) { return new ServiceBusQueueManager(azureProperties); } diff --git a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusTopicAutoConfiguration.java b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusTopicAutoConfiguration.java index b7a50da2acce..aad29735542a 100644 --- a/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusTopicAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/servicebus/AzureServiceBusTopicAutoConfiguration.java @@ -74,25 +74,29 @@ public ServiceBusTopicClientFactory topicClientFactory(AzureServiceBusProperties @Bean @ConditionalOnMissingBean + @ConditionalOnProperty("spring.cloud.azure.resource-group") public ServiceBusNamespaceManager serviceBusNamespaceManager(Azure azure, AzureProperties azureProperties) { return new ServiceBusNamespaceManager(azure, azureProperties); } @Bean @ConditionalOnMissingBean + @ConditionalOnProperty("spring.cloud.azure.resource-group") public ServiceBusTopicSubscriptionManager serviceBusTopicSubscriptionManager(AzureProperties azureProperties) { return new ServiceBusTopicSubscriptionManager(azureProperties); } @Bean @ConditionalOnMissingBean - public ServiceBusTopicOperation topicOperation(ServiceBusTopicClientFactory factory) { - return new ServiceBusTopicTemplate(factory); + @ConditionalOnProperty("spring.cloud.azure.resource-group") + public ServiceBusTopicManager serviceBusTopicManager(AzureProperties azureProperties) { + return new ServiceBusTopicManager(azureProperties); } - + @Bean @ConditionalOnMissingBean - public ServiceBusTopicManager serviceBusTopicManager(AzureProperties azureProperties) { - return new ServiceBusTopicManager(azureProperties); + public ServiceBusTopicOperation topicOperation(ServiceBusTopicClientFactory factory) { + return new ServiceBusTopicTemplate(factory); } + } diff --git a/sdk/spring/azure-spring-cloud-context/src/main/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java b/sdk/spring/azure-spring-cloud-context/src/main/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java index 6ae6948af659..428643707d38 100644 --- a/sdk/spring/azure-spring-cloud-context/src/main/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java +++ b/sdk/spring/azure-spring-cloud-context/src/main/java/com/azure/spring/cloud/autoconfigure/context/AzureContextAutoConfiguration.java @@ -7,6 +7,7 @@ import java.util.Optional; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; From dde0594e10b8424e60a58984be0fc6bbaadb01f5 Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Fri, 30 Oct 2020 21:56:23 -0400 Subject: [PATCH 45/47] Deleting duplicate sample --- .../README.adoc | 115 ------------------ .../pom.xml | 69 ----------- .../main/java/com/example/BlobController.java | 43 ------- .../java/com/example/StorageApplication.java | 21 ---- .../src/main/resources/application.properties | 26 ---- .../com/example/StorageApplicationIT.java | 50 -------- .../resources/application-test.properties | 8 -- 7 files changed, 332 deletions(-) delete mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/README.adoc delete mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/pom.xml delete mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/BlobController.java delete mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/StorageApplication.java delete mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties delete mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/java/com/example/StorageApplicationIT.java delete mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/resources/application-test.properties diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/README.adoc b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/README.adoc deleted file mode 100644 index 977ad8aefed1..000000000000 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/README.adoc +++ /dev/null @@ -1,115 +0,0 @@ -= Spring Cloud Azure Storage Starter Sample - -This code sample demonstrates how to read and write files with the Spring Resource abstraction for Azure Storage using -the -link:../../spring-cloud-azure-starters/spring-starter-azure-storage[Spring Cloud Azure Storage Starter].Running this sample will be charged by Azure. You can check the usage and bill at https://azure.microsoft.com/en-us/account/[this link]. - -Running this sample will be charged by Azure. You can check the usage and bill at https://azure.microsoft.com/en-us/account/[this link]. - -Maven coordinates: - -[source,xml] ----- - - com.microsoft.azure - spring-starter-azure-storage - ----- - -Gradle coordinates: - -[source] ----- -dependencies { - compile group: 'com.microsoft.azure', name: 'spring-starter-azure-storage' -} ----- - -== Access key based usage - -1. Create https://docs.microsoft.com/en-us/azure/storage/[Azure Storage] - -2. Update link:src/main/resources/application.properties[application.properties] - -+ -.... -spring.cloud.azure.storage.account=[storage-account-name] - -# Fill storage account access key copied from portal -spring.cloud.azure.storage.access-key=[storage-account-accesskey] - -.... - -== Credential file based usage - -1. Create azure credential file. Please see https://github.com/Azure/azure-libraries-for-java/blob/master/AUTH.md[how to create credential file]. -+ -.... -$ az login -$ az account set --subscription -$ az ad sp create-for-rbac --sdk-auth > my.azureauth -.... -+ -Make sure `my.azureauth` is encoded with UTF-8. - -2. Put credential file under `src/main/resources/`. - -3. Create https://docs.microsoft.com/en-us/azure/storage/[Azure Storage]. Or enable auto create -resources feature in link:src/main/resources/application.properties[application.properties]: -+ -.... -spring.cloud.azure.auto-create-resources=true - -# Example region is westUS, northchina -spring.cloud.azure.region=[region] -.... - -5. Update link:src/main/resources/application.properties[application.properties] -+ -.... - -# Enter 'my.azureauth' here if following step 1 and 2 -spring.cloud.azure.credential-file-path=[credential-file-path] - -spring.cloud.azure.resource-group=[resource-group] - -spring.cloud.azure.storage.account=[account-name] -.... - - - -== How to run - -5. Update link:src/main/resources/application.properties[application.properties] - -+ -.... - -# Default environment is GLOBAL. Provide your own if in another environment -# Example environment is China, GLOBAL -# spring.cloud.azure.environment=[environment] - -# Change into your containerName, blobName -blob=azure-blob://containerName/blobName - -.... - -6. Start the `StorageApplication` Spring Boot app. -+ -``` -$ mvn spring-boot:run -``` - -7. Send a POST request to update file contents: -+ -``` -$ curl -d 'new message' -H 'Content-Type: text/plain' localhost:8080/blob -``` -+ -Verify by sending a GET request -+ -``` -$ curl -XGET http://localhost:8080/blob -``` - -8. Delete the resources on http://ms.portal.azure.com/[Azure Portal] to avoid unexpected charges. diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/pom.xml b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/pom.xml deleted file mode 100644 index 2222014ad8fc..000000000000 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/pom.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - com.azure - azure-spring-boot-service - 1.0.0 - ../.. - - 4.0.0 - - 1.8 - 1.8 - 2.3.3.RELEASE - - - azure-spring-boot-sample-storage-resource - Spring Cloud Azure Storage Resource Sample - - - com.azure.spring - azure-spring-cloud-storage - 2.0.0-beta.1 - - - - org.springframework.boot - spring-boot-starter - ${spring.boot.version} - - - - org.springframework.boot - spring-boot-starter-web - ${spring.boot.version} - - - - junit - junit - 4.12 - test - - - org.springframework.boot - spring-boot-starter-test - ${spring.boot.version} - test - - - org.junit.vintage - junit-vintage-engine - - - - - - - - - - com.google.code.gson - gson - 2.8.6 - - - - diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/BlobController.java b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/BlobController.java deleted file mode 100644 index 34d07941b451..000000000000 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/BlobController.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See LICENSE in the project root for - * license information. - */ - -package com.example; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.io.Resource; -import org.springframework.core.io.WritableResource; -import org.springframework.util.StreamUtils; -import org.springframework.web.bind.annotation.*; - -import java.io.IOException; -import java.io.OutputStream; -import java.nio.charset.Charset; - -/** - * @author Warren Zhu - */ -@RestController -@RequestMapping("blob") -public class BlobController { - - @Value("${blob}") - private Resource blobFile; - - @GetMapping - public String readBlobFile() throws IOException { - return StreamUtils.copyToString( - this.blobFile.getInputStream(), - Charset.defaultCharset()); - } - - @PostMapping - public String writeBlobFile(@RequestBody String data) throws IOException { - try (OutputStream os = ((WritableResource) this.blobFile).getOutputStream()) { - os.write(data.getBytes()); - } - return "file was updated"; - } -} diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/StorageApplication.java b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/StorageApplication.java deleted file mode 100644 index e9f5752e9d70..000000000000 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/java/com/example/StorageApplication.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See LICENSE in the project root for - * license information. - */ - -package com.example; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -/** - * @author Warren Zhu - */ -@SpringBootApplication -public class StorageApplication { - - public static void main(String[] args) { - SpringApplication.run(StorageApplication.class, args); - } -} diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties deleted file mode 100644 index 9b14237bbb4a..000000000000 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/main/resources/application.properties +++ /dev/null @@ -1,26 +0,0 @@ -# Credential file based usage - -# spring.cloud.azure.credential-file-path=[credential-file-path] -# spring.cloud.azure.resource-group=test - -# Access key based usage - -# Fill storage account access key copied from portal -# spring.cloud.azure.storage.access-key=[storage-account-accesskey] - -# Storage account name length should be between 3 and 24 -# and use numbers and lower-case letters only. -spring.cloud.azure.storage.account=ybstortst2 - -spring.cloud.azure.resource-group=test - -# Change into your containerName and blobName -blob=azure-blob://ybstrcntnr/testblob.txt - -# Default environment is GLOBAL. Provide your own if in another environment -# Example environment is China, GLOBAL -# spring.cloud.azure.environment=[environment] -# Example region is westUS, northchina -spring.cloud.azure.region=eastus2 - -spring.cloud.azure.auto-create-resources=true diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/java/com/example/StorageApplicationIT.java b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/java/com/example/StorageApplicationIT.java deleted file mode 100644 index 9d7193b29265..000000000000 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/java/com/example/StorageApplicationIT.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See LICENSE in the project root for - * license information. - */ -package com.example; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.http.MediaType; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.servlet.MockMvc; - -import java.util.UUID; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = StorageApplication.class) -@AutoConfigureMockMvc -@TestPropertySource( - locations = "classpath:application-test.properties") -public class StorageApplicationIT { - - @Autowired - private MockMvc mvc; - - @Test - public void testPostAndGetSuccess() - throws Exception { - String content = UUID.randomUUID().toString(); - - mvc.perform(post("/blob") - .contentType(MediaType.APPLICATION_JSON).content(content)) - .andExpect(status().isOk()) - .andExpect(content().string("file was updated")); - - mvc.perform(get("/blob") - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(content().string(content)); - } -} diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/resources/application-test.properties b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/resources/application-test.properties deleted file mode 100644 index 197151f76113..000000000000 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-storage-resource/src/test/resources/application-test.properties +++ /dev/null @@ -1,8 +0,0 @@ -spring.cloud.azure.credential-file-path=file:@credential@ -spring.cloud.azure.resource-group=spring-cloud - -blob=azure-blob://container1/blob1 -spring.cloud.azure.storage.account=springcloud - -spring.cloud.azure.region=westUS -spring.cloud.azure.auto-create-resources=true From 2a7d5a3fa716a12758fdd40abda434cc8bc865dc Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Sun, 1 Nov 2020 21:52:57 -0500 Subject: [PATCH 46/47] Removing module for superfluous storage resource demeo --- sdk/spring/pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/sdk/spring/pom.xml b/sdk/spring/pom.xml index 67b904e8b6b0..0b8484fdfc30 100644 --- a/sdk/spring/pom.xml +++ b/sdk/spring/pom.xml @@ -41,7 +41,6 @@ azure-spring-boot-samples/azure-spring-boot-sample-servicebus-jms-queue azure-spring-boot-samples/azure-spring-boot-sample-servicebus-jms-topic azure-spring-boot-samples/azure-spring-boot-sample-storage-blob - azure-spring-boot-samples/azure-spring-boot-sample-storage-resource azure-spring-boot-samples/azure-spring-data-sample-gremlin azure-spring-boot-samples/azure-spring-data-sample-gremlin-web-service azure-spring-boot-samples/azure-cloud-foundry-service-sample From 5531c84a87971c186faaee473e7c6fb8632e311d Mon Sep 17 00:00:00 2001 From: Yev Bronshteyn Date: Sun, 1 Nov 2020 22:12:04 -0500 Subject: [PATCH 47/47] Fixing parent pom of identity library --- sdk/spring/azure-identity-spring-library/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/spring/azure-identity-spring-library/pom.xml b/sdk/spring/azure-identity-spring-library/pom.xml index 457d1880c49b..1d38f50de519 100644 --- a/sdk/spring/azure-identity-spring-library/pom.xml +++ b/sdk/spring/azure-identity-spring-library/pom.xml @@ -3,7 +3,7 @@ 4.0.0 - com.azure + com.azure.spring azure-spring-boot-service 1.0.0