Skip to content

Commit

Permalink
Fix Spring integration tests for sovereign clouds (#30534)
Browse files Browse the repository at this point in the history
* use AZURE_AUTHORITY_HOST env instead
* change to use data owner role
* enable cosmos tests
* try another region chinanorth3
* remove default amqp transport type
* refactor profile
* update changelog

Co-authored-by: Muyao <[email protected]>
Co-authored-by: Muyao <[email protected]>
  • Loading branch information
3 people authored Sep 20, 2022
1 parent 7adb8d1 commit 250c73d
Show file tree
Hide file tree
Showing 58 changed files with 1,117 additions and 184 deletions.
13 changes: 8 additions & 5 deletions sdk/spring/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,25 @@ This section includes changes in `spring-cloud-azure-autoconfigure` module.
#### Bugs Fixed
- Fix bug: Cannot configure "azure" authorization client. [#30354](https://github.com/Azure/azure-sdk-for-java/issues/30354).
- Fix parameter `requested_token_use` missing when using On behalf of process [#30359](https://github.com/Azure/azure-sdk-for-java/issues/30359).
- Fix Kafka `OAuth2AuthenticateCallbackHandler` cannot work with Kafka refreshing login mechanism [#30719](https://github.com/Azure/azure-sdk-for-java/issues/30719).
- Fix the cloud type cannot be configured for a consumer/producer/processor of Service Bus / Event Hubs bug [#30936](https://github.com/Azure/azure-sdk-for-java/issues/30936).

#### Features Added
- Support auto start-up for the auto-configured Service Bus Processor Client by enabling a new property of `spring.cloud.azure.servicebus.processor.auto-startup`. [#29997](https://github.com/Azure/azure-sdk-for-java/issues/29997)
- Configure the `spring.main.sources` with `AzureKafkaSpringCloudStreamConfiguration` class for Spring Cloud Stream Kafka Binder context, which helps developers omit customizing the property manually when leveraging Azure Identity with Kafka [#29976](https://github.com/Azure/azure-sdk-for-java/issues/29976).
- Provide the property of `spring.cloud.azure.eventhubs.kafka.enabled` to turn of/off the OAuth2 support of Spring Cloud Azure for Event Hubs for Kafka [#30574](https://github.com/Azure/azure-sdk-for-java/issues/30574).
- Support connecting to Azure AD via proxy. To achieve this, customer need provide a custom `RestTemplateCustomizer` bean. [#26493](https://github.com/Azure/azure-sdk-for-java/issues/26493).

### Spring Cloud Azure Resource Manager
### Spring Cloud Stream Event Hubs Binder
#### Bugs Fixed
- Fix the cloud type cannot be configured for Event Hubs Binder bug [#30936](https://github.com/Azure/azure-sdk-for-java/issues/30936).

### Spring Cloud Stream Service Bus Binder
#### Bugs Fixed
- Fix the Service Bus stream binder cannot automatically create Topic/Subscriptions from consumer. [#30722](https://github.com/Azure/azure-sdk-for-java/pull/30722).
- Fix the Service Bus Binder cannot automatically create Topic/Subscriptions from consumer bug. [#30722](https://github.com/Azure/azure-sdk-for-java/pull/30722).
- Fix the cloud type cannot be configured for Service Bus Binder bug [#30936](https://github.com/Azure/azure-sdk-for-java/issues/30936).

### Spring Cloud Azure Service

#### Bugs Fixed
- Fix Kafka OAuth2AuthenticateCallbackHandler cannot work with Kafka refreshing login mechanism [#30719](https://github.com/Azure/azure-sdk-for-java/issues/30719).

## 4.3.0 (2022-06-29)
- This release is compatible with Spring Boot 2.5.0-2.5.14, 2.6.0-2.6.9, 2.7.0-2.7.1. (Note: 2.5.x (x>14), 2.6.y (y>9) and 2.7.z (z>1) should be supported, but they aren't tested with this release.)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
import com.azure.spring.cloud.autoconfigure.properties.core.profile.AzureProfileConfigurationProperties;
import com.azure.spring.cloud.autoconfigure.properties.core.proxy.ProxyConfigurationProperties;
import com.azure.spring.cloud.autoconfigure.properties.core.retry.RetryConfigurationProperties;
import com.azure.spring.cloud.core.provider.RetryOptionsProvider;
import com.azure.spring.cloud.core.properties.AzureProperties;
import com.azure.spring.cloud.core.properties.client.HeaderProperties;
import com.azure.spring.cloud.core.provider.RetryOptionsProvider;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;

Expand Down Expand Up @@ -44,7 +44,7 @@ public class AzureGlobalProperties implements AzureProperties, RetryOptionsProvi
private final TokenCredentialConfigurationProperties credential = new TokenCredentialConfigurationProperties();

@NestedConfigurationProperty
private final AzureProfileConfigurationProperties profile = new AzureProfileConfigurationProperties();
private final GlobalProfileConfigurationProperties profile = new GlobalProfileConfigurationProperties();

@Override
public GlobalClientConfigurationProperties getClient() {
Expand Down Expand Up @@ -422,4 +422,19 @@ public void setTransportType(AmqpTransportType transportType) {
this.transportType = transportType;
}
}

/**
* Global profile properties. This global profile properties will have a default cloud type of Azure.
*/
public static class GlobalProfileConfigurationProperties extends AzureProfileConfigurationProperties {

/**
* Construct a default {@link GlobalProfileConfigurationProperties} with default cloud type Azure.
*/
public GlobalProfileConfigurationProperties() {
setCloudType(CloudType.AZURE);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -251,4 +251,8 @@ public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
static class IdentityClientProperties extends AbstractAzureHttpConfigurationProperties {

}

IdentityClientProperties getIdentityClientProperties() {
return identityClientProperties;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@
import com.azure.messaging.eventhubs.EventHubClientBuilder;
import com.azure.messaging.eventhubs.checkpointstore.blob.BlobCheckpointStore;
import com.azure.spring.cloud.autoconfigure.implementation.eventhubs.properties.AzureEventHubsProperties;
import com.azure.spring.cloud.core.implementation.util.AzureSpringIdentifier;
import com.azure.spring.cloud.core.customizer.AzureServiceClientBuilderCustomizer;
import com.azure.spring.cloud.core.implementation.util.AzureSpringIdentifier;
import com.azure.spring.cloud.service.implementation.storage.blob.BlobServiceClientBuilderFactory;
import com.azure.storage.blob.BlobContainerAsyncClient;
import com.azure.storage.blob.BlobServiceClientBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
Expand All @@ -26,7 +25,6 @@

import static com.azure.spring.cloud.autoconfigure.context.AzureContextUtils.EVENT_HUB_PROCESSOR_CHECKPOINT_STORE_STORAGE_CLIENT_BUILDER_BEAN_NAME;
import static com.azure.spring.cloud.autoconfigure.context.AzureContextUtils.EVENT_HUB_PROCESSOR_CHECKPOINT_STORE_STORAGE_CLIENT_BUILDER_FACTORY_BEAN_NAME;
import static com.azure.spring.cloud.core.implementation.util.AzurePropertiesUtils.mergeAzureCommonProperties;

/**
* Configures a {@link BlobCheckpointStore}
Expand Down Expand Up @@ -83,25 +81,11 @@ BlobServiceClientBuilderFactory eventHubProcessorBlobServiceClientBuilderFactory
AzureEventHubsProperties eventHubsProperties,
ObjectProvider<AzureServiceClientBuilderCustomizer<BlobServiceClientBuilder>> customizers) {
BlobServiceClientBuilderFactory factory =
new BlobServiceClientBuilderFactory(getCheckpointStoreProperties(eventHubsProperties));
new BlobServiceClientBuilderFactory(eventHubsProperties.buildProcessorProperties().getCheckpointStore());

factory.setSpringIdentifier(AzureSpringIdentifier.AZURE_SPRING_EVENT_HUBS);
customizers.orderedStream().forEach(factory::addBuilderCustomizer);
return factory;
}

private AzureEventHubsProperties.Processor.BlobCheckpointStore getCheckpointStoreProperties(
AzureEventHubsProperties ehProperties) {

AzureEventHubsProperties.Processor.BlobCheckpointStore result = new AzureEventHubsProperties.Processor
.BlobCheckpointStore();
AzureEventHubsProperties.Processor.BlobCheckpointStore csProperties = ehProperties.getProcessor()
.getCheckpointStore();

mergeAzureCommonProperties(ehProperties, csProperties, result);
BeanUtils.copyProperties(csProperties, result);

return result;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public abstract class AzureEventHubsCommonProperties extends AbstractAzureAmqpCo
/**
* The domain name of an Event Hub namespace.
*/
private String domainName = "servicebus.windows.net";
private String domainName;
/**
* The namespace of an event hub, which is the prefix of the FQDN. A FQDN should be composed of &lt;NamespaceName&gt;.&lt;DomainName&gt;
*/
Expand Down Expand Up @@ -54,7 +54,14 @@ protected String extractEventHubNameFromConnectionString() {
// Endpoint=sb://<FQDN>/;SharedAccessKeyName=<KeyName>;SharedAccessKey=<KeyValue>
// https://docs.microsoft.com/azure/event-hubs/event-hubs-get-connection-string
public String getFullyQualifiedNamespace() {
return this.namespace == null ? extractFqdnFromConnectionString() : (this.namespace + "." + domainName);
return this.namespace == null ? extractFqdnFromConnectionString() : buildFqdnFromNamespace();
}

private String buildFqdnFromNamespace() {
if (namespace == null || domainName == null) {
return null;
}
return this.namespace + "." + domainName;
}

public String getDomainName() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public class AzureEventHubsProperties extends AzureEventHubsCommonProperties
implements EventHubsNamespaceProperties, InitializingBean {

public static final String PREFIX = "spring.cloud.azure.eventhubs";
private static final String DEFAULT_DOMAIN_NAME = "servicebus.windows.net";
private static final Logger LOGGER = LoggerFactory.getLogger(AzureEventHubsProperties.class);

/**
Expand All @@ -43,6 +44,10 @@ public class AzureEventHubsProperties extends AzureEventHubsCommonProperties
private final Consumer consumer = new Consumer();
private final Processor processor = new Processor();

public AzureEventHubsProperties() {
this.setDomainName(DEFAULT_DOMAIN_NAME);
}

public Producer buildProducerProperties() {
PropertyMapper propertyMapper = PropertyMapper.get().alwaysApplyingWhenNonNull();

Expand Down Expand Up @@ -121,7 +126,7 @@ public Processor buildProcessorProperties() {
propertyMapper.from(this.processor.loadBalancing.getStrategy()).to(properties.loadBalancing::setStrategy);
propertyMapper.from(this.processor.loadBalancing.getUpdateInterval()).to(properties.loadBalancing::setUpdateInterval);

AzurePropertiesUtils.copyAzureCommonProperties(this.processor.checkpointStore, properties.checkpointStore);
AzurePropertiesUtils.mergeAzureCommonProperties(properties, this.processor.getCheckpointStore(), properties.checkpointStore);
BeanUtils.copyProperties(this.processor.checkpointStore, properties.checkpointStore);

return properties;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class AmqpClientConfigurationProperties extends ClientConfigurationProper
/**
* Transport type for AMQP-based client.
*/
private AmqpTransportType transportType = AmqpTransportType.AMQP;
private AmqpTransportType transportType;

@Override
public AmqpTransportType getTransportType() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@
/**
*
*/
public abstract class AzureServiceBusCommonProperties extends AbstractAzureAmqpConfigurationProperties {
abstract class AzureServiceBusCommonProperties extends AbstractAzureAmqpConfigurationProperties {

// https://help.boomi.com/bundle/connectors/page/r-atm-Microsoft_Azure_Service_Bus_connection.html
// https://docs.microsoft.com/rest/api/servicebus/addressing-and-protocol
/**
* The domain name of a Service Bus namespace.
*/
private String domainName = "servicebus.windows.net";
private String domainName;
/**
* The namespace of a service bus, which is the prefix of the FQDN. A FQDN should be composed of &lt;NamespaceName&gt;.&lt;DomainName&gt;
*/
Expand All @@ -43,7 +43,14 @@ private String extractFqdnFromConnectionString() {
}

public String getFullyQualifiedNamespace() {
return this.namespace == null ? extractFqdnFromConnectionString() : (this.namespace + "." + domainName);
return this.namespace == null ? extractFqdnFromConnectionString() : buildFqdnFromNamespace();
}

private String buildFqdnFromNamespace() {
if (namespace == null || domainName == null) {
return null;
}
return this.namespace + "." + domainName;
}

public String getDomainName() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class AzureServiceBusProperties extends AzureServiceBusCommonProperties
implements ServiceBusNamespaceProperties, InitializingBean {

public static final String PREFIX = "spring.cloud.azure.servicebus";
private static final String DEFAULT_DOMAIN_NAME = "servicebus.windows.net";
private static final Logger LOGGER = LoggerFactory.getLogger(AzureServiceBusProperties.class);
/**
* Whether to enable cross entity transaction on the connection to Service bus.
Expand All @@ -36,6 +37,10 @@ public class AzureServiceBusProperties extends AzureServiceBusCommonProperties
private final Consumer consumer = new Consumer();
private final Processor processor = new Processor();

public AzureServiceBusProperties() {
this.setDomainName(DEFAULT_DOMAIN_NAME);
}

public Boolean getCrossEntityTransactions() {
return crossEntityTransactions;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ public String getEndpoint() {
}

private String buildEndpointFromAccountName() {
if (accountName == null || profile.getCloudType() == null) {
return null;
}
return String.format(BLOB_ENDPOINT_PATTERN, accountName, profile.getEnvironment().getStorageEndpointSuffix());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ public class AzureProfileConfigurationProperties extends AzureProfileOptionsAdap
/**
* Name of the Azure cloud to connect to.
*/
private AzureProfileOptionsProvider.CloudType cloudType = AzureProfileOptionsProvider.CloudType.AZURE;
private AzureProfileOptionsProvider.CloudType cloudType;

private final AzureEnvironmentConfigurationProperties environment = new AzureEnvironmentConfigurationProperties(AzureEnvironment.AZURE);
private final AzureEnvironmentConfigurationProperties environment = new AzureEnvironmentConfigurationProperties(null);

@Override
public AzureProfileOptionsProvider.CloudType getCloudType() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import com.azure.core.amqp.AmqpTransportType;
import com.azure.core.http.policy.HttpLogDetailLevel;
import com.azure.core.management.AzureEnvironment;
import com.azure.cosmos.CosmosClientBuilder;
import com.azure.security.keyvault.secrets.SecretClientBuilder;
import com.azure.spring.cloud.autoconfigure.context.AzureGlobalProperties;
Expand All @@ -29,6 +30,7 @@

import static com.azure.spring.cloud.core.provider.AzureProfileOptionsProvider.CloudType.AZURE;
import static com.azure.spring.cloud.core.provider.AzureProfileOptionsProvider.CloudType.AZURE_CHINA;
import static com.azure.spring.cloud.core.provider.AzureProfileOptionsProvider.CloudType.AZURE_US_GOVERNMENT;
import static com.azure.spring.cloud.core.provider.AzureProfileOptionsProvider.CloudType.OTHER;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
Expand Down Expand Up @@ -291,5 +293,59 @@ void configureGlobalShouldApplyToHttpAzureKeyVaultSecretProperties() {
});
}

@Test
void configureGlobalCloudShouldApplyToAzureKeyVaultSecretProperties() {
AzureGlobalProperties azureProperties = new AzureGlobalProperties();
azureProperties.getProfile().setCloudType(AZURE_US_GOVERNMENT);

this.contextRunner
.withBean(AzureGlobalProperties.class, () -> azureProperties)
.withBean(SecretClientBuilder.class, () -> mock(SecretClientBuilder.class))
.withPropertyValues(
"spring.cloud.azure.keyvault.secret.endpoint=test"
)
.run(context -> {
assertThat(context).hasSingleBean(AzureKeyVaultSecretProperties.class);
final AzureKeyVaultSecretProperties properties = context.getBean(AzureKeyVaultSecretProperties.class);
assertThat(properties).extracting("profile.cloudType").isEqualTo(AZURE_US_GOVERNMENT);
assertThat(properties).extracting("profile.environment.activeDirectoryEndpoint").isEqualTo(AzureEnvironment.AZURE_US_GOVERNMENT.getActiveDirectoryEndpoint());
});
}

@Test
void configureGlobalCloudShouldApplyToAzureEventHubsProperties() {
AzureGlobalProperties azureProperties = new AzureGlobalProperties();
azureProperties.getProfile().setCloudType(AZURE_US_GOVERNMENT);

this.contextRunner
.withBean(AzureGlobalProperties.class, () -> azureProperties)
.withPropertyValues(
"spring.cloud.azure.eventhubs.namespace=test-namespace"
)
.run(context -> {
assertThat(context).hasSingleBean(AzureEventHubsProperties.class);
final AzureEventHubsProperties properties = context.getBean(AzureEventHubsProperties.class);
assertThat(properties).extracting("profile.cloudType").isEqualTo(AZURE_US_GOVERNMENT);
assertThat(properties).extracting("profile.environment.activeDirectoryEndpoint").isEqualTo(AzureEnvironment.AZURE_US_GOVERNMENT.getActiveDirectoryEndpoint());
});
}

@Test
void globalDefaultShouldNotApplyWhenServiceSpecifyCloudType() {
AzureGlobalProperties azureProperties = new AzureGlobalProperties();

this.contextRunner
.withBean(AzureGlobalProperties.class, () -> azureProperties)
.withPropertyValues(
"spring.cloud.azure.eventhubs.namespace=test-namespace",
"spring.cloud.azure.eventhubs.profile.cloud-type=AZURE_US_GOVERNMENT"
)
.run(context -> {
assertThat(context).hasSingleBean(AzureEventHubsProperties.class);
final AzureEventHubsProperties properties = context.getBean(AzureEventHubsProperties.class);
assertThat(properties).extracting("profile.cloudType").isEqualTo(AZURE_US_GOVERNMENT);
assertThat(properties).extracting("profile.environment.activeDirectoryEndpoint").isEqualTo(AzureEnvironment.AZURE_US_GOVERNMENT.getActiveDirectoryEndpoint());
});
}

}
Loading

0 comments on commit 250c73d

Please sign in to comment.