Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add storage common property configuration supports all Storage features #29094

Merged
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions eng/code-quality-reports/src/main/resources/revapi/revapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,30 @@
"superClass": "com.azure.core.models.MessageContent",
"justification": "To support Schema Registry Avro Serializer's signature, EventData extends from MessageContent."
},
{
"regex": true,
"code": "java.class.noLongerInheritsFromClass",
"new": "class com\\.azure\\.spring\\.cloud\\.autoconfigure\\.storage\\..*",
"justification": "To support for storage services to share values of common properties."
},
{
"regex": true,
"code": "java\\.annotation\\.added",
"new": "class com\\.azure\\.spring\\.cloud\\.autoconfigure\\.storage\\..*",
"justification": "To support for storage services to share values of common properties."
},
{
"regex": true,
"code": "java\\.annotation\\.attributeRemoved",
"new": "class com\\.azure\\.spring\\.cloud\\.autoconfigure\\.storage\\..*",
"justification": "To support for storage services to share values of common properties."
},
{
"regex": true,
"code": "java\\.annotation\\.attributeAdded",
"new": "class com\\.azure\\.spring\\.cloud\\.autoconfigure\\.storage\\..*",
"justification": "To support for storage services to share values of common properties."
},
{
"code": "java.method.visibilityReduced",
"new": "method com.azure.spring.cloud.autoconfigure.context.AzureTokenCredentialAutoConfiguration.AzureServiceClientBuilderFactoryPostProcessor com.azure.spring.cloud.autoconfigure.context.AzureTokenCredentialAutoConfiguration::builderFactoryBeanPostProcessor()",
Expand Down
5 changes: 5 additions & 0 deletions eng/jacoco-test-coverage/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,11 @@
<artifactId>spring-cloud-azure-starter-data-cosmos</artifactId>
<version>4.3.0-beta.1</version> <!-- {x-version-update;com.azure.spring:spring-cloud-azure-starter-data-cosmos;current} -->
</dependency>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-storage</artifactId>
<version>4.3.0-beta.1</version> <!-- {x-version-update;com.azure.spring:spring-cloud-azure-starter-storage;current} -->
</dependency>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-storage-blob</artifactId>
Expand Down
1 change: 1 addition & 0 deletions eng/versioning/version_client.txt
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ com.azure.spring:spring-cloud-azure-starter-keyvault-certificates;4.2.0;4.3.0-be
com.azure.spring:spring-cloud-azure-starter-keyvault-secrets;4.2.0;4.3.0-beta.1
com.azure.spring:spring-cloud-azure-starter-servicebus-jms;4.2.0;4.3.0-beta.1
com.azure.spring:spring-cloud-azure-starter-servicebus;4.2.0;4.3.0-beta.1
com.azure.spring:spring-cloud-azure-starter-storage;4.3.0-beta.1;4.3.0-beta.1
com.azure.spring:spring-cloud-azure-starter-storage-blob;4.2.0;4.3.0-beta.1
com.azure.spring:spring-cloud-azure-starter-storage-file-share;4.2.0;4.3.0-beta.1
com.azure.spring:spring-cloud-azure-starter-storage-queue;4.2.0;4.3.0-beta.1
Expand Down
10 changes: 9 additions & 1 deletion sdk/spring/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,28 @@
## 4.3.0-beta.1 (Unreleased)

### Features Added
- GA the `spring-cloud-azure-starter-storage`. This starter supports all features of Azure Storage.

### Breaking Changes

### Bugs Fixed

### Other Changes

### Spring Cloud Azure Autoconfigure
This section includes changes in `spring-cloud-azure-autoconfigure` module.

#### Breaking Changes
+ Add `AzureStorageConfiguration` to make Azure storage service share common property configuration [#29094](https://github.com/Azure/azure-sdk-for-java/pull/29094).
+ Add properties `spring.cloud.azure.storage.endpoint`, `spring.cloud.azure.storage.account-key`, `spring.cloud.azure.storage.sas-token`, `spring.cloud.azure.storage.connection-string`, `spring.cloud.azure.storage.account-name`.

### Spring Messaging Azure Service Bus
This section includes changes in the `spring-messaging-azure-servicebus` module.

#### Bugs Fixed
- Fix the `ServiceBusContainerProperties` constructor with overriding the default field values [#29095](https://github.com/Azure/azure-sdk-for-java/pull/29095).
- Restrict the concurrency value to be int format in `ServiceBusListener` [#29095](https://github.com/Azure/azure-sdk-for-java/pull/29095).

## 4.2.0 (2022-05-26)

- This release is compatible with Spring Boot 2.5.0-2.5.14, 2.6.0-2.6.8, 2.7.0. (Note: 2.5.x (x>14), 2.6.y (y>8) and 2.7.z (z>0) should be supported, but they aren't tested with this release.)
Expand Down
12 changes: 12 additions & 0 deletions sdk/spring/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ parameters:
displayName: 'spring-cloud-azure-starter-servicebus-jms'
type: boolean
default: true
- name: release_springcloudazurestarterstorage
displayName: 'spring-cloud-azure-starter-storage'
type: boolean
default: true
- name: release_springcloudazurestarterstorageblob
displayName: 'spring-cloud-azure-starter-storage-blob'
type: boolean
Expand Down Expand Up @@ -377,6 +381,14 @@ extends:
skipUpdatePackageJson: true
skipVerifyChangelog: true
releaseInBatch: ${{ parameters.release_springcloudazurestarterservicebusjms }}
- name: spring-cloud-azure-starter-storage
groupId: com.azure.spring
safeName: springcloudazurestarterstorage
skipPublishDocGithubIo: true
skipPublishDocMs: true
skipUpdatePackageJson: true
skipVerifyChangelog: true
releaseInBatch: ${{ parameters.release_springcloudazurestarterstorage }}
- name: spring-cloud-azure-starter-storage-blob
groupId: com.azure.spring
safeName: springcloudazurestarterstorageblob
Expand Down
2 changes: 2 additions & 0 deletions sdk/spring/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@
<module>spring-cloud-azure-starter-keyvault-secrets</module>
<module>spring-cloud-azure-starter-servicebus-jms</module>
<module>spring-cloud-azure-starter-servicebus</module>
<module>spring-cloud-azure-starter-storage</module>
<module>spring-cloud-azure-starter-storage-blob</module>
<module>spring-cloud-azure-starter-storage-file-share</module>
<module>spring-cloud-azure-starter-storage-queue</module>
Expand Down Expand Up @@ -222,6 +223,7 @@
<module>spring-cloud-azure-starter-keyvault-secrets</module>
<module>spring-cloud-azure-starter-servicebus-jms</module>
<module>spring-cloud-azure-starter-servicebus</module>
<module>spring-cloud-azure-starter-storage</module>
<module>spring-cloud-azure-starter-storage-blob</module>
<module>spring-cloud-azure-starter-storage-file-share</module>
<module>spring-cloud-azure-starter-storage-queue</module>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@
*/
String prefix() default "";

/**
* The prefixes that should be applied to each property. The prefixes automatically ends
* with a dot if not specified. A valid prefix is defined by one or more words
* separated with dots (e.g. {@code "spring.cloud.azure"}).
* @return the prefix array
*/
String[] prefixes() default {};

/**
* The name of the properties to test. If a prefix has been defined, it is applied to
* compute the full key of each property. For instance if the prefix is {@code "spring.cloud.azure"}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

class OnAnyPropertyCondition extends PropertyCondition {

Expand Down Expand Up @@ -50,7 +54,7 @@ protected ConditionOutcome determineOutcome(AnnotationAttributes annotationAttri

private static class Spec {

private final String prefix;
private final Set<String> prefixes;

private final String havingValue;

Expand All @@ -59,8 +63,7 @@ private static class Spec {
private final boolean matchIfMissing;

Spec(AnnotationAttributes annotationAttributes) {
String prefixAttr = annotationAttributes.getString("prefix");
prefix = AzureStringUtils.ensureEndsWithSuffix(prefixAttr.trim(), PROPERTY_SUFFIX);
this.prefixes = getPrefixes(annotationAttributes);
saragluna marked this conversation as resolved.
Show resolved Hide resolved
this.havingValue = annotationAttributes.getString("havingValue");
this.names = getNames(annotationAttributes);
this.matchIfMissing = annotationAttributes.getBoolean("matchIfMissing");
Expand All @@ -76,21 +79,36 @@ private String[] getNames(Map<String, Object> annotationAttributes) {
return (value.length > 0) ? value : name;
}

private Set<String> getPrefixes(AnnotationAttributes annotationAttributes) {
Set<String> prefixSet = new HashSet<>();
prefixSet.add(annotationAttributes.getString("prefix"));
prefixSet.addAll(Arrays.asList(annotationAttributes.getStringArray("prefixes")));
return prefixSet.stream()
.filter(item -> !item.isEmpty())
.map(p -> AzureStringUtils.ensureEndsWithSuffix(p.trim(), PROPERTY_SUFFIX))
.collect(Collectors.toSet());
}

private void collectProperties(PropertyResolver resolver, List<String> missing, List<String> nonMatching,
List<String> matching) {
for (String name : this.names) {
String key = this.prefix + name;
if (resolver.containsProperty(key)) {
if (!isMatch(resolver.getProperty(key), this.havingValue)) {
nonMatching.add(name);
} else {
matching.add(name);
}
} else {
if (!this.matchIfMissing) {
missing.add(name);
if (this.prefixes.isEmpty()) {
this.prefixes.add("");
}
for (String prefix : this.prefixes) {
for (String name : this.names) {
String key = prefix + name;
if (resolver.containsProperty(key)) {
if (!isMatch(resolver.getProperty(key), this.havingValue)) {
nonMatching.add(name);
} else {
matching.add(name);
}
} else {
matching.add(name);
if (!this.matchIfMissing) {
missing.add(name);
} else {
matching.add(name);
}
}
}
}
Expand All @@ -107,7 +125,15 @@ private boolean isMatch(String value, String requiredValue) {
public String toString() {
StringBuilder result = new StringBuilder();
result.append("(");
result.append(this.prefix);
if (this.prefixes.size() > 0) {
if (this.prefixes.size() == 1) {
result.append(this.prefixes.iterator().next());
} else {
result.append("[");
result.append(StringUtils.collectionToCommaDelimitedString(this.prefixes));
result.append("]");
}
}
if (this.names.length == 1) {
result.append(this.names[0]);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import org.springframework.beans.BeanUtils;

/**
* Util class for processor {@link AzureGlobalProperties}.
* Util class for processing {@link AzureGlobalProperties}.
*/
public final class AzureGlobalPropertiesUtils {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.spring.cloud.autoconfigure.implementation.properties.utils;

import com.azure.spring.cloud.autoconfigure.implementation.storage.common.AzureStorageProperties;
import com.azure.spring.cloud.core.implementation.util.AzurePropertiesUtils;
import com.azure.spring.cloud.core.properties.AzureProperties;

/**
* Util class for processing Azure Service properties.
*/
public final class AzureServicePropertiesUtils {

public AzureServicePropertiesUtils() {
}

/**
* Load the default value to an Azure Service properties from the Azure Storage properties.
*
* @param source The Azure Storage properties.
* @param target The properties of an Azure Service, such as Storage Blob properties. Some common components of the
* service's properties have default value as set to the Azure properties. For example, the proxy of
* the Storage Blob properties takes the proxy set to the Azure properties as default.
* @param <T> The type of the properties of an Azure Service.
* @return The Azure Service's properties.
*/
public static <T extends AzureProperties> T loadStorageProperties(AzureStorageProperties source, T target) {
AzurePropertiesUtils.copyAzureCommonPropertiesIgnoreNull(source, target);
AzurePropertiesUtils.copyPropertiesIgnoreNull(source, target);
return target;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
*/
public class AzureStorageProperties extends AbstractAzureServiceConfigurationProperties implements StorageProperties {

public static final String PREFIX = "spring.cloud.azure.storage";

/**
* Endpoint for Azure Storage service.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.spring.cloud.autoconfigure.storage;

import com.azure.spring.cloud.autoconfigure.AzureServiceConfigurationBase;
import com.azure.spring.cloud.autoconfigure.context.AzureGlobalProperties;
import com.azure.spring.cloud.autoconfigure.implementation.storage.common.AzureStorageProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* Common configuration for Azure Storage support.
*
* @since 4.3.0
*/
@Configuration
public class AzureStorageConfiguration extends AzureServiceConfigurationBase {

AzureStorageConfiguration(AzureGlobalProperties azureGlobalProperties) {
super(azureGlobalProperties);
}

@Bean
@ConfigurationProperties(AzureStorageProperties.PREFIX)
AzureStorageProperties azureStorageProperties() {
return loadProperties(getAzureGlobalProperties(), new AzureStorageProperties());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@

package com.azure.spring.cloud.autoconfigure.storage.blob;

import com.azure.spring.cloud.autoconfigure.AzureServiceConfigurationBase;
import com.azure.spring.cloud.autoconfigure.condition.ConditionalOnAnyProperty;
import com.azure.spring.cloud.autoconfigure.context.AzureGlobalProperties;
import com.azure.spring.cloud.autoconfigure.implementation.properties.utils.AzureServicePropertiesUtils;
import com.azure.spring.cloud.autoconfigure.implementation.storage.blob.properties.AzureStorageBlobProperties;
import com.azure.spring.cloud.autoconfigure.implementation.storage.common.AzureStorageProperties;
import com.azure.spring.cloud.autoconfigure.storage.AzureStorageConfiguration;
import com.azure.spring.cloud.core.implementation.util.AzureSpringIdentifier;
import com.azure.spring.cloud.core.provider.connectionstring.ServiceConnectionStringProvider;
import com.azure.spring.cloud.core.provider.connectionstring.StaticConnectionStringProvider;
Expand All @@ -27,7 +28,10 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

import static com.azure.spring.cloud.autoconfigure.context.AzureContextUtils.STORAGE_BLOB_CLIENT_BUILDER_BEAN_NAME;
import static com.azure.spring.cloud.autoconfigure.context.AzureContextUtils.STORAGE_BLOB_CLIENT_BUILDER_FACTORY_BEAN_NAME;
Expand All @@ -37,19 +41,20 @@
*
* @since 4.0.0
*/
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties
@ConditionalOnClass(BlobServiceClientBuilder.class)
@ConditionalOnProperty(value = "spring.cloud.azure.storage.blob.enabled", havingValue = "true", matchIfMissing = true)
@ConditionalOnAnyProperty(prefix = "spring.cloud.azure.storage.blob", name = { "account-name", "endpoint", "connection-string" })
public class AzureStorageBlobAutoConfiguration extends AzureServiceConfigurationBase {

AzureStorageBlobAutoConfiguration(AzureGlobalProperties azureGlobalProperties) {
super(azureGlobalProperties);
}
@ConditionalOnAnyProperty(
prefixes = { "spring.cloud.azure.storage.blob", "spring.cloud.azure.storage" },
name = { "account-name", "endpoint", "connection-string" })
@Import(AzureStorageConfiguration.class)
public class AzureStorageBlobAutoConfiguration {

@Bean
@ConfigurationProperties(AzureStorageBlobProperties.PREFIX)
AzureStorageBlobProperties azureStorageBlobProperties() {
return loadProperties(getAzureGlobalProperties(), new AzureStorageBlobProperties());
AzureStorageBlobProperties azureStorageBlobProperties(AzureStorageProperties azureStorageProperties) {
return AzureServicePropertiesUtils.loadStorageProperties(azureStorageProperties, new AzureStorageBlobProperties());
}

@Bean
Expand Down Expand Up @@ -130,7 +135,7 @@ BlobServiceClientBuilder blobServiceClientBuilder(@Qualifier(STORAGE_BLOB_CLIENT
}

@Bean
@ConditionalOnProperty("spring.cloud.azure.storage.blob.connection-string")
@ConditionalOnAnyProperty(prefixes = { AzureStorageBlobProperties.PREFIX, AzureStorageProperties.PREFIX }, name = { "connection-string" })
StaticConnectionStringProvider<AzureServiceType.StorageBlob> staticStorageBlobConnectionStringProvider(
AzureStorageBlobProperties properties) {
return new StaticConnectionStringProvider<>(AzureServiceType.STORAGE_BLOB, properties.getConnectionString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/
@ConditionalOnClass({ AzureStorageBlobProtocolResolver.class })
@ConditionalOnProperty(value = "spring.cloud.azure.storage.blob.enabled", havingValue = "true", matchIfMissing = true)
@ConditionalOnAnyProperty(prefix = "spring.cloud.azure.storage.blob", name = { "account-name", "endpoint", "connection-string" })
@ConditionalOnAnyProperty(prefixes = { "spring.cloud.azure.storage.blob", "spring.cloud.azure.storage" }, name = { "account-name", "endpoint", "connection-string" })
public class AzureStorageBlobResourceAutoConfiguration {

/**
Expand Down
Loading