Spring Cloud Azure developer guide
This article applies to: ✔️ Version 4.5.0 ✔️ Version 5.0.0
For more information about supported versions, see Spring Versions Mapping.
Spring is an open-source application framework developed by VMware that provides a simplified, modular approach for creating Java applications. Spring Cloud Azure is an open-source project that provides seamless Spring integration with Azure.
Get help
If you have any questions about this documentation, create a GitHub issue in one of the following GitHub repositories. Pull requests are also welcome.
GitHub repositories | Description |
---|---|
Azure/azure-sdk-for-java | This repository holds the source code. |
MicrosoftDocs/azure-dev-docs | This repository holds the documentation. |
What's new in 4.0 since 3.10.x
This documentation covers changes made in 4.0 since 3.10. This major release brings better security, leaner dependencies, support for production readiness, and more.
Tip
For more information on migrating to 4.0, see Migration guide for 4.0.
The following list summarizes some of the changes that Spring Cloud Azure 4.0 provides:
- A unified development experience, with unified project name, artifact ID, and properties.
- Simplified dependency management using a single
spring-cloud-azure-dependencies
BOM. - Expanded Azure support on Spring Initializr to cover Kafka, Event Hubs, Azure Cache for Redis, and Azure App Configuration.
- Rearchitected Spring module dependencies to remove excess layers and entanglement.
- Managed Identity support for Azure App Configuration, Event Hubs, Service Bus, Azure Cosmos DB, Key Vault, Storage Blob, and Storage Queue.
- Continued support for authentication methods in the underlying Azure SDK from our Spring libraries, such as SAS token and token credential authentication with Service Bus and Event Hubs.
- Credential chain is now enabled by default, enabling applications to obtain credentials from application properties, environment variables, managed identity, IDEs, and so on.
- Granular access control at the resource level (such as Service Bus queue) to enable better security governance and adherence to IT policies.
- More options exposed in a Spring-idiomatic way through significantly improved auto-configuration coverage of Azure SDK clients for both synchronous and asynchronous scenarios.
- Added health indicators for Azure App Configuration, Event Hubs, Azure Cosmos DB, Key Vault, Storage Blob, Storage Queue, and Storage File.
- Spring Cloud Sleuth support for all HTTP-based Azure SDKs.
Migration guide for 4.0
For more information on migrating to 4.0, see Migration guide for 4.0.
Getting started
Setting up dependencies
Bill of materials (BOM)
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-dependencies</artifactId>
<version>${spring.cloud.azure.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Starter dependencies
Spring Cloud Azure Starters are a set of convenient dependency descriptors to include in your application. Each starter contains all the dependencies and transitive dependencies needed to begin using their corresponding Spring Cloud Azure module. These starters boost your Spring Boot application development with Azure services.
For example, if you want to get started using Spring and Azure Cosmos DB for data persistence, include the spring-cloud-azure-starter-cosmos
dependency in your project.
The following table lists application starters provided by Spring Cloud Azure under the com.azure.spring
group:
Name | Description |
---|---|
spring-cloud-azure-starter | The core starter, including auto-configuration support. |
spring-cloud-azure-starter-active-directory | The starter for using Azure Active Directory with Spring Security. |
spring-cloud-azure-starter-active-directory-b2c | The starter for using Azure Active Directory B2C with Spring Security. |
spring-cloud-azure-starter-appconfiguration | The starter for using Azure App Configuration. |
spring-cloud-azure-starter-cosmos | The starter for using Azure Cosmos DB. |
spring-cloud-azure-starter-eventhubs | The starter for using Azure Event Hubs. |
spring-cloud-azure-starter-keyvault | The Starter for using Azure Key Vault. |
spring-cloud-azure-starter-keyvault-secrets | The starter for using Azure Key Vault Secrets. |
spring-cloud-azure-starter-keyvault-certificates | The starter for using Azure Key Vault Certificates. |
spring-cloud-azure-starter-servicebus | The starter for using Azure Service Bus. |
spring-cloud-azure-starter-servicebus-jms | The starter for using Azure Service Bus and JMS. |
spring-cloud-azure-starter-storage | The starter for using Azure Storage. |
spring-cloud-azure-starter-storage-blob | The starter for using Azure Storage Blob. |
spring-cloud-azure-starter-storage-file-share | The starter for using Azure Storage File Share. |
spring-cloud-azure-starter-storage-queue | The starter for using Azure Storage Queue. |
spring-cloud-azure-starter-actuator | The starter for using Spring Boot’s Actuator, which provides production ready features. |
The following table lists starters for Spring Data support:
Name | Description |
---|---|
spring-cloud-azure-starter-data-cosmos | The starter for using Spring Data for Azure Cosmos DB. |
The following table lists starters for Spring Integration support:
Name | Description |
---|---|
spring-cloud-azure-starter-integration-eventhubs | The starter for using Azure Event Hubs and Spring Integration. |
spring-cloud-azure-starter-integration-servicebus | The starter for using Azure Service Bus and Spring Integration. |
spring-cloud-azure-starter-integration-storage-queue | The starter for using Azure Storage Queue and Spring Integration. |
The following table lists starters for Spring Cloud Stream support:
Name | Description |
---|---|
spring-cloud-azure-starter-stream-eventhubs | The starters for using Azure Event Hubs and Spring Cloud Stream Binder. |
spring-cloud-azure-starter-stream-servicebus | The starter for using Azure Service Bus and Spring Cloud Stream Binder. |
The following table lists starters for MySQL support:
Name | Description |
---|---|
spring-cloud-azure-starter-jdbc-mysql | The starters for using Azure MySQLs and JDBC through Azure AD authentication. |
The following table lists starters for PostgreSQL support:
Name | Description |
---|---|
spring-cloud-azure-starter-jdbc-postgresql | The starters for using Azure PostgreSQL and JDBC through Azure AD authentication. |
Learning Spring Cloud Azure
We've prepared a full list of samples to show usage. You can find these samples at Spring Cloud Azure Samples.
Spring Cloud Azure configuration
Configuration for each Azure Service SDK
Most of Azure Service SDKs can be divided into two categories by transport type: HTTP-based or AMQP-based. There are properties that are common to all SDKs, such as authentication principals and Azure environment settings, or common to HTTP-based clients, such as logging level to log HTTP requests and responses. In Spring Cloud Azure 4.0, we added five common categories of configuration properties that you can specify for each Azure service.
The following table lists properties common to multiple services:
Property | Description |
---|---|
spring.cloud.azure.azure-service.client | Configures the transport clients underneath one Azure service SDK. |
spring.cloud.azure.azure-service.credential | Configures authentication with Azure Active Directory for one Azure service SDK. |
spring.cloud.azure.azure-service.profile | Configures the Azure cloud environment for one Azure service SDK. |
spring.cloud.azure.azure-service.proxy | Configures the proxy options for one Azure service SDK. |
spring.cloud.azure.azure-service.retry | Configures the retry options applicable to one Azure service SDK. The retry options has supported part of the SDKs, there’s no spring.cloud.azure.cosmos.retry. |
The configuration properties' prefixes have been unified to the spring.cloud.azure
namespace since Spring Cloud Azure 4.0 to make configuration properties more consistent and more intuitive. The following table provides a quick review of the prefixes for supported Azure services:
Azure service | Configuration property prefix | Configuration Properties Link |
---|---|---|
Azure App Configuration | spring.cloud.azure.appconfiguration | App Configuration configuration properties |
Azure Cosmos DB | spring.cloud.azure.cosmos | Azure Cosmos DB configuration properties |
Azure Event Hubs | spring.cloud.azure.eventhubs | Event Hubs configuration properties |
Azure Key Vault Certificate | spring.cloud.azure.keyvault.certificate | Key Vault Certificates configuration properties |
Azure Key Vault Secret | spring.cloud.azure.keyvault.secret | Key Vault Secrets configuration properties |
Azure Service Bus | spring.cloud.azure.servicebus | Service Bus configuration properties |
Azure Storage Blob | spring.cloud.azure.storage.blob | Storage Blob configuration properties |
Azure Storage File Share | spring.cloud.azure.storage.fileshare | Storage File Share configuration properties |
Azure Storage Queue | spring.cloud.azure.storage.queue | Storage Queue configuration properties |
Global configuration for Azure Service SDKs
There are some properties that you can share among different Azure services, for example to use the same service principal to access Azure Cosmos DB and Azure Event Hubs. Spring Cloud Azure 4.0 enables you to define properties that apply to all Azure SDKs in the namespace spring.cloud.azure
.
The following table lists global properties:
Property | Description |
---|---|
spring.cloud.azure.client | Configures the transport clients; applies to all Azure SDKs by default. |
spring.cloud.azure.credential | Configures authentication with Azure Active Directory for all Azure SDKs by default. |
spring.cloud.azure.profile | Configures the Azure cloud environment for all Azure SDKs by default. |
spring.cloud.azure.proxy | Configures the proxy options applicable to all Azure SDK clients by default. |
spring.cloud.azure.retry | Configures the retry options applicable to all Azure SDK clients by default. |
Note
Properties configured under each Azure service will override the global configurations.
Configuration examples
Global retry configuration for Azure Service SDKs
The following example shows you how to configure the retry behavior for any HTTP or AMQP protocol based Azure SDK client:
spring.cloud.azure:
retry:
mode: exponential
exponential:
max-retries: 4
base-delay: PT0.0801S
max-delay: PT9S
Retry configuration for Key Vault property source
The following configuration example shows you how to configure the retry behavior for the Azure Key Vault Secret client:
spring.cloud.azure:
keyvault:
secret:
property-source-enabled: true
property-sources:
- endpoint: <your-Azure-Key-Vault-endpoint>
retry:
mode: exponential
exponential:
max-retries: 4
base-delay: PT0.0801S
max-delay: PT9S
Spring Cloud Azure authentication
DefaultAzureCredential
The DefaultAzureCredential
is appropriate for most scenarios where the application is intended to be run in the Azure Cloud. This is because the DefaultAzureCredential
combines credentials commonly used to authenticate when deployed with credentials used to authenticate in a development environment.
Note
DefaultAzureCredential
is intended to simplify getting started with the SDK by handling common scenarios with reasonable default behaviors. If you want more control or your scenario isn't served by the default settings, you should use other credential types.
The DefaultAzureCredential
will attempt to authenticate via the following mechanisms in order:
- Environment - The
DefaultAzureCredential
will read account information specified via environment variables and use it to authenticate. - Managed Identity - If the application is deployed to an Azure host with Managed Identity enabled, the
DefaultAzureCredential
will authenticate with that account. - IntelliJ - If you've authenticated via Azure Toolkit for IntelliJ, the
DefaultAzureCredential
will authenticate with that account. - Visual Studio Code - If you've authenticated via the Visual Studio Code Azure Account plugin, the
DefaultAzureCredential
will authenticate with that account. - Azure CLI - If you've authenticated an account via the Azure CLI
az login
command, theDefaultAzureCredential
will authenticate with that account.
Tip
Be sure the security principal has been granted sufficient permission to access the Azure resource. For more information, see Authorize access with Azure Active Directory.
Note
Since Spring Cloud Azure AutoConfigure 4.1.0, a ThreadPoolTaskExecutor
bean named springCloudAzureCredentialTaskExecutor
will be automatically registered by default and will manage all threads created by Azure Identity. The name of each thread managed by this thread pool is prefixed with az-identity-
. This ThreadPoolTaskExecutor
bean is independent of the Executor
bean provided by Spring Boot.
Managed identities
A common challenge is the management of secrets and credentials used to secure communication between different components making up a solution. Managed identities eliminate the need to manage credentials. Managed identities provide an identity for applications to use when connecting to resources that support Azure Active Directory (Azure AD) authentication. Applications may use the managed identity to obtain Azure AD tokens. For example, an application may use a managed identity to access resources like Azure Key Vault where you can store credentials in a secure manner or to access storage accounts.
We encourage using managed identity instead of using connection string or key in your application because it's more secure and will save the trouble of managing secrets and credentials. In this case, DefaultAzureCredential
could better serve the scenario of developing locally using account information stored locally, then deploying the application to Azure Cloud and using managed identity.
Managed identity types
There are two types of managed identities:
- System-assigned - Some Azure services allow you to enable a managed identity directly on a service instance. When you enable a system-assigned managed identity, an identity is created in Azure AD that's tied to the lifecycle of that service instance. So when the resource is deleted, Azure automatically deletes the identity for you. By design, only that Azure resource can use this identity to request tokens from Azure AD.
- User-assigned - You may also create a managed identity as a standalone Azure resource. You can create a user-assigned managed identity and assign it to one or more instances of an Azure service. With user-assigned managed identities, the identity is managed separately from the resources that use it.
Note
When using a user-assigned managed identity, you can specify the client ID via spring.cloud.azure.credential.managed-identity-client-id
or spring.cloud.azure.<azure-service>.credential.managed-identity-client-id
. You don't need credential configuration if you use a system-assigned managed identity.
Tip
Be sure the security principal has been granted sufficient permission to access the Azure resource. For more information, see Authorize access with Azure Active Directory.
For more information about managed identity, see What are managed identities for Azure resources?.
Other credential types
If you want more control, or your scenario isn't served by the DefaultAzureCredential
or the default settings, you should use other credential types.
Authentication and authorization with Azure Active Directory
With Azure AD, you can use Azure role-based access control (Azure RBAC) to grant permissions to a security principal, which may be a user or an application service principal. When a security principal (a user or an application) attempts to access an Azure resource, for example an Event Hubs resource, the request must be authorized. With Azure AD, access to a resource is a two-step process:
- First, the security principal's identity is authenticated, and an OAuth 2.0 token is returned.
- Next, the token is passed as part of a request to the Azure service to authorize access to the specified resource.
Authenticate with Azure Active Directory
To connect applications to resources that support Azure Active Directory (Azure AD) authentication, you can set the following configurations with the prefix spring.cloud.azure.credential
or spring.cloud.azure.<azure-service>.credential
The following table lists authentication properties:
Property | Description |
---|---|
client-id | The client ID to use when performing service principal authentication with Azure. |
client-secret | The client secret to use when performing service principal authentication with Azure. |
client-certificate-path | Path of a PEM certificate file to use when performing service principal authentication with Azure. |
client-certificate-password | The password of the certificate file. |
username | The username to use when performing username/password authentication with Azure. |
password | The password to use when performing username/password authentication with Azure. |
managed-identity-enabled | Whether to enable managed identity. |
Tip
For the list of all Spring Cloud Azure configuration properties, see Spring Cloud Azure configuration properties.
The application will look in several places to find an available credential, and will use DefaultAzureCredential
if no credential properties are configured. If you want to use specific credential, see the following examples for guidance.
The following example shows you how to authenticate using a system-assigned managed identity:
spring.cloud.azure:
credential:
managed-identity-enabled: true
The following example shows you how to authenticate using a user-assigned managed identity:
spring.cloud.azure:
credential:
managed-identity-enabled: true
client-id: ${AZURE_CLIENT_ID}
The following example shows you how to authenticate using a service principal with a client secret:
spring.cloud.azure:
credential:
client-id: ${AZURE_CLIENT_ID}
client-secret: ${AZURE_CLIENT_SECRET}
profile:
tenant-id: ${AZURE_TENANT_ID}
The following example shows you how to authenticate using a service principal with a client PFX certificate:
spring.cloud.azure:
credential:
client-id: ${AZURE_CLIENT_ID}
client-certificate-path: ${AZURE_CLIENT_CERTIFICATE_PATH}
client-certificate-password: ${AZURE_CLIENT_CERTIFICATE_PASSWORD}
profile:
tenant-id: ${AZURE_TENANT_ID}
The following example shows you how to authenticate using a service principal with client PEM certificate:
spring.cloud.azure:
credential:
client-id: ${AZURE_CLIENT_ID}
client-certificate-path: ${AZURE_CLIENT_CERTIFICATE_PATH}
profile:
tenant-id: ${AZURE_TENANT_ID}
The following example shows you how to authenticate using a user credential:
spring.cloud.azure:
credential:
client-id: ${AZURE_CLIENT_ID}
username: ${AZURE_USER_USERNAME}
password: ${AZURE_USER_PASSWORD}
The following example shows you how to authenticate with Key Vault using a different service principal. This example configures the application with two credentials: one system-assigned managed identity and one service principal. The Key Vault Secret client will use the service principal, but any other components will use managed identity instead.
spring.cloud.azure:
credential:
managed-identity-enabled: true
keyvault.secret:
credential:
client-id: ${AZURE_CLIENT_ID}
client-secret: ${AZURE_CLIENT_SECRET}
profile:
tenant-id: ${AZURE_TENANT_ID}
Authorize access with Azure Active Directory
The authorization step requires that one or more Azure roles be assigned to the security principal. The roles that are assigned to a security principal determine the permissions that the principal will have.
Tip
For the list of all Azure built-in roles, see Azure built-in roles.
The following table lists the Azure built-in roles for authorizing access to Azure services supported in Spring Cloud Azure:
Role | Description |
---|---|
App Configuration Data Owner | Allows full access to App Configuration data. |
App Configuration Data Reader | Allows read access to App Configuration data. |
Azure Event Hubs Data Owner | Allows full access to Azure Event Hubs resources. |
Azure Event Hubs Data Receiver | Allows receive access to Azure Event Hubs resources. |
Azure Event Hubs Data Sender | Allows send access to Azure Event Hubs resources. |
Azure Service Bus Data Owner | Allows full access to Azure Service Bus resources. |
Azure Service Bus Data Receiver | Allows receive access to Azure Service Bus resources. |
Azure Service Bus Data Sender | Allows send access to Azure Service Bus resources. |
Storage Blob Data Owner | Provides full access to Azure Storage blob containers and data, including assigning POSIX access control. |
Storage Blob Data Reader | Read and list Azure Storage containers and blobs. |
Storage Queue Data Reader | Read and list Azure Storage queues and queue messages. |
Redis Cache Contributor | Manage Redis caches. |
Note
When using Spring Cloud Azure Resource Manager to get the connection strings for Event Hubs, Service Bus, and Storage Queue, or the properties of Cache for Redis, assign the Azure built-in role Contributor
. Azure Cache for Redis is special, and you can also assign the Redis Cache Contributor
role to get the Redis properties.
Note
A Key Vault access policy determines whether a given security principal, namely a user, application or user group, can perform different operations on Key Vault secrets, keys, and certificates. You can assign access policies using the Azure portal, the Azure CLI, or Azure PowerShell. For more information, see Assign a Key Vault access policy.
Important
Azure Cosmos DB exposes two built-in role definitions: Cosmos DB Built-in Data Reader
and Cosmos DB Built-in Data Contributor
. However, Azure portal support for role management isn't available yet. For more information about the permission model, role definitions, and role assignment, see Configure role-based access control with Azure Active Directory for your Azure Cosmos DB account.
SAS tokens
You can also configure services for authentication with Shared Access Signature (SAS). spring.cloud.azure.<azure-service>.sas-token
is the property to configure. For example, use spring.cloud.azure.storage.blob.sas-token
to authenticate to Storage Blob service.
Connection strings
Connection string is supported by some Azure services to provide connection information and credentials. To connect to those Azure services using connection string, just configure spring.cloud.azure.<azure-service>.connection-string
. For example, configure spring.cloud.azure.eventhubs.connection-string
to connect to the Event Hubs service.
Production ready
We’ve added health indicators for App Configuration, Event Hubs, Azure Cosmos DB, Key Vault, Storage Blob, Storage Queue, and Storage File, as well as Spring Cloud Sleuth support for all HTTP-based Azure SDKs. As an example, you now can probe to determine whether a storage blob is up or down via Spring Boot actuator endpoint, as well as track dependencies and latencies going from your application to Key Vault.
Enable health indicator
To enable the health indicators, add the Spring Cloud Azure Actuator Starter dependency to your pom.xml file. This dependency will also include the spring-boot-starter-actuator
.
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-actuator</artifactId>
</dependency>
The following table lists configurable properties to enable or disable health indicators for each Azure service:
Azure Service | Property |
---|---|
App Configuration | management.health.azure-appconfiguration.enabled |
Azure Cosmos DB | management.health.azure-cosmos.enabled |
Event Hubs | management.health.azure-eventhubs.enabled |
Key Vault Certificate | management.health.azure-keyvault-certificate.enabled |
Key Vault Secret | management.health.azure-keyvault-secret.enabled |
Storage Blob | management.health.azure-storage-blob.enabled |
Storage File Share | management.health.azure-storage-fileshare.enabled |
Storage Queue | management.health.azure-storage-queue.enabled |
Important
Calling the health endpoint of Azure services may cause extra charges. For example, if you call http://HOST_NAME:{port}/actuator/health/cosmos
to get Azure Cosmos DB health info, it will calculate Request Units (RUs). For more information, see Request Units in Azure Cosmos DB.
Note
For calling the health endpoint of Cosmos
, the option spring.cloud.azure.cosmos.database
should be configured; Otherwise, the health status of unknown
will be returned.
For calling the health endpoint of Storage Queue
, role of Storage Account Contributor
is required if Azure AD
is used for authorizing.
Enable sleuth
When you want to trace Azure SDK activities by using Spring Cloud Sleuth, add the following Spring Cloud Azure Trace Sleuth dependency to your pom.xml file:
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-trace-sleuth</artifactId>
</dependency>
Note
Only HTTP-based Azure SDK clients are currently supported. For example, Event Hubs and Service Bus with AMQP transport are currently not supported. For these requirements, we recommend that you use Azure Application Insight.
Auto-configure Azure SDK clients
Spring Boot simplifies the Spring Cloud Azure development experience. Spring Cloud Azure starters are a set of convenient dependency descriptors to include in your application. The starters handle the object instantiation and configuration logic, so you don’t have to. Every starter depends on spring-cloud-azure-starter
to provide critical bits of configuration, like the Azure cloud environment and authentication information. You can configure these as properties in, for example, a YAML file, as shown in the following example:
spring:
cloud:
azure:
profile:
tenant-id: ${AZURE_TENANT_ID}
cloud-type: Azure
credential:
client-id: ${AZURE_CLIENT_ID}
Note
The cloud
property is optional.
These properties are optional and, if not specified, Spring Boot will try to automatically find them for you. For details on how Spring Boot finds these properties, refer to the documentation.
Dependency setup
There are two ways to use Spring Cloud Azure starters. The first way is to use Azure SDKs with the spring-cloud-azure-starter
dependency as shown in the following example:
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-cosmos</artifactId>
</dependency>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter</artifactId>
</dependency>
The second way is to avoid adding Azure SDK dependencies and instead include the Spring Cloud Azure Starter for each Service directly. For example, with Azure Cosmos DB, you would add the following dependency:
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-cosmos</artifactId>
</dependency>
Tip
For the list of supported starters, see Starter dependencies.
Configuration
Note
If you use a security principal to authenticate and authorize with Azure Active Directory for accessing an Azure resource, be sure the security principal has been granted sufficient permission to access the Azure resource. For more information, see Authorize access with Azure Active Directory.
Configuration properties for each Azure service are under prefix spring.cloud.azure.<azure-service>
.
Tip
For the list of all Spring Cloud Azure configuration properties, see Spring Cloud Azure configuration properties.
Basic usage
Adding the following properties to your application.yaml file will autoconfigure the Azure Cosmos DB client for you.
spring:
cloud:
azure:
cosmos:
database: ${AZURE_COSMOS_DATABASE_NAME}
endpoint: ${AZURE_COSMOS_ENDPOINT}
consistency-level: eventual
connection-mode: direct
Then, both CosmosClient
and CosmosAsyncClient
are available in the context and can be autowired, as shown in the following example:
class Demo {
@Autowired
private CosmosClient cosmosClient;
@Override
public void run() {
User item = User.randomUser();
CosmosContainer container = cosmosClient.getDatabase(databaseName).getContainer(containerName);
container.createItem(item);
}
}
Samples
See the azure-spring-boot-samples on GitHub.
Resource handing
The Spring project provides a Spring Resources abstraction to access a number of low-level resources. The project provides interfaces like Resource
, ResourceLoader
and ResourcePatternResolver
. Spring Cloud Azure implements these interfaces for Azure Storage services, which allows you to interact with Azure storage Blob and File Share using the Spring programming model. Spring Cloud Azure provides spring-cloud-azure-starter-storage-blob
and spring-cloud-azure-starter-storage-file-share
to auto-configure Azure Storage Blob and Azure Storage File Share.
The following table lists Azure Storage related libraries:
Starter | Service | Description |
---|---|---|
spring-cloud-azure-starter-storage-blob | Azure Storage Blob | Allows unstructured data to be stored and accessed at a massive scale in block blobs. |
spring-cloud-azure-starter-storage-file-share | Azure Storage File Share | Offers fully managed cloud file shares that you can access from anywhere via the industry standard Server Message Block (SMB) protocol. |
Dependency setup
<dependencies>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-storage-blob</artifactId>
</dependency>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-storage-file-share</artifactId>
</dependency>
</dependencies>
The spring-cloud-azure-starter-storage-blob
dependency is only required when you're using Azure Storage Blob.
The spring-cloud-azure-starter-storage-file-share
dependency is only required when you're using Azure Storage File Share.
Tip
We also provide spring-cloud-azure-starter-storage
to support all the features of Storage. If you choose to use it, spring.cloud.azure.storage.enable
is the property to configure and the default value is true. You can then use spring.cloud.azure.storage.<storage-service>.enable
to disable unneeded services.
Configuration
Note
If you use a security principal to authenticate and authorize with Azure Active Directory for accessing an Azure resource, be sure the security principal has been granted sufficient permission to access the Azure resource. For more information, see Authorize access with Azure Active Directory.
The following table lists the configurable properties of spring-cloud-azure-starter-storage-blob
:
Property | Default | Description |
---|---|---|
spring.cloud.azure.storage.blob.enabled | true | A value that indicates whether an Azure Blob Storage service is enabled. |
spring.cloud.azure.storage.blob.endpoint | The URI to connect to Azure Blob Storage. | |
spring.cloud.azure.storage.blob.account-key | The private key to connect to Azure Blob Storage. | |
spring.cloud.azure.storage.blob.account-name | The Azure Storage Blob account name. |
The following table lists the configurable properties of spring-cloud-azure-starter-storage-file-share
:
Property | Default | Description |
---|---|---|
spring.cloud.azure.storage.fileshare.enabled | true | A value that indicates whether Azure File Storage service is enabled. |
spring.cloud.azure.storage.fileshare.endpoint | The URI to connect to Azure File Storage. | |
spring.cloud.azure.storage.fileshare.account-key | The private key to connect to Azure File Storage. | |
spring.cloud.azure.storage.fileshare.account-name | The Azure Storage File Share account name. |
Basic usage
Add the following properties to your application.yml file:
spring:
cloud:
azure:
storage:
blob:
account-name: ${STORAGE_ACCOUNT_NAME}
account-key: ${STORAGE_ACCOUNT_KEY}
endpoint: ${STORAGE_BLOB_ENDPOINT}
fileshare:
account-name: ${STORAGE_ACCOUNT_NAME}
account-key: ${STORAGE_ACCOUNT_KEY}
endpoint: ${STORAGE_FILESHARE_ENDPOINT}
Get a resource
Get a resource with @Value
You can use the annotation of @Value("azure-blob://[your-container-name]/[your-blob-name]")
to autowire a blob resource, as shown in the following example:
@Value("azure-blob://[your-container-name]/[your-blob-name]")
private Resource storageBlobResource;
You can use the annotation of @Value("azure-file://[your-fileshare-name]/[your-file-name]")
to autowire a file resource, as shown in the following example:
@Value("azure-file://[your-fileshare-name]/[your-file-name]")
private Resource storageFileResource;
Get a resource with ResourceLoader
@Autowired
private ResourceLoader resourceLoader;
...
// Get a BlobResource.
Resource storageBlobResource = resourceLoader.getResource("azure-blob://[your-container-name]/[your-blob-name]");
// Get a FileResource.
Resource storageFileResource = resourceLoader.getResource("azure-file://[your-fileshare-name]/[your-file-name]");
Get resources by searching pattern
You can use an implementation class of ResourcePatternResolver
to search resources. Use AzureStorageBlobProtocolResolver
to search blob
resources and AzureStorageFileProtocolResolver
to search file
resources.
For pattern search, the
searchPattern
should start withazure-blob://
orazure-file://
. For example,azure-blob://**/**
means to list all blobs in all containers, andazure-blob://demo-container/**
means to list all blobs in thedemo-container
container, including any sub-folder.For location search, the
searchLocation
should start withazure-blob://
orazure-file://
and the remaining file path should exist, otherwise an exception will be thrown.
@Autowired
private AzureStorageBlobProtocolResolver azureStorageBlobProtocolResolver;
@Autowired
private AzureStorageFileProtocolResolver azureStorageFileProtocolResolver;
// Get all text blobs.
Resource[] blobTextResources = azureStorageBlobProtocolResolver.getResources("azure-blob://[container-pattern]/*.txt");
// Get all text files.
Resource[] fileTextResources = azureStorageFileProtocolResolver.getResources("azure-file://[fileshare-pattern]/*.txt");
Handling with resource
Download data from specific resource
You can download a resource from Azure Storage Blob or File Share with the getInputStream()
method of Resource
.
@Value("azure-blob://[your-container-name]/[your-blob-name]")
private Resource storageBlobResource;
@Value("azure-file://[your-fileshare-name]/[your-file-name]")
private Resource storageFileResource;
//...
// Download data as a stream from a blob resource.
InputStream inputblobStream = storageBlobResource.getInputStream();
// Download data as a stream from a file resource.
InputStream inputfileStream = storageFileResource.getInputStream();
Upload data to specific resource
You can upload to a resource to Azure Blob or file storage by casting the Spring Resource
to WritableResource
, as shown in the following example:
@Value("azure-blob://[your-container-name]/[your-blob-name]")
private Resource storageBlobResource;
@Value("azure-file://[your-fileshare-name]/[your-file-name]")
private Resource storageFileResource;
String data = "sampledata";
// Upload string data to a blob.
try (OutputStream blobos = ((WritableResource) this.storageBlobResource).getOutputStream()) {
blobos.write(data.getBytes());
}
// Upload string data to a file.
try (OutputStream fileos = ((WritableResource) this.storageFileResource).getOutputStream()) {
fileos.write(data.getBytes());
}
Multipart upload
Files larger than 4 MiB will be uploaded to Azure Storage in parallel.
Samples
See the storage-blob-sample and storage-file-sample on GitHub.
Secret management
Spring Cloud Azure construct PropertySource
which holds secrets stored in Azure Key Vault Secrets.
Dependency setup
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-keyvault-secrets</artifactId>
</dependency>
Tip
We also provide spring-cloud-azure-starter-keyvault
to support all the features of Key Vault. If you choose to use it, spring.cloud.azure.keyvault.enable
is the property to configure and the default value is true. You can then use spring.cloud.azure.keyvault.<keyvault-service>.enable
to disable unneeded services.
Basic usage
If you want to authenticate by client-id
and client-secret
, the following properties are required:
Configuration Properties
spring:
cloud:
azure:
keyvault:
secret:
property-sources:
- name: key-vault-property-souece-1
endpoint: ${ENDPOINT_1}
- name: key-vault-property-souece-2
endpoint: ${ENDPOINT_2}
Java code
@SpringBootApplication
public class SampleApplication implements CommandLineRunner {
@Value("${sampleProperty1}")
private String sampleProperty1;
@Value("${sampleProperty2}")
private String sampleProperty2;
@Value("${samplePropertyInMultipleKeyVault}")
private String samplePropertyInMultipleKeyVault;
public static void main(String[] args) {
SpringApplication.run(SampleApplication.class, args);
}
public void run(String[] args) {
System.out.println("sampleProperty1: " + sampleProperty1);
System.out.println("sampleProperty2: " + sampleProperty2);
System.out.println("samplePropertyInMultipleKeyVault: " + samplePropertyInMultipleKeyVault);
}
}
Advanced usage
Special characters in property name
Key Vault secret names support only characters in [0-9a-zA-Z-]
. For more information, see theVault-name and Object-name section of Azure Key Vault keys, secrets and certificates overview. If your property name contains other characters, you can use the workarounds described in the following sections.
Use -
instead of .
in secret names
.
isn't supported in secret names. If your application has a property name that contains .
, such as spring.datasource.url
, replace .
with -
when saving the secret in Azure Key Vault. For example, save spring-datasource-url
in Azure Key Vault. In your application, you can still use spring.datasource.url
to retrieve the property value.
Note
This method cannot satisfy a requirement like spring.datasource-url
. When you save spring-datasource-url
in Key Vault, only spring.datasource.url
and spring-datasource-url
is supported to retrieve the property value, but spring.datasource-url
isn't supported. To handle this case, see the Use property placeholders section.
Use property placeholders
For example, suppose you're setting this property in your application.properties file:
property.with.special.character__=${propertyWithoutSpecialCharacter}
The application will get a propertyWithoutSpecialCharacter
key name and assign its value to property.with.special.character__
.
Case-sensitive
To enable case-sensitive mode, you can set the following property:
spring.cloud.azure.keyvault.secret.property-sources[].case-sensitive=true
Not retrieve all secrets in Key Vault
If you stored 1000 secrets in the Key Vault, and you just want to use 3 of them. You can list the 3 secret names by spring.cloud.azure.keyvault.secret.property-sources[].secret-keys
.
Setting refresh interval
By default, the secrets in KeyVaultPropertySource
will refresh every 30 minutes. You can configure the time by spring.cloud.azure.keyvault.secret.property-sources[].refresh-interval
. For example: spring.cloud.azure.keyvault.secret.property-sources[].refresh-interval=60m
means refresh every 60 minutes. Set to 0
to disable auto refresh.
PropertySource priority
If key exists in multiple PropertySources, which will take effect is decided by the priority.
- If there is no
SystemEnvironmentPropertySource
in PropertySource list, thenKeyVaultPropertySource
will take the highest priority. - If there is
SystemEnvironmentPropertySource
in PropertySource list, thenSystemEnvironmentPropertySource
have higher priority than KeyVaultPropertySource. Which means you can use environment variable to override the Key Vault secret value in your application. - If there are multiple KeyVaultPropertySource in PropertySource list, then the definition order is the priority order. Take above sample as example,
key-vault-property-souece-1
has higher priority thankey-vault-property-souece-2
.
All configurable properties
Property | Default value | Description |
---|---|---|
spring.cloud.azure.keyvault.secret.property-source-enabled | true | Whether to enable the Key Vault property source. |
spring.cloud.azure.keyvault.secret.property-sources[].name | Name of this property source. | |
spring.cloud.azure.keyvault.secret.property-sources[].endpoint | Azure Key Vault endpoint. | |
spring.cloud.azure.keyvault.secret.property-sources[].case-sensitive | false | Whether the secret keys are case-sensitive. |
spring.cloud.azure.keyvault.secret.property-sources[].secret-keys | The secret keys supported for this property source. All keys be retrieved if this property is missing. | |
spring.cloud.azure.keyvault.secret.property-sources[].refresh-interval | 30m | Time interval to refresh all Key Vault secrets. |
spring.cloud.azure.keyvault.secret.property-sources[].service-version | Secret service version used when making API requests. | |
spring.cloud.azure.keyvault.secret.property-sources[].client | Client related properties. | |
spring.cloud.azure.keyvault.secret.property-sources[].credential | Credential related properties. | |
spring.cloud.azure.keyvault.secret.property-sources[].profile | Profile related properties. | |
spring.cloud.azure.keyvault.secret.property-sources[].proxy | Proxy related properties. | |
spring.cloud.azure.keyvault.secret.property-sources[].retry | Retry related properties. |
- See Authorize access with Azure Active Directory to make sure the security principal has been granted the sufficient permission to access the Azure Key Vault Secrets.
- If common properties like
client
,credential
,profile
,proxy
,retry
aren't configured inspring.cloud.azure.keyvault.secret.property-sources[].xxx
,spring.cloud.azure.xxx
will be used. See Spring Cloud Azure configuration to get more information about these common properties. - See Spring Cloud Azure configuration properties to get more information about nested properties.
Samples
See the spring-cloud-azure-starter-keyvault-secrets samples on GitHub.
Spring Data support
Spring Data Azure Cosmos DB support
Azure Cosmos DB is a globally distributed database service that allows developers to work with data using various standard APIs, such as SQL, MongoDB, Graph, and Azure Table storage.
Dependency setup
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-data-cosmos</artifactId>
</dependency>
Configuration
Note
If you use a security principal to authenticate and authorize with Azure Active Directory for accessing an Azure resource, be sure the security principal has been granted sufficient permission to access the Azure resource. For more information, see Authorize access with Azure Active Directory.
The following table lists the configurable properties of spring-cloud-azure-starter-data-cosmos
:
Property | Description |
---|---|
spring.cloud.azure.cosmos.enabled | A value that indicates whether Azure Cosmos DB Service is enabled. The default value is true. |
spring.cloud.azure.cosmos.database | The Azure Cosmos DB database ID. |
spring.cloud.azure.cosmos.endpoint | The URI to connect Azure Cosmos DB. |
spring.cloud.azure.cosmos.key | The PrivateKey to connect Azure Cosmos DB. |
spring.cloud.azure.cosmos.credential.client-certificate-password | The password of the certificate file. |
spring.cloud.azure.cosmos.credential.client-certificate-path | The path of a PEM certificate file to use when performing service principal authentication with Azure. |
spring.cloud.azure.cosmos.credential.client-id | The client ID to use when performing service principal authentication with Azure. |
spring.cloud.azure.cosmos.credential.client-secret | The client secret to use when performing service principal authentication with Azure. |
spring.cloud.azure.cosmos.credential.managed-identity-enabled | Whether to enable managed identity. The default value is false. |
spring.cloud.azure.cosmos.credential.password | The password to use when performing username/password authentication with Azure. |
spring.cloud.azure.cosmos.credential.username | The username to use when performing username/password authentication with Azure. |
spring.cloud.azure.cosmos.populate-query-metrics | A value that indicates whether to populate diagnostics strings and query metrics. The default value is false. |
spring.cloud.azure.cosmos.consistency-level | A consistency level for Azure Cosmos DB. |
Key concepts
The following list shows the key concepts of the Spring Data support:
The Spring Data
CrudRepository
andReactiveCrudRepository
, which provide the following basic CRUD functionality:- save
- findAll
- findOne by ID
- deleteAll
- delete by ID
- delete entity
The Spring Data @Id annotation. There are two ways to map a field in a domain class to the
id
of an Azure Cosmos DB document:- Annotate a field in domain class with
@Id
. This field will be mapped to documentid
in Azure Cosmos DB. - Set the name of this field to
id
. This field will be mapped to documentid
in Azure Cosmos DB.
Note
If both ways are applied, the
@Id
annotation has higher priority.- Annotate a field in domain class with
Custom collection names. By default, collection name will be class name of user domain class. To customize it, add annotation
@Document(collection="myCustomCollectionName")
to your domain class, that's all.Supports Azure Cosmos DB partition. To specify a field of your domain class to be a partition key field, annotate it with
@PartitionKey
. When you do CRUD operations, specify your partition value. For more examples, see AddressRepositoryIT.java on GitHub.Supports Spring Data custom query find operation.
Supports spring-boot-starter-data-rest.
Supports List and nested types in domain classes.
Basic usage
Use a private key to access Azure Cosmos DB
The simplest way to connect Azure Cosmos DB with spring-cloud-azure-starter-data-cosmos
is with a primary key. Add the following properties:
spring:
cloud:
azure:
cosmos:
key: ${AZURE_COSMOS_KEY}
endpoint: ${AZURE_COSMOS_ENDPOINT}
database: ${AZURE_COSMOS_DATABASE}
Define an entity
Define an entity as a Document in Azure Cosmos DB, as shown in the following example:
@Container(containerName = "mycollection")
public class User {
@Id
private String id;
private String firstName;
@PartitionKey
private String lastName;
private String address;
public User() {
}
public User(String id, String firstName, String lastName, String address) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.address = address;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return String.format("%s %s, %s", firstName, lastName, address);
}
}
The id
field will be used as the document id
in Azure Cosmos DB. Alternately, you can annotate any field with @Id
to map it to the document id
.
The annotation @Container(containerName = "mycollection")
is used to specify the collection name of your document in Azure Cosmos DB.
Create repositories
To create repositories, extend the ReactiveCosmosRepository
interface, which provides Spring Data repository support.
@Repository
public interface UserRepository extends ReactiveCosmosRepository<User, String> {
Flux<User> findByFirstName(String firstName);
}
Currently, the ReactiveCosmosRepository
interface provides basic save, delete, and find operations. More operations will be supported later.
Create an application class
The following example creates an application class with all the components:
@SpringBootApplication
public class CosmosSampleApplication implements CommandLineRunner {
private static final Logger LOGGER = LoggerFactory.getLogger(CosmosSampleApplication.class);
@Autowired
private UserRepository repository;
@Autowired
private CosmosProperties properties;
public static void main(String[] args) {
SpringApplication.run(CosmosSampleApplication.class, args);
}
public void run(String... var1) {
final User testUser = new User("testId", "testFirstName",
"testLastName", "test address line one");
// Save the User class to Azure Cosmos DB database.
final Mono<User> saveUserMono = repository.save(testUser);
final Flux<User> firstNameUserFlux = repository.findByFirstName("testFirstName");
// Nothing happens until we subscribe to these Monos.
// findById will not return the user as user isn't present.
final Mono<User> findByIdMono = repository.findById(testUser.getId());
final User findByIdUser = findByIdMono.block();
Assert.isNull(findByIdUser, "User must be null");
final User savedUser = saveUserMono.block();
Assert.state(savedUser != null, "Saved user must not be null");
Assert.state(savedUser.getFirstName().equals(testUser.getFirstName()),
"Saved user first name doesn't match");
firstNameUserFlux.collectList().block();
final Optional<User> optionalUserResult = repository.findById(testUser.getId()).blockOptional();
Assert.isTrue(optionalUserResult.isPresent(), "Cannot find user.");
final User result = optionalUserResult.get();
Assert.state(result.getFirstName().equals(testUser.getFirstName()),
"query result firstName doesn't match!");
Assert.state(result.getLastName().equals(testUser.getLastName()),
"query result lastName doesn't match!");
LOGGER.info("findOne in User collection get result: {}", result.toString());
}
@PostConstruct
public void setup() {
// For this example, remove all of the existing records.
this.repository.deleteAll().block();
}
}
This example includes an autowired UserRepository
interface to support save, delete, and find operations.
Samples
See the azure-spring-boot-samples on GitHub.
Apart from using the spring-cloud-azure-starter-data-cosmos
library, you can directly use azure-spring-data-cosmos
library for more complex scenarios. For more information, see Spring Data for Azure Cosmos DB client library.
Spring Security support
Spring Security with Azure Active Directory
When you're building a web application, identity and access management will always be foundational pieces.
Azure offers a great platform to democratize your application development journey, as it not only offers a cloud-base identity service, but also deep integration with the rest of the Azure ecosystem.
Spring Security has made it easy to secure your Spring based applications with powerful abstractions and extensible interfaces. However, as powerful as the Spring framework can be, it is not tailored to a specific identity provider.
The spring-cloud-azure-starter-active-directory
provides the most optimal way to connect your web application to an Azure Active Directory (Azure AD for short) tenant and protect your resource server with Azure AD. It uses the Oauth 2.0 protocol to protect web applications and resource servers.
Accessing a web application
This scenario uses The OAuth 2.0 authorization code grant flow to log in a user with a Microsoft account.
System Diagram
Create required resources in Azure
Read MS docs about register an application with the Microsoft identity platform.
Create app registration. Get
AZURE_TENANT_ID
,AZURE_CLIENT_ID
andAZURE_CLIENT_SECRET
.Set
redirect URI
toAPPLICATION_BASE_URI/login/oauth2/code/
, for examplehttp://localhost:8080/login/oauth2/code/
. The tailing/
is required.
Add required dependencies
<dependencies>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-active-directory</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
</dependencies>
Add required properties
spring:
cloud:
azure:
active-directory:
profile:
tenant-id: ${AZURE_TENANT_ID}
credential:
client-id: ${AZURE_CLIENT_ID}
client-secret: ${AZURE_CLIENT_SECRET}
Now start you application and access your application by browser, then you will be redirected into Microsoft login page.
Advanced usages
Add extra security configurations
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AadOAuth2LoginSecurityConfig extends AadWebSecurityConfigurerAdapter {
/**
* Add configuration logic as needed.
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests()
.anyRequest().authenticated();
// Do some custom configuration
}
}
Authorize access by app roles
Create Required Resources in Azure
Read MS docs about Add app roles to your application and receive them in the token.
Create an app role with the following parameters:
Display name: Admin
Allowed member types: Users/Groups
Value: Admin
Do you want to enable this app role: yes
Note
If you want to use app role based access control, you can't put group names in role
claim . Refs: [Configuring groups optional claims] (/azure/active-directory/develop/active-directory-optional-claims#configuring-groups-optional-claims).
- Protect specific method.
class Demo {
@GetMapping("Admin")
@ResponseBody
@PreAuthorize("hasAuthority('APPROLE_Admin')")
public String admin() {
return "Admin message";
}
}
Authorize access by group name or group Id
Add related configuration properties.
spring: cloud: azure: active-directory: user-group: allowed-group-names: group1_name_1, group2_name_2 # 1. If allowed-group-ids == all, then all group ID will take effect. # 2. If "all" is used, we should not configure other group ids. # 3. "all" is only supported for allowed-group-ids, not supported for allowed-group-names. allowed-group-ids: group_id_1, group_id_2
Protect specific method.
@Controller public class RoleController { @GetMapping("group1") @ResponseBody @PreAuthorize("hasRole('ROLE_group1')") public String group1() { return "group1 message"; } @GetMapping("group2") @ResponseBody @PreAuthorize("hasRole('ROLE_group2')") public String group2() { return "group2 message"; } @GetMapping("group1Id") @ResponseBody @PreAuthorize("hasRole('ROLE_<group1-id>')") public String group1Id() { return "group1Id message"; } @GetMapping("group2Id") @ResponseBody @PreAuthorize("hasRole('ROLE_<group2-id>')") public String group2Id() { return "group2Id message"; } }
Use National Azure instead of Global Azure
Now except global Azure cloud, Azure Active Directory is deployed in the following national clouds:
Azure Government
Azure China 21Vianet
Azure Germany
Here is a sample of you want to use Azure China 21Vianet.
spring:
cloud:
azure:
active-directory:
base-uri: https://login.partner.microsoftonline.cn
graph-base-uri: https://microsoftgraph.chinacloudapi.cn
You can refer to these MS doc to get more information from MS docs about National cloud deployments.
Configure redirect uri template
Developers can customize the redirect-uri.
Add
redirect-uri-template
properties in application.yml.spring: cloud: azure: active-directory: redirect-uri-template: ${REDIRECT-URI-TEMPLATE}
Update redirect-uri in Azure portal.
Update WebSecurityConfigurerAdapter
After we set redirect-uri-template, we need to update WebSecurityConfigurerAdapter
:
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AadOAuth2LoginSecurityConfig extends AadWebSecurityConfigurerAdapter {
/**
* Add configuration logic as needed.
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.oauth2Login()
.loginProcessingUrl("${REDIRECT-URI-TEMPLATE}")
.and()
.authorizeRequests()
.anyRequest().authenticated();
}
}
Connecting to Azure AD via proxy
To connect Azure AD via proxy, provide a RestTemplateCustomizer
bean like the one shown in the following example:
@Configuration
class DemoConfiguration {
@Bean
public RestTemplateCustomizer proxyRestTemplateCustomizer() {
return (RestTemplate restTemplate) -> {
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_SERVER_HOST, PROXY_SERVER_PORT));
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setProxy(proxy);
restTemplate.setRequestFactory(requestFactory);
};
}
}
Samples
Sample project: aad-web-application.
Web application accessing resource servers
System Diagram
Create Required Resources in Azure
Read MS docs about register an application with the Microsoft identity platform.
Create app registration. Get
AZURE_TENANT_ID
,AZURE_CLIENT_ID
andAZURE_CLIENT_SECRET
.Set
redirect URI
toAPPLICATION_BASE_URI/login/oauth2/code/
, for examplehttp://localhost:8080/login/oauth2/code/
. The tailing/
is required.
Add required dependencies
<dependencies>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-active-directory</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
</dependencies>
Add required properties
spring:
cloud:
azure:
active-directory:
profile:
tenant-id: ${AZURE_TENANT_ID}
credential:
client-id: ${AZURE_CLIENT_ID}
client-secret: ${AZURE_CLIENT_SECRET}
authorization-clients:
graph:
scopes: https://graph.microsoft.com/Analytics.Read, email
Here, graph
is the name of OAuth2AuthorizedClient
, scopes
means the scopes need to consent when login.
Use OAuth2AuthorizedClient in your application
public class Demo {
@GetMapping("/graph")
@ResponseBody
public String graph(
@RegisteredOAuth2AuthorizedClient("graph") OAuth2AuthorizedClient graphClient) {
// toJsonString() is just a demo.
// oAuth2AuthorizedClient contains access_token. We can use this access_token to access resource server.
return toJsonString(graphClient);
}
}
Now start you application and access your application by browser, then you will be redirected into Microsoft login page.
Advanced usages
Client Credential Flow
The default flow is authorization code flow, if you want to use client credentials flow, you can configure like this:
spring:
cloud:
azure:
active-directory:
profile:
tenant-id: ${AZURE_TENANT_ID}
credential:
client-id: ${AZURE_CLIENT_ID}
client-secret: ${AZURE_CLIENT_SECRET}
authorization-clients:
graph:
authorization-grant-type: client_credentials # Change type to client_credentials
scopes: https://graph.microsoft.com/Analytics.Read, email
Access multiple resource servers
In one web application, you can access multiple resource server by configuring like this:
spring:
cloud:
azure:
active-directory:
profile:
tenant-id: ${AZURE_TENANT_ID}
credential:
client-id: ${AZURE_CLIENT_ID}
client-secret: ${AZURE_CLIENT_SECRET}
authorization-clients:
resource-server-1:
scopes: # Scopes for resource-server-1
resource-server-2:
scopes: # Scopes for resource-server-2
Then you can use OAuth2AuthorizedClient in application like this
public class Demo {
@GetMapping("/resource-server-1")
@ResponseBody
public String graph(
@RegisteredOAuth2AuthorizedClient("resource-server-1") OAuth2AuthorizedClient client) {
return callResourceServer1(client);
}
@GetMapping("/resource-server-2")
@ResponseBody
public String graph(
@RegisteredOAuth2AuthorizedClient("resource-server-2") OAuth2AuthorizedClient client) {
return callResourceServer2(client);
}
}
Incremental consent
In previous sample, all scopes will be consented when customer first login, no matter it's belong to resource-server-1 or resource-server-2. If you don't want to let customer consent all scopes, you can do like this:
spring:
cloud:
azure:
active-directory:
profile:
tenant-id: ${AZURE_TENANT_ID}
credential:
client-id: ${AZURE_CLIENT_ID}
client-secret: ${AZURE_CLIENT_SECRET}
authorization-clients:
resource-server-1:
scopes: # Scopes for resource-server-1
resource-server-2:
on-demand: true # means incremental consent
scopes: # Scopes for resource-server-2
Samples
Sample project: aad-web-application.
Accessing a resource server
This scenario doesn't support login, just protect the server by validating the access token. If the access token is valid, the server serves the request.
System Diagram
Create required resources in Azure
Read MS docs about register an application with the Microsoft identity platform.
Create app registration. Get
AZURE_CLIENT_ID
.Read MS docs about configure an application to expose a web API.
Expose a web API with a scope named
Scope-1
.
Add required dependencies
<dependencies>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-active-directory</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
</dependencies>
Add required properties
spring:
cloud:
azure:
active-directory:
credential:
client-id: ${AZURE_CLIENT_ID}
Now start your application and access your application's web api.
You will get 401 without an access token.
Access your application with an access token, the following claims in access token will be validated:
iss
: The access token must be issued by Azure AD.nbf
: Current time can not beforenbf
.exp
: Current time can not afterexp
.aud
: Ifspring.cloud.azure.active-directory.credential.client-id
orspring.cloud.azure.active-directory.credential.app-id-uri
configured, the audience must equal to the configuredclient-id
orapp-id-uri
. If the 2 properties are not configured, this claim will not be validated.
Refer to MS docs about Microsoft identity platform access tokens to get more information about access token.
Advanced usages
Add extra security configurations
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AadOAuth2ResourceServerSecurityConfig extends AadResourceServerWebSecurityConfigurerAdapter {
/**
* Add configuration logic as needed.
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests((requests) -> requests.anyRequest().authenticated());
}
}
Validate permission by scopes
Create Required Resources in Azure
Read MS docs about configure an application to expose a web API.
Expose a web API with a scope named
Scope1
.
Protect specific method.
class Demo {
@GetMapping("scope1")
@ResponseBody
@PreAuthorize("hasAuthority('SCOPE_Scope1')")
public String scope1() {
return "Congratulations, you can access `scope1` endpoint.";
}
}
By doing this, when access /scope1
endpoint, the following claims in access token will be validated:
scp
: The value must containsScope1
.
Validate permission by app roles
Create Required Resources in Azure
Read MS docs about Add app roles to your application and receive them in the token.
Create an app role with the following parameters:
Display name: AppRole1
Allowed member types: Users/Groups
Value: AppRole1
Do you want to enable this app role: yes
Protect specific method.
class Demo {
@GetMapping("app-role1")
@ResponseBody
@PreAuthorize("hasAuthority('APPROLE_AppRole1')")
public String appRole1() {
return "Congratulations, you can access `app-role1` endpoint.";
}
}
By doing this, when access /app-role1
endpoint, the following claims in access token will be validated:
roles
: The value must containsAppRole1
.
Use JWT client authentication
To use a JSON Web Token (JWT) for client authentication, use the following steps:
- See the Register your certificate with Microsoft identity platform section of Microsoft identity platform application authentication certificate credentials.
- Upload a .pem certificate to the application registered in the Azure portal.
- Configure the certificate path and password of a .PFX or .P12 certificate.
- Add the property
spring.cloud.azure.active-directory.authorization-clients.azure.client-authentication-method=private_key_jwt
configuration to the client to be authenticated through JWT client authentication.
The following example configuration file is for a web application scenario. The certificate information is configured in the global properties.
spring:
cloud:
azure:
credential:
client-id: ${AZURE_CLIENT_ID}
client-certificate-path: ${AZURE_CERTIFICATE_PATH}
client-certificate-password: ${AZURE_CERTIFICATE_PASSWORD}
profile:
tenant-id: ${AZURE_TENANT_ID}
active-directory:
enabled: true
user-group:
allowed-group-names: group1,group2
allowed-group-ids: <group1-id>,<group2-id>
post-logout-redirect-uri: http://localhost:8080
authorization-clients:
azure:
client-authentication-method: private_key_jwt
arm:
client-authentication-method: private_key_jwt
on-demand: true
scopes: https://management.core.windows.net/user_impersonation
graph:
client-authentication-method: private_key_jwt
scopes:
- https://graph.microsoft.com/User.Read
- https://graph.microsoft.com/Directory.Read.All
webapiA:
client-authentication-method: private_key_jwt
scopes:
- ${WEB_API_A_APP_ID_URL}/Obo.WebApiA.ExampleScope
webapiB:
client-authentication-method: private_key_jwt
scopes:
- ${WEB_API_B_APP_ID_URL}/.default
authorization-grant-type: client_credentials
You can also configure the certificate information in the active-directory
service properties, as shown in this example:
spring:
cloud:
azure:
active-directory:
enabled: true
credential:
client-id: ${AZURE_CLIENT_ID}
client-certificate-path: ${AZURE_CERTIFICATE_PATH}
client-certificate-password: ${AZURE_CERTIFICATE_PASSWORD}
profile:
tenant-id: ${AZURE_TENANT_ID}
user-group:
allowed-group-names: group1,group2
allowed-group-ids: <group1-id>,<group2-id>
post-logout-redirect-uri: http://localhost:8080
authorization-clients:
azure:
client-authentication-method: private_key_jwt
arm:
client-authentication-method: private_key_jwt
on-demand: true
scopes: https://management.core.windows.net/user_impersonation
graph:
client-authentication-method: private_key_jwt
scopes:
- https://graph.microsoft.com/User.Read
- https://graph.microsoft.com/Directory.Read.All
webapiA:
client-authentication-method: private_key_jwt
scopes:
- ${WEB_API_A_APP_ID_URL}/Obo.WebApiA.ExampleScope
webapiB:
client-authentication-method: private_key_jwt
scopes:
- ${WEB_API_B_APP_ID_URL}/.default
authorization-grant-type: client_credentials
Connecting to Azure AD via proxy
To connect Azure AD via proxy, provide a RestTemplateCustomizer
bean. For more information, see the Connecting to Azure AD via proxy section.
Samples
Sample project: aad-resource-server.
Resource server visiting other resource servers
System Diagram
Create required resources in Azure
Read MS docs about register an application with the Microsoft identity platform.
Create app registration. Get
AZURE_TENANT_ID
,AZURE_CLIENT_ID
andAZURE_CLIENT_SECRET
.
Add required dependencies
<dependencies>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-active-directory</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
</dependencies>
Add required properties
spring:
cloud:
azure:
active-directory:
profile:
tenant-id: ${AZURE_TENANT_ID}
credential:
client-id: ${AZURE_CLIENT_ID}
client-secret: ${AZURE_CLIENT_SECRET}
authorization-clients:
graph:
scopes:
- https://graph.microsoft.com/User.Read
Use OAuth2AuthorizedClient in your application
public class SampleController {
@GetMapping("call-graph")
public String callGraph(@RegisteredOAuth2AuthorizedClient("graph") OAuth2AuthorizedClient graph) {
return callMicrosoftGraphMeEndpoint(graph);
}
}
Samples
Sample project: aad-resource-server-obo.
Web application and resource server in one application
Create required resources in Azure
Read MS docs about register an application with the Microsoft identity platform.
Create app registration. Get
AZURE_TENANT_ID
,AZURE_CLIENT_ID
andAZURE_CLIENT_SECRET
.
Add required dependencies
<dependencies>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-active-directory</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
</dependencies>
Add required properties
Set property spring.cloud.azure.active-directory.application-type
to web_application_and_resource_server
, and specify the authorization type for each authorization client.
spring:
cloud:
azure:
active-directory:
profile:
tenant-id: ${AZURE_TENANT_ID}
credential:
client-id: ${AZURE_CLIENT_ID}
client-secret: ${AZURE_CLIENT_SECRET}
app-id-uri: ${WEB_API_ID_URI}
application-type: web_application_and_resource_server # This is required.
authorization-clients:
graph:
authorizationGrantType: authorization_code # This is required.
scopes:
- https://graph.microsoft.com/User.Read
- https://graph.microsoft.com/Directory.Read.All
Define securityConfigurationAdapter
Configure multiple HttpSecurity instances, AadWebApplicationAndResourceServerConfig
contain two security configurations for resource server and web application.
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AadWebApplicationAndResourceServerConfig {
@Order(1)
@Configuration
public static class ApiWebSecurityConfigurationAdapter extends AadResourceServerWebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
// All the paths that match `/api/**`(configurable) work as `Resource Server`, other paths work as `Web application`.
http.antMatcher("/api/**")
.authorizeRequests().anyRequest().authenticated();
}
}
@Configuration
public static class HtmlWebSecurityConfigurerAdapter extends AadWebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
// @formatter:off
http.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated();
// @formatter:on
}
}
}
Configuration
Configurable properties of spring-cloud-azure-starter-active-directory:
Name | Description |
---|---|
spring.cloud.azure.active-directory.app-id-uri | App ID URI which might be used in the "aud" claim of an id_token. |
spring.cloud.azure.active-directory.application-type | Type of the Azure AD application. |
spring.cloud.azure.active-directory.authenticate-additional-parameters | Add additional parameters to the Authorization URL. |
spring.cloud.azure.active-directory.authorization-clients | The OAuth2 authorization clients. |
spring.cloud.azure.active-directory.credential.client-id | Client Id to use when performing service principal authentication with Azure. |
spring.cloud.azure.active-directory.credential.client-secret | Client secret to use when performing service principal authentication with Azure. |
spring.cloud.azure.active-directory.jwk-set-cache-lifespan | The lifespan of the cached JWK set before it expires, default is 5 minutes. |
spring.cloud.azure.active-directory.jwk-set-cache-refresh-time | The refresh time of the cached JWK set before it expires, default is 5 minutes. |
spring.cloud.azure.active-directory.jwt-connect-timeout | Connection Timeout for the JWKSet Remote URL call. |
spring.cloud.azure.active-directory.jwt-read-timeout | Read Timeout for the JWKSet Remote URL call. |
spring.cloud.azure.active-directory.jwt-size-limit | Size limit in Bytes of the JWKSet Remote URL call. |
spring.cloud.azure.active-directory.post-logout-redirect-uri | The redirect uri after logout. |
spring.cloud.azure.active-directory.profile.cloud-type | Name of the Azure cloud to connect to. Supported types are: AZURE, AZURE_CHINA, AZURE_GERMANY, AZURE_US_GOVERNMENT, OTHER. |
spring.cloud.azure.active-directory.profile.environment | Properties to Azure Active Directory endpoints. |
spring.cloud.azure.active-directory.profile.tenant-id | Azure Tenant ID. |
spring.cloud.azure.active-directory.redirect-uri-template | Redirection Endpoint: Used by the authorization server to return responses containing authorization credentials to the client via the resource owner user-agent. The default value is {baseUrl}/login/oauth2/code/ . |
spring.cloud.azure.active-directory.resource-server.claim-to-authority-prefix-map | Configure which claim will be used to build GrantedAuthority, and prefix of the GrantedAuthority's string value. Default value is: "scp" -> "SCOPE_", "roles" -> "APPROLE_". |
spring.cloud.azure.active-directory.resource-server.principal-claim-name | Configure which claim in access token be returned in AuthenticatedPrincipal#getName. Default value is "sub". |
spring.cloud.azure.active-directory.session-stateless | If true activates the stateless auth filter AadAppRoleStatelessAuthenticationFilter. The default is false which activates AadAuthenticationFilter. |
spring.cloud.azure.active-directory.user-group.allowed-group-ids | The group ids can be used to construct GrantedAuthority. |
spring.cloud.azure.active-directory.user-group.allowed-group-names | The group names can be used to construct GrantedAuthority. |
spring.cloud.azure.active-directory.user-group.use-transitive-members | If "true", use "v1.0/me/transitiveMemberOf" to get members. Otherwise, use "v1.0/me/memberOf". The default value is false . |
spring.cloud.azure.active-directory.user-name-attribute | Decide which claim to be principal's name. |
Here are some examples about how to use these properties:
Application type
THe application type can be inferred from the dependencies: spring-security-oauth2-client or spring-security-oauth2-resource-server. If the inferred value is not the value you want, you can specify the application type. Here is the table about valid values and inferred value:
Application type of spring-cloud-azure-starter-active-directory:
Has dependency: spring-security-oauth2-client | Has dependency: spring-security-oauth2-resource-server | Valid values of application type | Inferred value |
---|---|---|---|
Yes | No | web_application |
web_application |
No | Yes | resource_server |
resource_server |
Yes | Yes | web_application , resource_server , resource_server_with_obo , web_application_and_resource_server |
resource_server_with_obo |
Spring Security with Azure Active Directory B2C
Azure Active Directory (Azure AD) B2C is an identity management service that enables you to customize and control how customers sign up, sign in, and manage their profiles when using your applications. Azure AD B2C enables these actions while protecting the identities of your customers at the same time.
Dependency setup
<dependencies>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-active-directory-b2c</artifactId>
</dependency>
</dependencies>
Configuration
Configurable properties of spring-cloud-azure-starter-active-directory-b2c:
Name | Description |
---|---|
spring.cloud.azure.active-directory.b2c.app-id-uri | App ID URI which might be used in the "aud" claim of a token. |
spring.cloud.azure.active-directory.b2c.authenticate-additional-parameters | Additional parameters for authentication. |
spring.cloud.azure.active-directory.b2c.authorization-clients | Specify client configuration. |
spring.cloud.azure.active-directory.b2c.base-uri | Azure AD B2C endpoint base uri. |
spring.cloud.azure.active-directory.b2c.credential | Azure AD B2C credential information. |
spring.cloud.azure.active-directory.b2c.jwt-connect-timeout | Connection Timeout for the JWKSet Remote URL call. |
spring.cloud.azure.active-directory.b2c.jwt-read-timeout | Read Timeout for the JWKSet Remote URL call. |
spring.cloud.azure.active-directory.b2c.jwt-size-limit | Size limit in Bytes of the JWKSet Remote URL call. |
spring.cloud.azure.active-directory.b2c.login-flow | Specify the primary sign-in flow key. The default value is sign-up-or-sign-in . |
spring.cloud.azure.active-directory.b2c.logout-success-url | Redirect url after logout. The default value is http://localhost:8080/login . |
spring.cloud.azure.active-directory.b2c.profile | Azure AD B2C profile information. |
spring.cloud.azure.active-directory.b2c.reply-url | Reply url after get authorization code. The default value is {baseUrl}/login/oauth2/code/ . |
spring.cloud.azure.active-directory.b2c.user-flows | User flows. |
spring.cloud.azure.active-directory.b2c.user-name-attribute-name | User name attribute name. |
For full configurations, check Spring Cloud Azure configuration properties.
Basic usage
A web application is any web-based application that allows user to login with Azure AD, whereas a resource server will either accept or deny access after validating access_token obtained from Azure AD. We will cover 4 scenarios in this guide:
Accessing a web application.
Web application accessing resource servers.
Accessing a resource server.
Resource server accessing other resource servers.
Usage 1: Accessing a web application
This scenario uses The OAuth 2.0 authorization code grant flow to log in a user with your Azure AD B2C user.
Select Azure AD B2C from the portal menu, click Applications, and then click Add.
Specify your application Name, we call it
webapp
, addhttp://localhost:8080/login/oauth2/code/
for the Reply URL, record the Application ID as yourWEB_APP_AZURE_CLIENT_ID
and then click Save.Select Keys from your application, click Generate key to generate
WEB_APP_AZURE_CLIENT_SECRET
and then Save.Select User flows on your left, and then Click New user flow.
Choose Sign up or in, Profile editing and Password reset to create user flows respectively. Specify your user flow Name and User attributes and claims, click Create.
Select API permissions > Add a permission > Microsoft APIs, select Microsoft Graph, select Delegated permissions, check offline_access and openid permissions, select Add permission to complete the process.
Grant admin consent for Graph permissions.
Add the following dependencies in your pom.xml.
<dependencies> <dependency> <groupId>com.azure.spring</groupId> <artifactId>azure-spring-boot-starter-active-directory-b2c</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity5</artifactId> </dependency> </dependencies>
Add properties in application.yml using the values you created earlier, for example:
spring: cloud: azure: active-directory: b2c: authenticate-additional-parameters: domain_hint: xxxxxxxxx # optional login_hint: xxxxxxxxx # optional prompt: [login,none,consent] # optional base-uri: ${BASE_URI} credential: client-id: ${WEBAPP_AZURE_CLIENT_ID} client-secret: ${WEBAPP_AZURE_CLIENT_SECRET} login-flow: ${LOGIN_USER_FLOW_KEY} # default to sign-up-or-sign-in, will look up the user-flows map with provided key. logout-success-url: ${LOGOUT_SUCCESS_URL} user-flows: ${YOUR_USER_FLOW_KEY}: ${USER_FLOW_NAME} user-name-attribute-name: ${USER_NAME_ATTRIBUTE_NAME}
Write your Java code.
Controller code can refer to the following:
@Controller public class WebController { private void initializeModel(Model model, OAuth2AuthenticationToken token) { if (token != null) { final OAuth2User user = token.getPrincipal(); model.addAllAttributes(user.getAttributes()); model.addAttribute("grant_type", user.getAuthorities()); model.addAttribute("name", user.getName()); } } @GetMapping(value = { "/", "/home" }) public String index(Model model, OAuth2AuthenticationToken token) { initializeModel(model, token); return "home"; } }
Security configuration code can refer to the following:
@EnableWebSecurity public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { private final AadB2cOidcLoginConfigurer configurer; public WebSecurityConfiguration(AadB2cOidcLoginConfigurer configurer) { this.configurer == configurer; } @Override protected void configure(HttpSecurity http) throws Exception { // @formatter:off http.authorizeRequests() .anyRequest().authenticated() .and() .apply(configurer); // @formatter:off } }
Copy the home.html from aad-b2c-web-application sample, and replace the
PROFILE_EDIT_USER_FLOW
andPASSWORD_RESET_USER_FLOW
with your user flow name respectively that completed earlier.Build and test your app
Let
Webapp
run on port 8080.After your application is built and started by Maven, open
http://localhost:8080/
in a web browser; you should be redirected to login page.Click link with the login user flow, you should be redirected Azure AD B2C to start the authentication process.
After you have logged in successfully, you should see the sample
home page
from the browser.
Usage 2: Web application accessing resource servers
This scenario is based on Accessing a web application scenario to allow application to access other resources, that is The OAuth 2.0 client credentials grant flow.
Select Azure AD B2C from the portal menu, click Applications, and then click Add.
Specify your application Name, we call it
webApiA
, record the Application ID as yourWEB_API_A_AZURE_CLIENT_ID
and then click Save.Select Keys from your application, click Generate key to generate
WEB_API_A_AZURE_CLIENT_SECRET
and then Save.Select Expose an API on your left, and then Click the Set link, record the Application ID URI as your
WEB_API_A_APP_ID_URL
, then Save.Select Manifest on your left, and then paste the following json segment into
appRoles
array, record the Application ID URI as yourWEB_API_A_APP_ID_URL
, record the value of the app role as yourWEB_API_A_ROLE_VALUE
, then save.{ "allowedMemberTypes": [ "Application" ], "description": "WebApiA.SampleScope", "displayName": "WebApiA.SampleScope", "id": "04989db0-3efe-4db6-b716-ae378517d2b7", "isEnabled": true, "value": "WebApiA.SampleScope" }
Select API permissions > Add a permission > My APIs, select WebApiA application name, select Application Permissions, select WebApiA.SampleScope permission, select Add permission to complete the process.
Grant admin consent for WebApiA permissions.
Add the following dependency on the basis of Accessing a web application scenario.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency>
Add the following configuration on the basis of Accessing a web application scenario.
spring: cloud: azure: active-directory: b2c: base-uri: ${BASE_URI} # Such as: https://xxxxb2c.b2clogin.com profile: tenant-id: ${AZURE_TENANT_ID} authorization-clients: ${RESOURCE_SERVER_A_NAME}: authorization-grant-type: client_credentials scopes: ${WEB_API_A_APP_ID_URL}/.default
Write your
Webapp
Java code.Controller code can refer to the following:
class Demo { /** * Access to protected data from Webapp to WebApiA through client credential flow. The access token is obtained by webclient, or * <p>@RegisteredOAuth2AuthorizedClient("webApiA")</p>. In the end, these two approaches will be executed to * DefaultOAuth2AuthorizedClientManager#authorize method, get the access token. * * @return Respond to protected data from WebApi A. */ @GetMapping("/webapp/webApiA") public String callWebApiA() { String body = webClient .get() .uri(LOCAL_WEB_API_A_SAMPLE_ENDPOINT) .attributes(clientRegistrationId("webApiA")) .retrieve() .bodyToMono(String.class) .block(); LOGGER.info("Call callWebApiA(), request '/webApiA/sample' returned: {}", body); return "Request '/webApiA/sample'(WebApi A) returned a " + (body != null ? "success." : "failure."); } }
Security configuration code is the same with Accessing a web application scenario, another bean
webClient
is added as follows:public class SampleConfiguration { @Bean public WebClient webClient(OAuth2AuthorizedClientManager oAuth2AuthorizedClientManager) { ServletOAuth2AuthorizedClientExchangeFilterFunction function = new ServletOAuth2AuthorizedClientExchangeFilterFunction(oAuth2AuthorizedClientManager); return WebClient.builder() .apply(function.oauth2Configuration()) .build(); } }
See Accessing a resource server section to write your
WebApiA
Java code.Build and test your app
Let
Webapp
andWebApiA
run on port 8080 and 8081 respectively. StartWebapp
andWebApiA
application, return to the home page after logging successfully, you can accesshttp://localhost:8080/webapp/webApiA
to get WebApiA resource response.
Usage 3: Accessing a resource server
This scenario not support login. Just protect the server by validating the access token, and if valid, serves the request.
Refer to Usage 2: Web Application Accessing Resource Servers to build your
WebApiA
permission.Add
WebApiA
permission and grant admin consent for your web application.Add the following dependencies in your pom.xml.
<dependencies> <dependency> <groupId>com.azure.spring</groupId> <artifactId>azure-spring-boot-starter-active-directory-b2c</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
Add the following configuration.
spring: cloud: azure: active-directory: b2c: base-uri: ${BASE_URI} # Such as: https://xxxxb2c.b2clogin.com profile: tenant-id: ${AZURE_TENANT_ID} app-id-uri: ${APP_ID_URI} # If you're using v1.0 token, configure app-id-uri for `aud` verification credential: client-id: ${AZURE_CLIENT_ID} # If you're using v2.0 token, configure client-id for `aud` verification
Write your Java code.
Controller code can refer to the following:
class Demo { /** * webApiA resource api for web app * @return test content */ @PreAuthorize("hasAuthority('APPROLE_WebApiA.SampleScope')") @GetMapping("/webApiA/sample") public String webApiASample() { LOGGER.info("Call webApiASample()"); return "Request '/webApiA/sample'(WebApi A) returned successfully."; } }
Security configuration code can refer to the following:
@EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class ResourceServerConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests((requests) -> requests.anyRequest().authenticated()) .oauth2ResourceServer() .jwt() .jwtAuthenticationConverter(new AadJwtBearerTokenAuthenticationConverter()); } }
Build and test your app
Let
WebApiA
run on port 8081. Get the access token forwebApiA
resource and accesshttp://localhost:8081/webApiA/sample
as the Bearer authorization header.
Usage 4: Resource server accessing other resource servers
This scenario is an upgrade of Accessing a resource server, supports access to other application resources, based on OAuth2 client credentials flow.
Referring to the previous steps, we create a
WebApiB
application and expose an application permissionWebApiB.SampleScope
.{ "allowedMemberTypes": [ "Application" ], "description": "WebApiB.SampleScope", "displayName": "WebApiB.SampleScope", "id": "04989db0-3efe-4db6-b716-ae378517d2b7", "isEnabled": true, "lang": null, "origin": "Application", "value": "WebApiB.SampleScope" }
Grant admin consent for WebApiB permissions.
On the basis of Accessing a resource server, add a dependency in your pom.xml.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency>
Add the following configuration on the basis of Accessing a resource server scenario configuration.
spring: cloud: azure: active-directory: b2c: credential: client-secret: ${WEB_API_A_AZURE_CLIENT_SECRET} authorization-clients: ${RESOURCE_SERVER_B_NAME}: authorization-grant-type: client_credentials scopes: ${WEB_API_B_APP_ID_URL}/.default
Write your Java code.
WebApiA controller code can refer to the following:
public class SampleController { /** * Access to protected data from WebApiA to WebApiB through client credential flow. The access token is obtained by webclient, or * <p>@RegisteredOAuth2AuthorizedClient("webApiA")</p>. In the end, these two approaches will be executed to * DefaultOAuth2AuthorizedClientManager#authorize method, get the access token. * * @return Respond to protected data from WebApi B. */ @GetMapping("/webApiA/webApiB/sample") @PreAuthorize("hasAuthority('APPROLE_WebApiA.SampleScope')") public String callWebApiB() { String body = webClient .get() .uri(LOCAL_WEB_API_B_SAMPLE_ENDPOINT) .attributes(clientRegistrationId("webApiB")) .retrieve() .bodyToMono(String.class) .block(); LOGGER.info("Call callWebApiB(), request '/webApiB/sample' returned: {}", body); return "Request 'webApiA/webApiB/sample'(WebApi A) returned a " + (body != null ? "success." : "failure."); } }
WebApiB controller code can refer to the following:
public class SampleController { /** * webApiB resource api for other web application * @return test content */ @PreAuthorize("hasAuthority('APPROLE_WebApiB.SampleScope')") @GetMapping("/webApiB/sample") public String webApiBSample() { LOGGER.info("Call webApiBSample()"); return "Request '/webApiB/sample'(WebApi B) returned successfully."; } }
Security configuration code is the same with Accessing a resource server scenario, another bean
webClient
is added as followspublic class SampleConfiguration { @Bean public WebClient webClient(OAuth2AuthorizedClientManager oAuth2AuthorizedClientManager) { ServletOAuth2AuthorizedClientExchangeFilterFunction function = new ServletOAuth2AuthorizedClientExchangeFilterFunction(oAuth2AuthorizedClientManager); return WebClient.builder() .apply(function.oauth2Configuration()) .build(); } }
Build and test your app
Let
WebApiA
andWebApiB
run on port 8081 and 8082 respectively. StartWebApiA
andWebApiB
application, get the access token forwebApiA
resource and accesshttp://localhost:8081/webApiA/webApiB/sample
as the Bearer authorization header.
Samples
See spring-cloud-azure-starter-active-directory-b2c samples for more details.
Spring Integration support
Spring Integration Extension for Azure provides Spring Integration adapters for the various services provided by the Azure SDK for Java. We provide Spring Integration support for these Azure services: Event Hubs, Service Bus, Storage Queue. The following is a list of supported adapters:
spring-cloud-azure-starter-integration-eventhubs
- for more information, see Spring Integration with Azure Event Hubsspring-cloud-azure-starter-integration-servicebus
- for more information, see Spring Integration with Azure Service Busspring-cloud-azure-starter-integration-storage-queue
- for more information, see Spring Integration with Azure Storage Queue
Spring Integration with Azure Event Hubs
Key concepts
Azure Event Hubs is a big data streaming platform and event ingestion service. It can receive and process millions of events per second. Data sent to an event hub can be transformed and stored by using any real-time analytics provider or batching/storage adapters.
Spring Integration enables lightweight messaging within Spring-based applications and supports integration with external systems via declarative adapters. Those adapters provide a higher-level of abstraction over Spring's support for remoting, messaging, and scheduling. The Spring Integration for Event Hubs extension project provides inbound and outbound channel adapters and gateways for Azure Event Hubs.
Note
RxJava support APIs are dropped from version 4.0.0. See Javadoc for details.
Consumer group
Event Hubs provides similar support of consumer group as Apache Kafka, but with slight different logic. While Kafka stores all committed offsets in the broker, you have to store offsets of Event Hubs messages being processed manually. Event Hubs SDK provides the function to store such offsets inside Azure Storage.
Partitioning support
Event Hubs provides a similar concept of physical partition as Kafka. But unlike Kafka's auto re-balancing between consumers and partitions, Event Hubs provides a kind of preemptive mode. The storage account acts as a lease to determine which partition is owned by which consumer. When a new consumer starts, it will try to steal some partitions from most heavy-loaded consumers to achieve the workload balancing.
To specify the load balancing strategy, developers can use EventHubsContainerProperties
for the configuration. See the following section for an example of how to configure EventHubsContainerProperties
.
Batch consumer support
The EventHubsInboundChannelAdapter
supports the batch-consuming mode. To enable it, users can specify the listener mode as ListenerMode.BATCH
when constructing an EventHubsInboundChannelAdapter
instance.
When enabled, an Message of which the payload is a list of batched events will be received and passed to the downstream channel. Each message header is also converted as a list, of which the content is the associated header value parsed from each event. For the communal headers of partition ID, checkpointer and last enqueued properties, they are presented as a single value for the entire batch of events shares the same one. See Event Hubs Message Headers for more details.
Note
The checkpoint header only exists when MANUAL checkpoint mode is used.
Checkpointing of batch consumer supports two modes: BATCH
and MANUAL
. BATCH
mode is an auto checkpointing mode to checkpoint the entire batch of events together once they are received. MANUAL
mode is to checkpoint the events by users. When used, the
Checkpointer will be passed into the message header, and users could use it to do checkpointing.
The batch consuming policy can be specified by properties of max-size
and max-wait-time
, where max-size
is a necessary property while max-wait-time
is optional.
To specify the batch consuming strategy, developers can use EventHubsContainerProperties
for the configuration. See the following section for an example of how to configure EventHubsContainerProperties
.
Dependency setup
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-integration-eventhubs</artifactId>
</dependency>
Configuration
This starter provides the following 3 parts of configuration options:
Connection Configuration Properties
This section contains the configuration options used for connecting to Azure Event Hubs.
Note
If you choose to use a security principal to authenticate and authorize with Azure Active Directory for accessing an Azure resource, see Authorize access with Azure AD to make sure the security principal has been granted the sufficient permission to access the Azure resource.
Connection configurable properties of spring-cloud-azure-starter-integration-eventhubs:
Property | Type | Description |
---|---|---|
spring.cloud.azure.eventhubs.enabled | boolean | Whether an Azure Event Hubs is enabled. |
spring.cloud.azure.eventhubs.connection-string | String | Event Hubs Namespace connection string value. |
spring.cloud.azure.eventhubs.namespace | String | Event Hubs Namespace value, which is the prefix of the FQDN. A FQDN should be composed of NamespaceName.DomainName |
spring.cloud.azure.eventhubs.domain-name | String | Domain name of an Azure Event Hubs Namespace value. |
spring.cloud.azure.eventhubs.custom-endpoint-address | String | Custom Endpoint address. |
spring.cloud.azure.eventhubs.shared-connection | Boolean | Whether the underlying EventProcessorClient and EventHubProducerAsyncClient use the same connection. By default, a new connection is constructed and used created for each Event Hub client created. |
Checkpoint Configuration Properties
This section contains the configuration options for the Storage Blobs service, which is used for persisting partition ownership and checkpoint information.
Note
From version 4.0.0, when the property of spring.cloud.azure.eventhubs.processor.checkpoint-store.create-container-if-not-exists is not enabled manually, no Storage container will be created automatically.
Checkpointing configurable properties of spring-cloud-azure-starter-integration-eventhubs:
Property | Type | Description |
---|---|---|
spring.cloud.azure.eventhubs.processor.checkpoint-store.create-container-if-not-exists | Boolean | Whether to allow creating containers if not exists. |
spring.cloud.azure.eventhubs.processor.checkpoint-store.account-name | String | Name for the storage account. |
spring.cloud.azure.eventhubs.processor.checkpoint-store.account-key | String | Storage account access key. |
spring.cloud.azure.eventhubs.processor.checkpoint-store.container-name | String | Storage container name. |
Common Azure Service SDK configuration options are configurable for Storage Blob checkpoint store as well. The supported configuration options are introduced in the Configuration page, and could be configured with either the unified prefix spring.cloud.azure.
or the prefix of spring.cloud.azure.eventhubs.processor.checkpoint-store
.
Event Hub processor configuration properties
The EventHubsInboundChannelAdapter
uses the EventProcessorClient
to consume messages from an event hub, to configure the overall properties of an EventProcessorClient
,
developers can use EventHubsContainerProperties
for the configuration. See the following section about how to work with EventHubsInboundChannelAdapter
.
Basic usage
Send messages to Azure Event Hubs
Fill the credential configuration options.
- For credentials as connection string, configure the following properties in
application.yml
:
spring: cloud: azure: eventhubs: connection-string: ${AZURE_SERVICE_BUS_CONNECTION_STRING} processor: checkpoint-store: container-name: ${CHECKPOINT-CONTAINER} account-name: ${CHECKPOINT-STORAGE-ACCOUNT} account-key: ${CHECKPOINT-ACCESS-KEY}
- For credentials as managed identities, configure the following properties in
application.yml
:
spring: cloud: azure: credential: managed-identity-enabled: true client-id: ${AZURE_CLIENT_ID} eventhubs: namespace: ${AZURE_SERVICE_BUS_NAMESPACE} processor: checkpoint-store: container-name: ${CONTAINER_NAME} account-name: ${ACCOUNT_NAME}
- For credentials as service principal, configure the following properties in application.yml:
spring: cloud: azure: credential: client-id: ${AZURE_CLIENT_ID} client-secret: ${AZURE_CLIENT_SECRET} profile: tenant-id: ${AZURE_TENANT_ID} eventhubs: namespace: ${AZURE_SERVICE_BUS_NAMESPACE} processor: checkpoint-store: container-name: ${CONTAINER_NAME} account-name: ${ACCOUNT_NAME}
- For credentials as connection string, configure the following properties in
Create
DefaultMessageHandler
with theEventHubsTemplate
bean to send messages to Event Hubs.class Demo { private static final String OUTPUT_CHANNEL = "output"; private static final String EVENTHUB_NAME = "eh1"; @Bean @ServiceActivator(inputChannel = OUTPUT_CHANNEL) public MessageHandler messageSender(EventHubsTemplate eventHubsTemplate) { DefaultMessageHandler handler = new DefaultMessageHandler(EVENTHUB_NAME, eventHubsTemplate); handler.setSendCallback(new ListenableFutureCallback<Void>() { @Override public void onSuccess(Void result) { LOGGER.info("Message was sent successfully."); } @Override public void onFailure(Throwable ex) { LOGGER.error("There was an error sending the message.", ex); } }); return handler; } }
Create a message gateway binding with the above message handler via a message channel.
class Demo { @Autowired EventHubOutboundGateway messagingGateway; @MessagingGateway(defaultRequestChannel = OUTPUT_CHANNEL) public interface EventHubOutboundGateway { void send(String text); } }
Send messages using the gateway.
class Demo { public void demo() { this.messagingGateway.send(message); } }
Receive messages from Azure Event Hubs
Fill the credential configuration options.
Create a bean of message channel as the input channel.
@Configuration class Demo { @Bean public MessageChannel input() { return new DirectChannel(); } }
Create
EventHubsInboundChannelAdapter
with theEventHubsMessageListenerContainer
bean to receive messages from Event Hubs.@Configuration class Demo { private static final String INPUT_CHANNEL = "input"; private static final String EVENTHUB_NAME = "eh1"; private static final String CONSUMER_GROUP = "$Default"; @Bean public EventHubsInboundChannelAdapter messageChannelAdapter( @Qualifier(INPUT_CHANNEL) MessageChannel inputChannel, EventHubsMessageListenerContainer listenerContainer) { EventHubsInboundChannelAdapter adapter = new EventHubsInboundChannelAdapter(processorContainer); adapter.setOutputChannel(inputChannel); return adapter; } @Bean public EventHubsMessageListenerContainer messageListenerContainer(EventHubsProcessorFactory processorFactory) { EventHubsContainerProperties containerProperties = new EventHubsContainerProperties(); containerProperties.setEventHubName(EVENTHUB_NAME); containerProperties.setConsumerGroup(CONSUMER_GROUP); containerProperties.setCheckpointConfig(new CheckpointConfig(CheckpointMode.MANUAL)); return new EventHubsMessageListenerContainer(processorFactory, containerProperties); } }
Create a message receiver binding with EventHubsInboundChannelAdapter via the message channel created before.
class Demo { @ServiceActivator(inputChannel = INPUT_CHANNEL) public void messageReceiver(byte[] payload, @Header(AzureHeaders.CHECKPOINTER) Checkpointer checkpointer) { String message = new String(payload); LOGGER.info("New message received: '{}'", message); checkpointer.success() .doOnSuccess(s -> LOGGER.info("Message '{}' successfully checkpointed", message)) .doOnError(e -> LOGGER.error("Error found", e)) .block(); } }
Configure EventHubsMessageConverter to customize objectMapper
EventHubsMessageConverter
is made as a configurable bean to allow users to customize ObjectMapper.
Batch consumer support
To consume messages from Event Hubs in batches is similar with the above sample, besides users should set the batch-consuming related configuration options for EventHubsInboundChannelAdapter
.
When create EventHubsInboundChannelAdapter
, the listener mode should be set as BATCH
. When create bean of EventHubsMessageListenerContainer
, set the checkpoint mode as either MANUAL
or BATCH
, and the batch options can be configured as needed.
@Configuration
class Demo {
private static final String INPUT_CHANNEL = "input";
private static final String EVENTHUB_NAME = "eh1";
private static final String CONSUMER_GROUP = "$Default";
@Bean
public EventHubsInboundChannelAdapter messageChannelAdapter(
@Qualifier(INPUT_CHANNEL) MessageChannel inputChannel,
EventHubsMessageListenerContainer listenerContainer) {
EventHubsInboundChannelAdapter adapter = new EventHubsInboundChannelAdapter(processorContainer, ListenerMode.BATCH);
adapter.setOutputChannel(inputChannel);
return adapter;
}
@Bean
public EventHubsMessageListenerContainer messageListenerContainer(EventHubsProcessorFactory processorFactory) {
EventHubsContainerProperties containerProperties = new EventHubsContainerProperties();
containerProperties.setEventHubName(EVENTHUB_NAME);
containerProperties.setConsumerGroup(CONSUMER_GROUP);
containerProperties.getBatch().setMaxSize(100);
containerProperties.setCheckpointConfig(new CheckpointConfig(CheckpointMode.MANUAL));
return new EventHubsMessageListenerContainer(processorFactory, containerProperties);
}
}
Event Hubs message headers
The following table illustrates how Event Hubs message properties are mapped to Spring message headers. For Azure Event Hubs, message is called as event
.
Mapping between Event Hubs Message / Event Properties and Spring Message Headers in Record Listener Mode:
Event Hubs Event Properties | Spring Message Header Constants | Type | Description |
---|---|---|---|
Enqueued time | EventHubsHeaders#ENQUEUED_TIME | Instant | The instant, in UTC, of when the event was enqueued in the Event Hub partition. |
Offset | EventHubsHeaders#OFFSET | Long | The offset of the event when it was received from the associated Event Hub partition. |
Partition key | AzureHeaders#PARTITION_KEY | String | The partition hashing key if it was set when originally publishing the event. |
Partition ID | AzureHeaders#RAW_PARTITION_ID | String | The partition ID of the Event Hub. |
Sequence number | EventHubsHeaders#SEQUENCE_NUMBER | Long | The sequence number assigned to the event when it was enqueued in the associated Event Hub partition. |
Last enqueued event properties | EventHubsHeaders#LAST_ENQUEUED_EVENT_PROPERTIES | LastEnqueuedEventProperties | The properties of the last enqueued event in this partition. |
NA | AzureHeaders#CHECKPOINTER | Checkpointer | The header for checkpoint the specific message. |
Users can parse the message headers for the related information of each event. To set a message header for the event, all customized headers will be put as an application property of an event, where the header is set as the property key. When events are received from Event Hubs, all application properties will be converted to the message header.
Note
Message headers of partition key, enqueued time, offset and sequence number is not supported to be set manually.
When the batch-consumer mode is enabled, the specific headers of batched messages are listed the follows, which contains a list of values from each single Event Hubs event.
Mapping between Event Hubs Message / Event Properties and Spring Message Headers in Batch Listener Mode:
Event Hubs Event Properties | Spring Batch Message Header Constants | Type | Description |
---|---|---|---|
Enqueued time | EventHubsHeaders#ENQUEUED_TIME | List of Instant | List of the instant, in UTC, of when each event was enqueued in the Event Hub partition. |
Offset | EventHubsHeaders#OFFSET | List of Long | List of the offset of each event when it was received from the associated Event Hub partition. |
Partition key | AzureHeaders#PARTITION_KEY | List of String | List of the partition hashing key if it was set when originally publishing each event. |
Sequence number | EventHubsHeaders#SEQUENCE_NUMBER | List of Long | List of the sequence number assigned to each event when it was enqueued in the associated Event Hub partition. |
System properties | EventHubsHeaders#BATCH_CONVERTED_SYSTEM_PROPERTIES | List of Map | List of the system properties of each event. |
Application properties | EventHubsHeaders#BATCH_CONVERTED_APPLICATION_PROPERTIES | List of Map | List of the application properties of each event, where all customized message headers or event properties are placed. |
Note
When publish messages, all the above batch headers will be removed from the messages if exist.
Samples
See azure-spring-boot-samples for more details.
Spring Integration with Azure Service Bus
Key concepts
Spring Integration enables lightweight messaging within Spring-based applications and supports integration with external systems via declarative adapters.
The Spring Integration for Azure Service Bus extension project provides inbound and outbound channel adapters for Azure Service Bus.
Note
CompletableFuture support APIs have been deprecated from version 2.10.0, and is replaced by Reactor Core from version 4.0.0. See Javadoc for details.
Dependency setup
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-integration-servicebus</artifactId>
</dependency>
Configuration
This starter provides the following 2 parts of configuration options:
Connection configuration properties
This section contains the configuration options used for connecting to Azure Service Bus.
Note
If you choose to use a security principal to authenticate and authorize with Azure Active Directory for accessing an Azure resource, see Authorize access with Azure AD to make sure the security principal has been granted the sufficient permission to access the Azure resource.
Connection configurable properties of spring-cloud-azure-starter-integration-servicebus:
Property | Type | Description |
---|---|---|
spring.cloud.azure.servicebus.enabled | boolean | Whether an Azure Service Bus is enabled. |
spring.cloud.azure.servicebus.connection-string | String | Service Bus Namespace connection string value. |
spring.cloud.azure.servicebus.namespace | String | Service Bus Namespace value, which is the prefix of the FQDN. A FQDN should be composed of NamespaceName.DomainName |
spring.cloud.azure.servicebus.domain-name | String | Domain name of an Azure Service Bus Namespace value. |
Service Bus processor configuration properties
The ServiceBusInboundChannelAdapter
uses the ServiceBusProcessorClient
to consume messages, to configure the overall properties of an ServiceBusProcessorClient
,
developers can use ServiceBusContainerProperties
for the configuration. See the following section about how to work with ServiceBusInboundChannelAdapter
.
Basic usage
Send messages to Azure Service Bus
Fill the credential configuration options.
- For credentials as connection string, configure the following properties in application.yml:
spring: cloud: azure: servicebus: connection-string: ${AZURE_SERVICE_BUS_CONNECTION_STRING}
- For credentials as managed identities, configure the following properties in application.yml:
spring: cloud: azure: credential: managed-identity-enabled: true client-id: ${AZURE_CLIENT_ID} profile: tenant-id: ${AZURE_TENANT_ID} servicebus: namespace: ${AZURE_SERVICE_BUS_NAMESPACE}
For credentials as service principal, configure the following properties in application.yml:
spring: cloud: azure: credential: client-id: ${AZURE_CLIENT_ID} client-secret: ${AZURE_CLIENT_SECRET} profile: tenant-id: ${AZURE_TENANT_ID} servicebus: namespace: ${AZURE_SERVICE_BUS_NAMESPACE}
Create
DefaultMessageHandler
with theServiceBusTemplate
bean to send messages to Service Bus, set the entity type for the ServiceBusTemplate. This sample takes Service Bus Queue as example.class Demo { private static final String OUTPUT_CHANNEL = "queue.output"; @Bean @ServiceActivator(inputChannel = OUTPUT_CHANNEL) public MessageHandler queueMessageSender(ServiceBusTemplate serviceBusTemplate) { serviceBusTemplate.setDefaultEntityType(ServiceBusEntityType.QUEUE); DefaultMessageHandler handler = new DefaultMessageHandler(QUEUE_NAME, serviceBusTemplate); handler.setSendCallback(new ListenableFutureCallback<Void>() { @Override public void onSuccess(Void result) { LOGGER.info("Message was sent successfully."); } @Override public void onFailure(Throwable ex) { LOGGER.info("There was an error sending the message."); } }); return handler; } }
Create a message gateway binding with the above message handler via a message channel.
class Demo { @Autowired QueueOutboundGateway messagingGateway; @MessagingGateway(defaultRequestChannel = OUTPUT_CHANNEL) public interface QueueOutboundGateway { void send(String text); } }
Send messages using the gateway.
class Demo { public void demo() { this.messagingGateway.send(message); } }
Receive messages from Azure Service Bus
Fill the credential configuration options.
Create a bean of message channel as the input channel.
@Configuration class Demo { private static final String INPUT_CHANNEL = "input"; @Bean public MessageChannel input() { return new DirectChannel(); } }
Create
ServiceBusInboundChannelAdapter
with theServiceBusMessageListenerContainer
bean to receive messages to Service Bus. This sample takes Service Bus Queue as example.@Configuration class Demo { private static final String QUEUE_NAME = "queue1"; @Bean public ServiceBusMessageListenerContainer messageListenerContainer(ServiceBusProcessorFactory processorFactory) { ServiceBusContainerProperties containerProperties = new ServiceBusContainerProperties(); containerProperties.setEntityName(QUEUE_NAME); containerProperties.setAutoComplete(false); return new ServiceBusMessageListenerContainer(processorFactory, containerProperties); } @Bean public ServiceBusInboundChannelAdapter queueMessageChannelAdapter( @Qualifier(INPUT_CHANNEL) MessageChannel inputChannel, ServiceBusMessageListenerContainer listenerContainer) { ServiceBusInboundChannelAdapter adapter = new ServiceBusInboundChannelAdapter(listenerContainer); adapter.setOutputChannel(inputChannel); return adapter; } }
Create a message receiver binding with ServiceBusInboundChannelAdapter via the message channel we created before.
class Demo { @ServiceActivator(inputChannel = INPUT_CHANNEL) public void messageReceiver(byte[] payload, @Header(AzureHeaders.CHECKPOINTER) Checkpointer checkpointer) { String message = new String(payload); LOGGER.info("New message received: '{}'", message); checkpointer.success() .doOnSuccess(s -> LOGGER.info("Message '{}' successfully checkpointed", message)) .doOnError(e -> LOGGER.error("Error found", e)) .block(); } }
Configure ServiceBusMessageConverter to customize objectMapper
ServiceBusMessageConverter
is made as a configurable bean to allow users to customize ObjectMapper.
Service Bus message headers
For some Service Bus headers that can be mapped to multiple Spring header constants, the priority of different Spring headers is listed.
Mapping between Service Bus Headers and Spring Headers:
Service Bus Message Headers and Properties | Spring Message Header Constants | Type | Configurable | Description |
---|---|---|---|---|
Content type | MessageHeaders#CONTENT_TYPE | String | Yes | The RFC2045 Content-Type descriptor of the message. |
Correlation ID | ServiceBusMessageHeaders#CORRELATION_ID | String | Yes | The correlation ID of the message |
Message ID | ServiceBusMessageHeaders#MESSAGE_ID | String | Yes | The message ID of the message, this header has higher priority than MessageHeaders#ID . |
Message ID | MessageHeaders#ID | UUID | Yes | The message ID of the message, this header has lower priority than ServiceBusMessageHeaders#MESSAGE_ID . |
Partition key | ServiceBusMessageHeaders#PARTITION_KEY | String | Yes | The partition key for sending the message to a partitioned entity. |
Reply to | MessageHeaders#REPLY_CHANNEL | String | Yes | The address of an entity to send replies to. |
Reply to session ID | ServiceBusMessageHeaders#REPLY_TO_SESSION_ID | String | Yes | The ReplyToGroupId property value of the message. |
Scheduled enqueue time utc | ServiceBusMessageHeaders#SCHEDULED_ENQUEUE_TIME | OffsetDateTime | Yes | The datetime at which the message should be enqueued in Service Bus, this header has higher priority than AzureHeaders#SCHEDULED_ENQUEUE_MESSAGE . |
Scheduled enqueue time utc | AzureHeaders#SCHEDULED_ENQUEUE_MESSAGE | Integer | Yes | The datetime at which the message should be enqueued in Service Bus, this header has lower priority than ServiceBusMessageHeaders#SCHEDULED_ENQUEUE_TIME . |
Session ID | ServiceBusMessageHeaders#SESSION_ID | String | Yes | The session IDentifier for a session-aware entity. |
Time to live | ServiceBusMessageHeaders#TIME_TO_LIVE | Duration | Yes | The duration of time before this message expires. |
To | ServiceBusMessageHeaders#TO | String | Yes | The "to" address of the message, reserved for future use in routing scenarios and presently ignored by the broker itself. |
Subject | ServiceBusMessageHeaders#SUBJECT | String | Yes | The subject for the message. |
Dead letter error description | ServiceBusMessageHeaders#DEAD_LETTER_ERROR_DESCRIPTION | String | No | The description for a message that has been dead-lettered. |
Dead letter reason | ServiceBusMessageHeaders#DEAD_LETTER_REASON | String | No | The reason a message was dead-lettered. |
Dead letter source | ServiceBusMessageHeaders#DEAD_LETTER_SOURCE | String | No | The entity in which the message was dead-lettered. |
Delivery count | ServiceBusMessageHeaders#DELIVERY_COUNT | long | No | The number of the times this message was delivered to clients. |
Enqueued sequence number | ServiceBusMessageHeaders#ENQUEUED_SEQUENCE_NUMBER | long | No | The enqueued sequence number assigned to a message by Service Bus. |
Enqueued time | ServiceBusMessageHeaders#ENQUEUED_TIME | OffsetDateTime | No | The datetime at which this message was enqueued in Service Bus. |
Expires at | ServiceBusMessageHeaders#EXPIRES_AT | OffsetDateTime | No | The datetime at which this message will expire. |
Lock token | ServiceBusMessageHeaders#LOCK_TOKEN | String | No | The lock token for the current message. |
Locked until | ServiceBusMessageHeaders#LOCKED_UNTIL | OffsetDateTime | No | The datetime at which the lock of this message expires. |
Sequence number | ServiceBusMessageHeaders#SEQUENCE_NUMBER | long | No | The unique number assigned to a message by Service Bus. |
State | ServiceBusMessageHeaders#STATE | ServiceBusMessageState | No | The state of the message, which can be Active, Deferred, or Scheduled. |
Partition key support
This starter supports Service Bus partitioning by allowing setting partition key and session ID in the message header. This section introduces how to set partition key for messages.
Recommended: Use ServiceBusMessageHeaders.PARTITION_KEY
as the key of the header.
public class SampleController {
@PostMapping("/messages")
public ResponseEntity<String> sendMessage(@RequestParam String message) {
LOGGER.info("Going to add message {} to Sinks.Many.", message);
many.emitNext(MessageBuilder.withPayload(message)
.setHeader(ServiceBusMessageHeaders.PARTITION_KEY, "Customize partition key")
.build(), Sinks.EmitFailureHandler.FAIL_FAST);
return ResponseEntity.ok("Sent!");
}
}
Not recommended but currently supported: AzureHeaders.PARTITION_KEY
as the key of the header.
public class SampleController {
@PostMapping("/messages")
public ResponseEntity<String> sendMessage(@RequestParam String message) {
LOGGER.info("Going to add message {} to Sinks.Many.", message);
many.emitNext(MessageBuilder.withPayload(message)
.setHeader(AzureHeaders.PARTITION_KEY, "Customize partition key")
.build(), Sinks.EmitFailureHandler.FAIL_FAST);
return ResponseEntity.ok("Sent!");
}
}
Note
When both ServiceBusMessageHeaders.PARTITION_KEY
and AzureHeaders.PARTITION_KEY
are set in the message headers,
ServiceBusMessageHeaders.PARTITION_KEY
is preferred.
Session support
This example demonstrates how to manually set the session ID of a message in the application.
public class SampleController {
@PostMapping("/messages")
public ResponseEntity<String> sendMessage(@RequestParam String message) {
LOGGER.info("Going to add message {} to Sinks.Many.", message);
many.emitNext(MessageBuilder.withPayload(message)
.setHeader(ServiceBusMessageHeaders.SESSION_ID, "Customize session ID")
.build(), Sinks.EmitFailureHandler.FAIL_FAST);
return ResponseEntity.ok("Sent!");
}
}
Note
When the ServiceBusMessageHeaders.SESSION_ID
is set in the message headers, and a different ServiceBusMessageHeaders.PARTITION_KEY
(or AzureHeaders.PARTITION_KEY
) header is also set, the value of the session ID will eventually be used to overwrite the value of the partition key.
Samples
See azure-spring-boot-samples for more details.
Spring Integration with Azure Storage Queue
Key concepts
Azure Queue Storage is a service for storing large numbers of messages. You access messages from anywhere in the world via authenticated calls using HTTP or HTTPS. A queue message can be up to 64 KB in size. A queue may contain millions of messages, up to the total capacity limit of a storage account. Queues are commonly used to create a backlog of work to process asynchronously.
Dependency setup
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-integration-storage-queue</artifactId>
</dependency>
Configuration
This starter provides the following configuration options:
Connection configuration properties
This section contains the configuration options used for connecting to Azure Storage Queue.
Note
If you choose to use a security principal to authenticate and authorize with Azure Active Directory for accessing an Azure resource, see Authorize access with Azure AD to make sure the security principal has been granted the sufficient permission to access the Azure resource.
Connection configurable properties of spring-cloud-azure-starter-integration-storage-queue:
Property | Type | Description |
---|---|---|
spring.cloud.azure.storage.queue.enabled | boolean | Whether an Azure Storage Queue is enabled. |
spring.cloud.azure.storage.queue.connection-string | String | Storage Queue Namespace connection string value. |
spring.cloud.azure.storage.queue.accountName | String | Storage Queue account name. |
spring.cloud.azure.storage.queue.accountKey | String | Storage Queue account key. |
spring.cloud.azure.storage.queue.endpoint | String | Storage Queue service endpoint. |
spring.cloud.azure.storage.queue.sasToken | String | Sas token credential |
spring.cloud.azure.storage.queue.serviceVersion | QueueServiceVersion | QueueServiceVersion that is used when making API requests. |
spring.cloud.azure.storage.queue.messageEncoding | String | Queue message encoding. |
Basic usage
Send messages to Azure Storage Queue
Fill the credential configuration options.
- For credentials as connection string, configure the following properties in application.yml:
spring: cloud: azure: storage: queue: connection-string: ${AZURE_SERVICE_BUS_CONNECTION_STRING}
- For credentials as managed identities, configure the following properties in application.yml:
spring: cloud: azure: credential: managed-identity-enabled: true client-id: ${AZURE_CLIENT_ID} profile: tenant-id: ${AZURE_TENANT_ID} storage: queue: namespace: ${AZURE_SERVICE_BUS_NAMESPACE}
- For credentials as service principal, configure the following properties in application.yml:
spring: cloud: azure: credential: client-id: ${AZURE_CLIENT_ID} client-secret: ${AZURE_CLIENT_SECRET} profile: tenant-id: ${AZURE_TENANT_ID} storage: queue: namespace: ${AZURE_SERVICE_BUS_NAMESPACE}
Create
DefaultMessageHandler
with theStorageQueueTemplate
bean to send messages to Storage Queue.class Demo { private static final String STORAGE_QUEUE_NAME = "example"; private static final String OUTPUT_CHANNEL = "output"; @Bean @ServiceActivator(inputChannel = OUTPUT_CHANNEL) public MessageHandler messageSender(StorageQueueTemplate storageQueueTemplate) { DefaultMessageHandler handler = new DefaultMessageHandler(STORAGE_QUEUE_NAME, storageQueueTemplate); handler.setSendCallback(new ListenableFutureCallback<Void>() { @Override public void onSuccess(Void result) { LOGGER.info("Message was sent successfully."); } @Override public void onFailure(Throwable ex) { LOGGER.info("There was an error sending the message."); } }); return handler; } }
Create a Message gateway binding with the above message handler via a message channel.
class Demo { @Autowired StorageQueueOutboundGateway storageQueueOutboundGateway; @MessagingGateway(defaultRequestChannel = OUTPUT_CHANNEL) public interface StorageQueueOutboundGateway { void send(String text); } }
Send messages using the gateway.
class Demo { public void demo() { this.storageQueueOutboundGateway.send(message); } }
Receive messages from Azure Storage Queue
Fill the credential configuration options.
Create a bean of message channel as the input channel.
class Demo { private static final String INPUT_CHANNEL = "input"; @Bean public MessageChannel input() { return new DirectChannel(); } }
Create
StorageQueueMessageSource
with theStorageQueueTemplate
bean to receive messages to Storage Queue.class Demo { private static final String STORAGE_QUEUE_NAME = "example"; @Bean @InboundChannelAdapter(channel = INPUT_CHANNEL, poller = @Poller(fixedDelay = "1000")) public StorageQueueMessageSource storageQueueMessageSource(StorageQueueTemplate storageQueueTemplate) { return new StorageQueueMessageSource(STORAGE_QUEUE_NAME, storageQueueTemplate); } }
Create a message receiver binding with StorageQueueMessageSource created in the last step via the message channel we created before.
class Demo { @ServiceActivator(inputChannel = INPUT_CHANNEL) public void messageReceiver(byte[] payload, @Header(AzureHeaders.CHECKPOINTER) Checkpointer checkpointer) { String message = new String(payload); LOGGER.info("New message received: '{}'", message); checkpointer.success() .doOnError(Throwable::printStackTrace) .doOnSuccess(t -> LOGGER.info("Message '{}' successfully checkpointed", message)) .block(); } }
Samples
See azure-spring-boot-samples for more details.
Spring Cloud Stream support
Spring Cloud Stream is a framework for building highly scalable event-driven microservices connected with shared messaging systems.
The framework provides a flexible programming model built on already established and familiar Spring idioms and best practices, including support for persistent pub/sub semantics, consumer groups, and stateful partitions.
Current binder implementations include:
spring-cloud-azure-stream-binder-eventhubs
- for more information, see Spring Cloud Stream Binder for Azure Event Hubsspring-cloud-azure-stream-binder-servicebus
- for more information, see Spring Cloud Stream Binder for Azure Service Bus
Spring Cloud Stream Binder for Azure Event Hubs
Key concepts
The Spring Cloud Stream Binder for Azure Event Hubs provides the binding implementation for the Spring Cloud Stream framework. This implementation uses Spring Integration Event Hubs Channel Adapters at its foundation. From design's perspective, Event Hubs is similar as Kafka. Also, Event Hubs could be accessed via Kafka API. If your project has tight dependency on Kafka API, you can try Events Hub with Kafka API Sample
Consumer group
Event Hubs provides similar support of consumer group as Apache Kafka, but with slight different logic. While Kafka stores all committed offsets in the broker, you have to store offsets of Event Hubs messages being processed manually. Event Hubs SDK provides the function to store such offsets inside Azure Storage.
Partitioning support
Event Hubs provides a similar concept of physical partition as Kafka. But unlike Kafka's auto re-balancing between consumers and partitions, Event Hubs provides a kind of preemptive mode. The storage account acts as a lease to determine which partition is owned by which consumer. When a new consumer starts, it will try to steal some partitions from most heavy-loaded consumers to achieve the workload balancing.
To specify the load balancing strategy, properties of spring.cloud.stream.eventhubs.bindings.<binding-name>.consumer.load-balancing.*
are provided. See Consumer properties section for more details.
Batch consumer support
Spring Cloud Azure Stream Event Hubs binder supports Spring Cloud Stream Batch Consumer feature.
To work with the batch-consumer mode, the property of spring.cloud.stream.bindings.<binding-name>.consumer.batch-mode
should be set as true
. When enabled, an Message of which the payload is a list of batched events will be received and passed to the Consumer
function. Each message header is also converted as a list, of which the content is the associated header value parsed from each event. For the communal headers of partition ID, checkpointer and last enqueued properties, they are presented as a single value for the entire batch of events shares the same one. See Event Hubs Message Headers for more details.
Note
The checkpoint header only exists when MANUAL checkpoint mode is used.
Checkpointing of batch consumer supports two modes: BATCH
and MANUAL
. BATCH
mode is an auto checkpointing mode to checkpoint the entire batch of events together once they are received by the binder. MANUAL
mode is to checkpoint the events by users. When used, the
Checkpointer will be passed into the message header, and users could use it to do checkpointing.
The batch size can be specified by properties of max-size
and max-wait-time
with prefix as spring.cloud.stream.eventhubs.bindings.<binding-name>.consumer.batch.
, where max-size
is a necessary property while max-wait-time
is optional. See Consumer properties section for more details.
Dependency setup
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-stream-binder-eventhubs</artifactId>
</dependency>
Alternatively, you can also use the Spring Cloud Azure Stream Event Hubs Starter, as shown in the following example for Maven:
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-stream-eventhubs</artifactId>
</dependency>
Configuration
The binder provides the following 3 parts of configuration options:
Connection configuration properties
This section contains the configuration options used for connecting to Azure Event Hubs.
Note
If you choose to use a security principal to authenticate and authorize with Azure Active Directory for accessing an Azure resource, refer to Authorize access with Azure AD to make sure the security principal has been granted the sufficient permission to access the Azure resource.
Connection configurable properties of spring-cloud-azure-stream-binder-eventhubs:
Property | Type | Description |
---|---|---|
spring.cloud.azure.eventhubs.enabled | boolean | Whether an Azure Event Hubs is enabled. |
spring.cloud.azure.eventhubs.connection-string | String | Event Hubs Namespace connection string value. |
spring.cloud.azure.eventhubs.namespace | String | Event Hubs Namespace value, which is the prefix of the FQDN. A FQDN should be composed of NamespaceName.DomainName |
spring.cloud.azure.eventhubs.domain-name | String | Domain name of an Azure Event Hubs Namespace value. |
spring.cloud.azure.eventhubs.custom-endpoint-address | String | Custom Endpoint address. |
Tip
Common Azure Service SDK configuration options are configurable for the Spring Cloud Azure Stream Event Hubs binder as well. The supported configuration options are introduced in the Configuration page, and could be configured with either the unified prefix spring.cloud.azure.
or the prefix of spring.cloud.azure.eventhubs.
.
The binder also supports Spring Could Azure Resource Manager by default. To learn about how to retrieve the connection string with security principals that are not granted with Data
related roles, refer to the resource manager example for details.
Checkpoint configuration properties
This section contains the configuration options for the Storage Blobs service, which is used for persisting partition ownership and checkpoint information.
Note
From version 4.0.0, when the property of spring.cloud.azure.eventhubs.processor.checkpoint-store.create-container-if-not-exists is not enabled manually, no Storage container will be created automatically with the name from spring.cloud.stream.bindings.binding-name.destination.
Checkpointing configurable properties of spring-cloud-azure-stream-binder-eventhubs:
Property | Type | Description |
---|---|---|
spring.cloud.azure.eventhubs.processor.checkpoint-store.create-container-if-not-exists | Boolean | Whether to allow creating containers if not exists. |
spring.cloud.azure.eventhubs.processor.checkpoint-store.account-name | String | Name for the storage account. |
spring.cloud.azure.eventhubs.processor.checkpoint-store.account-key | String | Storage account access key. |
spring.cloud.azure.eventhubs.processor.checkpoint-store.container-name | String | Storage container name. |
Tip
Common Azure Service SDK configuration options are configurable for Storage Blob checkpoint store as well. The supported configuration options are introduced in the Configuration page, and could be configured with either the unified prefix spring.cloud.azure.
or the prefix of spring.cloud.azure.eventhubs.processor.checkpoint-store
.
Azure Event Hubs Binding configuration properties
The following options are divided into four sections: Consumer Properties, Advanced Consumer Configurations, Producer Properties and Advanced Producer Configurations.
Consumer properties
These properties are exposed via EventHubsConsumerProperties
.
Consumer configurable properties of spring-cloud-azure-stream-binder-eventhubs:
Property | Type | Description |
---|---|---|
spring.cloud.stream.eventhubs.bindings.binding-name.consumer.checkpoint.mode | CheckpointMode | Checkpoint mode used when consumer decide how to checkpoint message |
spring.cloud.stream.eventhubs.bindings.binding-name.consumer.checkpoint.count | Integer | Decides the amount of message for each partition to do one checkpoint. Will take effect only when PARTITION_COUNT checkpoint mode is used. |
spring.cloud.stream.eventhubs.bindings.binding-name.consumer.checkpoint.interval | Duration | Decides the time interval to do one checkpoint. Will take effect only when TIME checkpoint mode is used. |
spring.cloud.stream.eventhubs.bindings.<binding-name.consumer.batch.max-size | Integer | The maximum number of events in a batch. Required for the batch-consumer mode. |
spring.cloud.stream.eventhubs.bindings.binding-name.consumer.batch.max-wait-time | Duration | The maximum time duration for batch consuming. Will take effect only when the batch-consumer mode is enabled and is optional. |
spring.cloud.stream.eventhubs.bindings.binding-name.consumer.load-balancing.update-interval | Duration | The interval time duration for updating. |
spring.cloud.stream.eventhubs.bindings.binding-name.consumer.load-balancing.strategy | LoadBalancingStrategy | The load balancing strategy. |
spring.cloud.stream.eventhubs.bindings.binding-name.consumer.load-balancing.partition-ownership-expiration-interval | Duration | The time duration after which the ownership of partition expires. |
spring.cloud.stream.eventhubs.bindings.binding-name.consumer.track-last-enqueued-event-properties | Boolean | Whether the event processor should request information on the last enqueued event on its associated partition, and track that information as events are received. |
spring.cloud.stream.eventhubs.bindings.binding-name.consumer.prefetch-count | Integer | The count used by the consumer to control the number of events the Event Hub consumer will actively receive and queue locally. |
spring.cloud.stream.eventhubs.bindings.binding-name.consumer.initial-partition-event-position | Map with the key as the partition ID, and values of StartPositionProperties |
The map containing the event position to use for each partition if a checkpoint for the partition does not exist in checkpoint store. This map is keyed off of the partition ID. |
Note
The initial-partition-event-position
configuration accepts a map
to specify the initial position for each event hub. Thus, its key is the partition ID, and the value is of StartPositionProperties
which includes properties of offset, sequence number, enqueued date time and whether inclusive. For example, you can set it as
spring:
cloud:
stream:
eventhubs:
bindings:
<binding-name>:
consumer:
initial-partition-event-position:
0:
offset: earliest
1:
sequence-number: 100
2:
enqueued-date-time: 2022-01-12T13:32:47.650005Z
4:
inclusive: false
Advanced consumer configuration
The above connection, checkpoint and common Azure SDK client configuration are supported to be customized for each binder consumer, which can be configured with the prefix spring.cloud.stream.eventhubs.bindings.<binding-name>.consumer.
.
Producer properties
These properties are exposed via EventHubsProducerProperties
.
Producer configurable properties of spring-cloud-azure-stream-binder-eventhubs:
Property | Type | Description |
---|---|---|
spring.cloud.stream.eventhubs.bindings.binding-name.producer.sync | boolean | The switch flag for sync of producer. If true, the producer will wait for a response after a send operation. |
spring.cloud.stream.eventhubs.bindings.binding-name.producer.send-timeout | long | The amount of time to wait for a response after a send operation. Will take effect only when a sync producer is enabled. |
Advanced producer configuration
The above connection and common Azure SDK client configuration are supported to be customized for each binder producer, which can be configured with the prefix spring.cloud.stream.eventhubs.bindings.<binding-name>.producer.
.
Basic usage
Sending and receiving messages from/to Event Hubs
Fill the configuration options with credential information.
- For credentials as connection string, configure the following properties in application.yml:
spring: cloud: azure: eventhubs: connection-string: ${EVENTHUB_NAMESPACE_CONNECTION_STRING} processor: checkpoint-store: container-name: ${CHECKPOINT_CONTAINER} account-name: ${CHECKPOINT_STORAGE_ACCOUNT} account-key: ${CHECKPOINT_ACCESS_KEY} stream: function: definition: consume;supply bindings: consume-in-0: destination: ${EVENTHUB_NAME} group: ${CONSUMER_GROUP} supply-out-0: destination: ${THE_SAME_EVENTHUB_NAME_AS_ABOVE} eventhubs: bindings: consume-in-0: consumer: checkpoint: mode: MANUAL
- For credentials as service principal, configure the following properties in application.yml:
spring: cloud: azure: credential: client-id: ${AZURE_CLIENT_ID} client-secret: ${AZURE_CLIENT_SECRET} profile: tenant-id: ${AZURE_TENANT_ID} eventhubs: namespace: ${EVENTHUB_NAMESPACE} processor: checkpoint-store: container-name: ${CONTAINER_NAME} account-name: ${ACCOUNT_NAME} stream: function: definition: consume;supply bindings: consume-in-0: destination: ${EVENTHUB_NAME} group: ${CONSUMER_GROUP} supply-out-0: destination: ${THE_SAME_EVENTHUB_NAME_AS_ABOVE} eventhubs: bindings: consume-in-0: consumer: checkpoint: mode: MANUAL
- For credentials as managed identites, configure the following properties in application.yml:
spring: cloud: azure: credential: managed-identity-enabled: true client-id: ${AZURE_MANAGED_IDENTITY_CLIENT_ID} # Only needed when using a user-assigned managed identity eventhubs: namespace: ${EVENTHUB_NAMESPACE} processor: checkpoint-store: container-name: ${CONTAINER_NAME} account-name: ${ACCOUNT_NAME} stream: function: definition: consume;supply bindings: consume-in-0: destination: ${EVENTHUB_NAME} group: ${CONSUMER_GROUP} supply-out-0: destination: ${THE_SAME_EVENTHUB_NAME_AS_ABOVE} eventhubs: bindings: consume-in-0: consumer: checkpoint: mode: MANUAL
Define supplier and consumer.
@Bean public Consumer<Message<String>> consume() { return message -> { Checkpointer checkpointer = (Checkpointer) message.getHeaders().get(CHECKPOINTER); LOGGER.info("New message received: '{}', partition key: {}, sequence number: {}, offset: {}, enqueued time: {}", message.getPayload(), message.getHeaders().get(EventHubsHeaders.PARTITION_KEY), message.getHeaders().get(EventHubsHeaders.SEQUENCE_NUMBER), message.getHeaders().get(EventHubsHeaders.OFFSET), message.getHeaders().get(EventHubsHeaders.ENQUEUED_TIME) ); checkpointer.success() .doOnSuccess(success -> LOGGER.info("Message '{}' successfully checkpointed", message.getPayload())) .doOnError(error -> LOGGER.error("Exception found", error)) .block(); }; } @Bean public Supplier<Message<String>> supply() { return () -> { LOGGER.info("Sending message, sequence " + i); return MessageBuilder.withPayload("Hello world, " + i++).build(); }; }
Partitioning support
A PartitionSupplier
with user-provided partition information will be created to configure the partition information about the message to be sent, the following is the process of obtaining different priorities of the partition ID and key:
)
Batch consumer support
Fill the batch configuration options
spring: cloud: stream: function: definition: consume bindings: consume-in-0: destination: ${AZURE_EVENTHUB_NAME} group: ${AZURE_EVENTHUB_CONSUMER_GROUP} consumer: batch-mode: true eventhubs: bindings: consume-in-0: consumer: batch: max-batch-size: 10 # Required for batch-consumer mode max-wait-time: 1m # Optional, the default value is null checkpoint: mode: BATCH # or MANUAL as needed
Define supplier and consumer.
For checkpointing mode as
BATCH
, you can use the following code to send messages and consume in batches.@Bean public Consumer<Message<List<String>>> consume() { return message -> { for (int i = 0; i < message.getPayload().size(); i++) { LOGGER.info("New message received: '{}', partition key: {}, sequence number: {}, offset: {}, enqueued time: {}", message.getPayload().get(i), ((List<Object>) message.getHeaders().get(EventHubsHeaders.BATCH_CONVERTED_PARTITION_KEY)).get(i), ((List<Object>) message.getHeaders().get(EventHubsHeaders.BATCH_CONVERTED_SEQUENCE_NUMBER)).get(i), ((List<Object>) message.getHeaders().get(EventHubsHeaders.BATCH_CONVERTED_OFFSET)).get(i), ((List<Object>) message.getHeaders().get(EventHubsHeaders.BATCH_CONVERTED_ENQUEUED_TIME)).get(i)); } }; } @Bean public Supplier<Message<String>> supply() { return () -> { LOGGER.info("Sending message, sequence " + i); return MessageBuilder.withPayload("\"test"+ i++ +"\"").build(); }; }
For checkpointing mode as
MANUAL
, you can use the following code to send messages and consume/checkpoint in batches.@Bean public Consumer<Message<List<String>>> consume() { return message -> { for (int i = 0; i < message.getPayload().size(); i++) { LOGGER.info("New message received: '{}', partition key: {}, sequence number: {}, offset: {}, enqueued time: {}", message.getPayload().get(i), ((List<Object>) message.getHeaders().get(EventHubHeaders.BATCH_CONVERTED_PARTITION_KEY)).get(i), ((List<Object>) message.getHeaders().get(EventHubHeaders.BATCH_CONVERTED_SEQUENCE_NUMBER)).get(i), ((List<Object>) message.getHeaders().get(EventHubHeaders.BATCH_CONVERTED_OFFSET)).get(i), ((List<Object>) message.getHeaders().get(EventHubHeaders.BATCH_CONVERTED_ENQUEUED_TIME)).get(i)); } Checkpointer checkpointer = (Checkpointer) message.getHeaders().get(CHECKPOINTER); checkpointer.success() .doOnSuccess(success -> LOGGER.info("Message '{}' successfully checkpointed", message.getPayload())) .doOnError(error -> LOGGER.error("Exception found", error)) .block(); }; } @Bean public Supplier<Message<String>> supply() { return () -> { LOGGER.info("Sending message, sequence " + i); return MessageBuilder.withPayload("\"test"+ i++ +"\"").build(); }; }
Note
In the batch-consuming mode, the default content type of Spring Cloud Stream binder is application/json
, so make sure the message payload is aligned with the content type. For example, when using the default content type of application/json
to receive messages with String
payload, the payload should be JSON String, surrounded with double quotes for the original String text. While for text/plain
content type, it can be a String
object directly. For more details, refer to the official doc of Spring Cloud Stream Content Type Negotiation.
Error channels
- Consumer error channel
This channel is open by default, you can handle the error message in this way:
// Replace destination with spring.cloud.stream.bindings.input.destination
// Replace group with spring.cloud.stream.bindings.input.group
@ServiceActivator(inputChannel = "{destination}.{group}.errors")
public void consumerError(Message<?> message) {
LOGGER.error("Handling customer ERROR: " + message);
}
- Producer error channel
This channel is not open by default. You need to add a configuration in your application.properties to enable it, like this:
spring.cloud.stream.default.producer.errorChannelEnabled=true
You can handle the error message in this way:
// Replace destination with spring.cloud.stream.bindings.output.destination
@ServiceActivator(inputChannel = "{destination}.errors")
public void producerError(Message<?> message) {
LOGGER.error("Handling Producer ERROR: " + message);
}
- Global default error channel
A global error channel called "errorChannel" is created by default Spring Integration, which allows users to subscribe many endpoints to it.
@ServiceActivator(inputChannel = "errorChannel")
public void producerError(Message<?> message) {
LOGGER.error("Handling ERROR: " + message);
}
Event Hubs message headers
See the Event Hubs message headers for the basic message headers supported.
Multiple binder support
Connection to multiple Event Hubs namespaces is also supported by using multiple binders.This sample takes connection string as example. Credentials of service principals and managed identities are also supported, users can set related properties in each binder's environment settings.
To use multiple binders of EventHubs, we need to configure the following properties in application.yml
spring: cloud: stream: function: definition: consume1;supply1;consume2;supply2 bindings: consume1-in-0: destination: ${EVENTHUB_NAME_01} group: ${CONSUMER_GROUP_01} supply1-out-0: destination: ${THE_SAME_EVENTHUB_NAME_01_AS_ABOVE} consume2-in-0: binder: eventhub-2 destination: ${EVENTHUB_NAME_02} group: ${CONSUMER_GROUP_02} supply2-out-0: binder: eventhub-2 destination: ${THE_SAME_EVENTHUB_NAME_02_AS_ABOVE} binders: eventhub-1: type: eventhubs default-candidate: true environment: spring: cloud: azure: eventhubs: connection-string: ${EVENTHUB_NAMESPACE_01_CONNECTION_STRING} processor: checkpoint-store: container-name: ${CHECKPOINT_CONTAINER_01} account-name: ${CHECKPOINT_STORAGE_ACCOUNT} account-key: ${CHECKPOINT_ACCESS_KEY} eventhub-2: type: eventhubs default-candidate: false environment: spring: cloud: azure: eventhubs: connection-string: ${EVENTHUB_NAMESPACE_02_CONNECTION_STRING} processor: checkpoint-store: container-name: ${CHECKPOINT_CONTAINER_02} account-name: ${CHECKPOINT_STORAGE_ACCOUNT} account-key: ${CHECKPOINT_ACCESS_KEY} eventhubs: bindings: consume1-in-0: consumer: checkpoint: mode: MANUAL consume2-in-0: consumer: checkpoint: mode: MANUAL poller: initial-delay: 0 fixed-delay: 1000
we need define two suppliers and two consumers
@Bean public Supplier<Message<String>> supply1() { return () -> { LOGGER.info("Sending message1, sequence1 " + i); return MessageBuilder.withPayload("Hello world1, " + i++).build(); }; } @Bean public Supplier<Message<String>> supply2() { return () -> { LOGGER.info("Sending message2, sequence2 " + j); return MessageBuilder.withPayload("Hello world2, " + j++).build(); }; } @Bean public Consumer<Message<String>> consume1() { return message -> { Checkpointer checkpointer = (Checkpointer) message.getHeaders().get(CHECKPOINTER); LOGGER.info("New message1 received: '{}'", message); checkpointer.success() .doOnSuccess(success -> LOGGER.info("Message1 '{}' successfully checkpointed", message)) .doOnError(error -> LOGGER.error("Exception found", error)) .block(); }; } @Bean public Consumer<Message<String>> consume2() { return message -> { Checkpointer checkpointer = (Checkpointer) message.getHeaders().get(CHECKPOINTER); LOGGER.info("New message2 received: '{}'", message); checkpointer.success() .doOnSuccess(success -> LOGGER.info("Message2 '{}' successfully checkpointed", message)) .doOnError(error -> LOGGER.error("Exception found", error)) .block(); }; }
Resource provision
Event Hubs binder supports provisioning of event hub and consumer group, users could use the following properties to enable provisioning.
spring:
cloud:
azure:
credential:
tenant-id: ${AZURE_TENANT_ID}
profile:
subscription-id: ${AZURE_SUBSCRIPTION_ID}
eventhubs:
resource:
resource-group: ${AZURE_EVENTHUBS_RESOURECE_GROUP}
Samples
See azure-spring-boot-samples for more details.
Spring Cloud Stream Binder for Azure Service Bus
Key concepts
The Spring Cloud Stream Binder for Azure Service Bus provides the binding implementation for the Spring Cloud Stream Framework. This implementation uses Spring Integration Service Bus Channel Adapters at its foundation.
Scheduled message
This binder supports submitting messages to a topic for delayed processing. Users can send scheduled messages with header x-delay
expressing in milliseconds a delay time for the message. The message will be delivered to the respective topics after x-delay
milliseconds.
Consumer group
Service Bus Topic provides similar support of consumer group as Apache Kafka, but with slight different logic.
This binder relies on Subscription
of a topic to act as a consumer group.
Dependency setup
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-stream-binder-servicebus</artifactId>
</dependency>
Alternatively, you can also use the Spring Cloud Azure Stream Service Bus Starter, as shown in the following example for Maven:
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-stream-servicebus</artifactId>
</dependency>
Configuration
The binder provides the following 2 parts of configuration options:
Connection configuration properties
This section contains the configuration options used for connecting to Azure Service Bus.
Note
If you choose to use a security principal to authenticate and authorize with Azure Active Directory for accessing an Azure resource, refer to Authorize access with Azure AD to make sure the security principal has been granted the sufficient permission to access the Azure resource.
Connection configurable properties of spring-cloud-azure-stream-binder-servicebus:
Property | Type | Description |
---|---|---|
spring.cloud.azure.servicebus.enabled | boolean | Whether an Azure Service Bus is enabled. |
spring.cloud.azure.servicebus.connection-string | String | Service Bus Namespace connection string value. |
spring.cloud.azure.servicebus.namespace | String | Service Bus Namespace value, which is the prefix of the FQDN. A FQDN should be composed of NamespaceName.DomainName |
spring.cloud.azure.servicebus.domain-name | String | Domain name of an Azure Service Bus Namespace value. |
Note
Common Azure Service SDK configuration options are configurable for the Spring Cloud Azure Stream Service Bus binder as well. The supported configuration options are introduced in the Configuration page, and could be configured with either the unified prefix spring.cloud.azure.
or the prefix of spring.cloud.azure.servicebus.
.
The binder also supports Spring Could Azure Resource Manager by default. To learn about how to retrieve the connection string with security principals that are not granted with Data
related roles, refer to the resource manager example for details.
Azure Service Bus binding configuration properties
The following options are divided into four sections: Consumer Properties, Advanced Consumer Configurations, Producer Properties and Advanced Producer Configurations.
Consumer properties
These properties are exposed via ServiceBusConsumerProperties
.
Consumer configurable properties of spring-cloud-azure-stream-binder-servicebus:
Property | Type | Default | Description |
---|---|---|---|
spring.cloud.stream.servicebus.bindings.binding-name.consumer.requeue-rejected | boolean | false | If the failed messages are routed to the DLQ. |
spring.cloud.stream.servicebus.bindings.binding-name.consumer.max-concurrent-calls | Integer | 1 | Max concurrent messages that the Service Bus processor client should process. |
spring.cloud.stream.servicebus.bindings.binding-name.consumer.max-concurrent-sessions | Integer | null | Maximum number of concurrent sessions to process at any given time. |
spring.cloud.stream.servicebus.bindings.binding-name.consumer.session-enabled | Boolean | null | Whether session is enabled. |
spring.cloud.stream.servicebus.bindings.binding-name.consumer.prefetch-count | Integer | 0 | The prefetch count of the Service Bus processor client. |
spring.cloud.stream.servicebus.bindings.binding-name.consumer.sub-queue | SubQueue | none | The type of the sub queue to connect to. |
spring.cloud.stream.servicebus.bindings.binding-name.consumer.max-auto-lock-renew-duration | Duration | 5m | The amount of time to continue auto-renewing the lock. |
spring.cloud.stream.servicebus.bindings.binding-name.consumer.receive-mode | ServiceBusReceiveMode | peek_lock | The receive mode of the Service Bus processor client. |
spring.cloud.stream.servicebus.bindings.binding-name.consumer.auto-complete | Boolean | true | Whether to settle messages automatically. If set as false, a message header of Checkpointer will be added to enable developers to settle messages manually. |
Advanced consumer configuration
The above connection and common Azure SDK client configuration are supported to be customized for each binder consumer, which can be configured with the prefix spring.cloud.stream.servicebus.bindings.<binding-name>.consumer.
.
Producer properties
These properties are exposed via ServiceBusProducerProperties
.
Producer configurable properties of spring-cloud-azure-stream-binder-servicebus:
Property | Type | Default | Description |
---|---|---|---|
spring.cloud.stream.servicebus.bindings.binding-name.producer.sync | boolean | false | Switch flag for sync of producer. |
spring.cloud.stream.servicebus.bindings.binding-name.producer.send-timeout | long | 10000 | Timeout value for sending of producer. |
spring.cloud.stream.servicebus.bindings.binding-name.producer.entity-type | ServiceBusEntityType | null | Service Bus entity type of the producer, required for the binding producer. |
Important
When using the binding producer, property of spring.cloud.stream.servicebus.bindings.<binding-name>.producer.entity-type
is required to be configured.
Advanced producer configuration
The above connection and common Azure SDK client configuration are supported to be customized for each binder producer, which can be configured with the prefix spring.cloud.stream.servicebus.bindings.<binding-name>.producer.
.
Basic usage
Sending and receiving messages from/to Service Bus
Fill the configuration options with credential information.
- For credentials as connection string, configure the following properties in application.yml:
spring: cloud: azure: servicebus: connection-string: ${SERVICEBUS_NAMESPACE_CONNECTION_STRING} stream: function: definition: consume;supply bindings: consume-in-0: destination: ${SERVICEBUS_ENTITY_NAME} # If you use Service Bus Topic, add the following configuration # group: ${SUBSCRIPTION_NAME} supply-out-0: destination: ${SERVICEBUS_ENTITY_NAME_SAME_AS_ABOVE} servicebus: bindings: consume-in-0: consumer: auto-complete: false supply-out-0: producer: entity-type: queue # set as "topic" if you use Service Bus Topic
- For credentials as service principal, configure the following properties in application.yml:
spring: cloud: azure: credential: client-id: ${AZURE_CLIENT_ID} client-secret: ${AZURE_CLIENT_SECRET} profile: tenant-id: ${AZURE_TENANT_ID} servicebus: namespace: ${SERVICEBUS_NAMESPACE} stream: function: definition: consume;supply bindings: consume-in-0: destination: ${SERVICEBUS_ENTITY_NAME} # If you use Service Bus Topic, add the following configuration # group: ${SUBSCRIPTION_NAME} supply-out-0: destination: ${SERVICEBUS_ENTITY_NAME_SAME_AS_ABOVE} servicebus: bindings: consume-in-0: consumer: auto-complete: false supply-out-0: producer: entity-type: queue # set as "topic" if you use Service Bus Topic
- For credentials as managed identities, configure the following properties in application.yml:
spring: cloud: azure: credential: managed-identity-enabled: true client-id: ${MANAGED_IDENTITY_CLIENT_ID} # Only needed when using a user-assigned managed identity servicebus: namespace: ${SERVICEBUS_NAMESPACE} stream: function: definition: consume;supply bindings: consume-in-0: destination: ${SERVICEBUS_ENTITY_NAME} # If you use Service Bus Topic, add the following configuration # group: ${SUBSCRIPTION_NAME} supply-out-0: destination: ${SERVICEBUS_ENTITY_NAME_SAME_AS_ABOVE} servicebus: bindings: consume-in-0: consumer: auto-complete: false supply-out-0: producer: entity-type: queue # set as "topic" if you use Service Bus Topic
Define supplier and consumer.
@Bean public Consumer<Message<String>> consume() { return message -> { Checkpointer checkpointer = (Checkpointer) message.getHeaders().get(CHECKPOINTER); LOGGER.info("New message received: '{}'", message.getPayload()); checkpointer.success() .doOnSuccess(success -> LOGGER.info("Message '{}' successfully checkpointed", message.getPayload())) .doOnError(error -> LOGGER.error("Exception found", error)) .block(); }; } @Bean public Supplier<Message<String>> supply() { return () -> { LOGGER.info("Sending message, sequence " + i); return MessageBuilder.withPayload("Hello world, " + i++).build(); }; }
Partition key support
The binder supports Service Bus partitioning by allowing setting partition key and session ID in the message header. This section introduces how to set partition key for messages.
Spring Cloud Stream provides a partition key SpEL expression property spring.cloud.stream.bindings.<binding-name>.producer.partition-key-expression
. For example, setting this property as "'partitionKey-' + headers[<message-header-key>]"
and add a header called message-header-key. Spring Cloud Stream will use the value for this header when evaluating the above expression to assign a partition key. Here is an example producer code:
@Bean
public Supplier<Message<String>> generate() {
return () -> {
String value = "random payload";
return MessageBuilder.withPayload(value)
.setHeader("<message-header-key>", value.length() % 4)
.build();
};
}
Session support
The binder supports message sessions of Service Bus. Session ID of a message could be set via the message header.
@Bean
public Supplier<Message<String>> generate() {
return () -> {
String value = "random payload";
return MessageBuilder.withPayload(value)
.setHeader(ServiceBusMessageHeaders.SESSION_ID, "Customize session ID")
.build();
};
}
Note
According to Service Bus partitioning, session ID has higher priority than partition key. So when both of ServiceBusMessageHeaders#SESSION_ID
and ServiceBusMessageHeaders#PARTITION_KEY
(or AzureHeaders#PARTITION_KEY
) headers are set,
the value of the session ID will eventually be used to overwrite the value of the partition key.
Error channels
- Consumer error channel
This channel is open by default, and a default consumer error channel handler is used to send failed messages to the dead-letter queue when spring.cloud.stream.servicebus.bindings.<binding-name>.consumer.requeue-rejected
is enabled, otherwise the failed messages will be abandoned.
To customize the consumer error channel handler, you can register you own error handler to the related consumer error channel in this way:
// Replace destination with spring.cloud.stream.bindings.input.destination
// Replace group with spring.cloud.stream.bindings.input.group
@ServiceActivator(inputChannel = "{destination}.{group}.errors")
public void consumerError(Message<?> message) {
LOGGER.error("Handling customer ERROR: " + message);
}
- Producer error channel
This channel is not open by default. You need to add a configuration in your application.properties to enable it, like this:
spring.cloud.stream.default.producer.errorChannelEnabled=true
You can handle the error message in this way:
// Replace destination with spring.cloud.stream.bindings.output.destination
@ServiceActivator(inputChannel = "{destination}.errors")
public void producerError(Message<?> message) {
LOGGER.error("Handling Producer ERROR: " + message);
}
- Global default error channel
A global error channel called "errorChannel" is created by default Spring Integration, which allows users to subscribe many endpoints to it.
@ServiceActivator(inputChannel = "errorChannel")
public void producerError(Message<?> message) {
LOGGER.error("Handling ERROR: " + message);
}
Service Bus message headers
See the Service Bus message headers for the basic message headers supported.
Note
When setting the partiton key, the priority of message header is higher than Spring Cloud Stream property. So spring.cloud.stream.bindings.<binding-name>.producer.partition-key-expression
will take effect only when none of the headers of ServiceBusMessageHeaders#SESSION_ID
, ServiceBusMessageHeaders#PARTITION_KEY
, AzureHeaders#PARTITION_KEY
is configured.
Multiple Binder support
Connection to multiple Service Bus namespaces is also supported by using multiple binders. This sample takes connection string as example. Credentials of service principals and managed identities are also supported, users can set related properties in each binder's environment settings.
To use multiple binders of ServiceBus, we need to configure the following properties in application.yml
spring: cloud: stream: function: definition: consume1;supply1;consume2;supply2 bindings: consume1-in-0: destination: ${SERVICEBUS_TOPIC_NAME} group: ${SUBSCRIPTION_NAME} supply1-out-0: destination: ${SERVICEBUS_TOPIC_NAME_SAME_AS_ABOVE} consume2-in-0: binder: servicebus-2 destination: ${SERVICEBUS_QUEUE_NAME} supply2-out-0: binder: servicebus-2 destination: ${SERVICEBUS_QUEUE_NAME_SAME_AS_ABOVE} binders: servicebus-1: type: servicebus default-candidate: true environment: spring: cloud: azure: servicebus: connection-string: ${SERVICEBUS_NAMESPACE_01_CONNECTION_STRING} servicebus-2: type: servicebus default-candidate: false environment: spring: cloud: azure: servicebus: connection-string: ${SERVICEBUS_NAMESPACE_02_CONNECTION_STRING} servicebus: bindings: consume1-in-0: consumer: auto-complete: false supply1-out-0: producer: entity-type: topic consume2-in-0: consumer: auto-complete: false supply2-out-0: producer: entity-type: queue poller: initial-delay: 0 fixed-delay: 1000
we need define two suppliers and two consumers
@Bean public Supplier<Message<String>> supply1() { return () -> { LOGGER.info("Sending message1, sequence1 " + i); return MessageBuilder.withPayload("Hello world1, " + i++).build(); }; } @Bean public Supplier<Message<String>> supply2() { return () -> { LOGGER.info("Sending message2, sequence2 " + j); return MessageBuilder.withPayload("Hello world2, " + j++).build(); }; } @Bean public Consumer<Message<String>> consume1() { return message -> { Checkpointer checkpointer = (Checkpointer) message.getHeaders().get(CHECKPOINTER); LOGGER.info("New message1 received: '{}'", message); checkpointer.success() .doOnSuccess(s -> LOGGER.info("Message '{}' successfully checkpointed", message.getPayload())) .doOnError(e -> LOGGER.error("Error found", e)) .block(); }; } @Bean public Consumer<Message<String>> consume2() { return message -> { Checkpointer checkpointer = (Checkpointer) message.getHeaders().get(CHECKPOINTER); LOGGER.info("New message2 received: '{}'", message); checkpointer.success() .doOnSuccess(s -> LOGGER.info("Message '{}' successfully checkpointed", message.getPayload())) .doOnError(e -> LOGGER.error("Error found", e)) .block(); }; }
Resource provision
Service bus binder supports provisioning of queue, topic and subscription, users could use the following properties to enable provisioning.
spring:
cloud:
azure:
credential:
tenant-id: ${AZURE_TENANT_ID}
profile:
subscription-id: ${AZURE_SUBSCRIPTION_ID}
servicebus:
resource:
resource-group: ${AZURE_SERVICEBUS_RESOURECE_GROUP}
stream:
servicebus:
bindings:
<binding-name>:
consumer:
entity-type: ${SERVICEBUS_CONSUMER_ENTITY_TYPE}
Samples
See azure-spring-boot-samples for more details.
Spring JMS support
To use Azure Service Bus by the JMS API integrated into the Spring JMS framework. Azure Service Bus connection string have to be provided which is to be parsed into the login username, password and remote URI for the AMQP broker.
Dependency setup
Adding the following dependencies if you want to migrate your Spring JMS application to use Azure Service Bus.
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-servicebus-jms</artifactId>
</dependency>
Configuration
Configurable properties when using Spring JMS support:
Property | Description |
---|---|
spring.jms.servicebus.connection-string | Azure Service Bus connection string. Should be provided when want to provide the connection string directly. |
spring.jms.servicebus.topic-client-id | JMS client ID. Only works for the topicJmsListenerContainerFactory bean. |
spring.jms.servicebus.enabled | Whether to enable Servive Bus JMS autoconfiguration. The default value is true . |
spring.jms.servicebus.idle-timeout | Connection idle timeout duration that how long the client expects Service Bus to keep a connection alive when no messages delivered. The default value is 2m . |
spring.jms.servicebus.pricing-tier | The Azure Service Bus Price Tier. |
spring.jms.servicebus.listener.reply-pub-sub-domain | Whether the reply destination type is topic. Only works for the topicJmsListenerContainerFactory bean. |
spring.jms.servicebus.listener.phase | The phase in which this container should be started and stopped. |
spring.jms.servicebus.listener.reply-qos-settings | Configure the QosSettings to use when sending a reply. |
spring.jms.servicebus.listener.subscription-durable | Whether to make the subscription durable. Only works for the topicJmsListenerContainerFactory bean. The default value is true . |
spring.jms.servicebus.listener.subscription-shared | Whether to make the subscription shared. Only works for the topicJmsListenerContainerFactory bean. |
spring.jms.servicebus.pool.block-if-full | Whether to block when a connection is requested and the pool is full. Set it to false to throw a JMSException instead. |
spring.jms.servicebus.pool.block-if-full-timeout | Blocking period before throwing an exception if the pool is still full. |
spring.jms.servicebus.pool.enabled | Whether a JmsPoolConnectionFactory should be created, instead of a regularConnectionFactory. |
spring.jms.servicebus.pool.idle-timeout | Connection pool idle timeout. |
spring.jms.servicebus.pool.max-connections | Maximum number of pooled connections. |
spring.jms.servicebus.pool.max-sessions-per-connection | Maximum number of pooled sessions per connection in the pool. |
spring.jms.servicebus.pool.time-between-expiration-check | Time to sleep between runs of the idle connection eviction thread. When negative, no idle connection eviction thread runs. |
spring.jms.servicebus.pool.use-anonymous-producers | Whether to use only one anonymous 'MessageProducer' instance. Set it to false to create one 'MessageProducer' every time one is required. |
spring.jms.servicebus.prefetch-policy.all | Fallback value for prefetch option in this Service Bus namespace. The default value is 0 . |
spring.jms.servicebus.prefetch-policy.durable-topic-prefetch | The number of prefetch for durable topic. The default value is 0 . |
spring.jms.servicebus.prefetch-policy.queue-browser-prefetch | The number of prefetch for queue browser. The default value is 0 . |
spring.jms.servicebus.prefetch-policy.queue-prefetch | The number of prefetch for queue. The default value is 0 . |
spring.jms.servicebus.prefetch-policy.topic-prefetch | The number of prefetch for topic. The default value is 0 . |
Note
Spring JMS general configuration is omitted for short. See Spring JMS Document for more details.
Basic usage
Use Service Bus connection String
The simplest way to connect to Service Bus for Spring JMS application is with the connection string.
Add the following properties and you are good to go.
spring:
jms:
servicebus:
connection-string: ${AZURE_SERVICEBUS_CONNECTION_STRING}
pricing-tier: ${PRICING_TIER}
Note
The default enabled ConnectionFactory
is the CachingConnectionFactory
which adds Session caching as well MessageProducer caching. If you want to activate the connection pooling featured one of JmsPoolConnectionFactory, the property of spring.jms.servicebus.pool.enabled
should be specified true
. You can find other pooling configuration options (properties with prefix spring.jms.servicebus.pool.
) from the above Configuration section.
Samples
See azure-spring-boot-samples for more details.
Spring Native support
Spring Native provides support for compiling Spring Boot applications to native executables using the GraalVM native-image compiler. The native images will bring many advantages, such as instant startup, instant peak performance, and reduced memory consumption. Some Spring Cloud Azure features can also benefit from the Spring Native support. The goal is that Spring Cloud Azure applications can be built as native images without any code modification. For more information, see the Spring Native documentation.
Support
Spring Cloud Azure has been validated against GraalVM and Spring Native, and provides the beta version support. You can try it on your projects if they are using those supported dependencies, and raise bugs or contribute pull requests if something goes wrong on Spring Cloud Azure. For more information, see the Support section in the Spring Native documentation.
Spring Native
Spring Cloud Azure 4.1.0-beta.1
has been tested against Spring Native 0.11.4
and GraalVM 22.0.0
.
Spring Cloud Azure Native
Note
Spring Native 0.11.4
has been tested against Spring Cloud Azure Native Configuration 4.0.0-beta.1
.
Spring Cloud Azure provides a dependency spring-cloud-azure-native-configuration
that is an extension of Spring Native configuration for Spring Cloud Azure libraries. The Spring Native AOT plugin will combine the spring-native-configuration
and spring-cloud-azure-native-configuration
to build applications into native executables. You don't need any extra modifications to the code that uses Spring Cloud Azure libraries apart from adding the dependency, which only applies to the code in the Spring Cloud Azure libraries.
The following features are supported:
- Azure App Configuration clients auto-configuration
- Azure Event Hubs clients auto-configuration
- Azure Key Vault Certificates clients auto-configuration
- Azure Key Vault Secrets clients auto-configuration
- Azure Storage Blob clients auto-configuration
- Azure Storage File Share clients auto-configuration
- Azure Storage Queue clients auto-configuration
- Spring Integration for Azure Event Hubs
- Spring Integration for Azure Storage Queue
Limitations
The Spring Cloud Azure support for Spring Native is still in the early stages and continues to be updated. The following features are not yet supported:
- Azure Cosmos DB clients auto-configuration
- Azure Service Bus clients auto-configuration
- Spring Data for Azure Cache for Redis
- Spring Data for Azure Cosmos DB
- Spring Cloud Stream for Azure Event Hubs
- Spring Cloud Stream for Azure Service Bus
- Spring Kafka for Azure Event Hubs
- Spring Integration for Azure Service Bus
Note
Not all the native image options are supported by Spring Native. For more information, see the Native image options section of the Spring Native documentation.
Warning
Spring Cloud Azure 4.1.0-beta.1
is not validated for building native executables based on Gradle Kotlin.
Project setup
Spring Cloud Azure applications can enable Spring Native support by following the instructions in the Getting started section of the Spring Native documentation. The only additional processing required is to add the following dependency to the POM file.
Tip
The dependency com.azure.spring:spring-cloud-azure-native-configuration
is not managed in com.azure.spring:spring-cloud-azure-dependencies
.
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-native-configuration</artifactId>
<version>4.0.0-beta.1</version>
</dependency>
Build the native application
The following sections describe the two main ways to build a Spring Boot native application with Spring Cloud Azure libraries.
Build with Buildpacks
The native application can be built as follows:
For more information, see the Getting started with Buildpacks section in the Spring Native documentation.
Build with Native Build Tools
You can build the native application by using the following command:
For more information, see the Getting started with Native Build Tools section of the Spring Native documentation.
Run the native application
The following sections describe the two main ways to run a native executable.
Tip
Assuming the project artifact ID is spring-cloud-azure-sample
and the project version is 0.0.1-SNAPSHOT
, you can specify the custom image name in one of the following ways:
- If you're using Cloud Native Buildpacks, use the
image
->name
->custom-image-name
configuration element in the Spring Boot plugin. - If you're using GraalVM Native Build Tools, use the
imageName
->custom-image-name
configuration element in the Spring Boot plugin.
Run with Buildpacks
To run the application, you can use docker
the usual way as shown in the following example:
docker run --rm -p 8080:8080 spring-cloud-azure-sample:0.0.1-SNAPSHOT
Run with Native Build Tools
To run your application, use the following command:
Samples
For more information, see Using Spring Native with Spring Cloud Azure Storage Blob Starter on GitHub.
Here are other verified samples that support Spring Native. For more information, see Run Samples Based On Spring Native on GitHub.
Library Artifact ID | Supported Example Projects |
---|---|
spring-cloud-azure-starter-appconfiguration | appconfiguration-client |
spring-cloud-azure-starter-eventhubs | eventhubs-client |
spring-cloud-azure-starter-integration-eventhubs | storage-queue-integration, storage-queue-operation |
spring-cloud-azure-starter-integration-storage-queue | appconfiguration-client |
spring-cloud-azure-starter-keyvault-secrets | property-source, secret-client |
spring-cloud-azure-starter-storage-blob | storage-blob-sample |
spring-cloud-azure-starter-storage-file-share | storage-file-sample |
spring-cloud-azure-starter-storage-queue | storage-queue-client |
MySQL support
Azure Database for MySQL is a relational database service powered by the MySQL community edition. You can use either Single Server or Flexible Server to host a MySQL database in Azure. It's a fully managed database-as-a-service offering that can handle mission-critical workloads with predictable performance and dynamic scalability.
From version 4.5.0
, Spring Cloud Azure supports various types of credentials for authentication to Azure Database for MySQL Flexible server.
Supported MySQL version
The current version of the starter should use Azure Database for MySQL Flexible Server version 5.7
or 8.0
.
Core Features
Passwordless connection
Passwordless connection uses Azure Active Directory (Azure AD) authentication for connecting to Azure services without storing any credentials in the application, its configuration files, or in environment variables. Azure AD authentication is a mechanism for connecting to Azure Database for MySQL using identities defined in Azure AD. With Azure AD authentication, you can manage database user identities and other Microsoft services in a central location, which simplifies permission management.
How it works
Spring Cloud Azure will first build one of the following types of credentials depending on the application authentication configuration:
ClientSecretCredential
ClientCertificateCredential
UsernamePasswordCredential
ManagedIdentityCredential
DefaultAzureCredential
If none of these types of credentials are found, the DefaultAzureCredential
credentials will be obtained from application properties, environment variables, managed identities, or the IDE. For detailed information, see the Spring Cloud Azure authentication section.
The following high-level diagram summarizes how authentication works using OAuth credential authentication with Azure Database for MySQL. The arrows indicate communication pathways.
Configuration
Spring Cloud Azure for MySQL supports the following two levels of configuration options:
The global authentication configuration options of
credential
andprofile
with prefixes ofspring.cloud.azure
.Spring Cloud Azure for MySQL common configuration options.
The following table shows the Spring Cloud Azure for MySQL common configuration options:
Name | Description |
---|---|
spring.datasource.azure.passwordless-enabled | Whether to enable passwordless connections to Azure databases by using OAuth2 Azure Active Directory token credentials. |
spring.datasource.azure.credential.client-certificate-password | Password of the certificate file. |
spring.datasource.azure.credential.client-certificate-path | Path of a PEM certificate file to use when performing service principal authentication with Azure. |
spring.datasource.azure.credential.client-id | Client ID to use when performing service principal authentication with Azure. This is a legacy property. |
spring.datasource.azure.credential.client-secret | Client secret to use when performing service principal authentication with Azure. This is a legacy property. |
spring.datasource.azure.credential.managed-identity-enabled | Whether to enable managed identity to authenticate with Azure. If true and the client-id is set, will use the client ID as user assigned managed identity client ID. The default value is false. |
spring.datasource.azure.credential.password | Password to use when performing username/password authentication with Azure. |
spring.datasource.azure.credential.username | Username to use when performing username/password authentication with Azure. |
spring.datasource.azure.profile.cloud-type | Name of the Azure cloud to connect to. |
spring.datasource.azure.profile.environment.active-directory-endpoint | The Azure Active Directory endpoint to connect to. |
spring.datasource.azure.profile.tenant-id | Tenant ID for Azure resources. |
Dependency setup
Add the following dependency to your project. This will automatically include the spring-boot-starter
dependency in your project transitively.
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-jdbc-mysql</artifactId>
</dependency>
Note
Passwordless connections have been supported since version 4.5.0
.
Remember to add the BOM spring-cloud-azure-dependencies
along with the above dependency. For more information, see the Getting started section.
Basic usage
The following sections show the classic Spring Boot application usage scenarios.
Important
Passwordless connection uses Azure AD authentication. To use Azure AD authentication, you should set the Azure AD admin user first. Only an Azure AD Admin user can create and enable users for Azure AD-based authentication. For more information, see the Create an Azure Database for MySQL instance and set up the admin user section.
Connect to Azure MySQL locally without password
To create users and grant permission, see the Create a MySQL non-admin user and grant permission section.
Configure the following properties in your application.yml file:
spring: datasource: url: jdbc:mysql://${AZURE_MYSQL_SERVER_NAME}.mysql.database.azure.com:3306/${AZURE_MYSQL_DATABASE_NAME} username: ${AZURE_MYSQL_AD_NON_ADMIN_USERNAME} azure: passwordless-enabled: true
Connect to Azure MySQL using a service principal
Create an Azure AD user for service principal and grant permission.
First, use the following commands to set up some environment variables.
export AZURE_MYSQL_AZURE_AD_SP_USERID=$(az ad sp list --display-name <service_principal-name> --query '[0].appId' -otsv) export AZURE_MYSQL_AZURE_AD_SP_USERNAME=<YOUR_MYSQL_AZURE_AD_USERNAME> export AZURE_MYSQL_SERVER_NAME=<YOUR_MYSQL_SERVER_NAME> export AZURE_MYSQL_DATABASE_NAME=<YOUR_MYSQL_DATABASE_NAME> export CURRENT_USERNAME=$(az ad signed-in-user show --query userPrincipalName -o tsv)
Then, create a SQL script called create_ad_user_sp.sql for creating a non-admin user. Add the following contents and save it locally:
cat << EOF > create_ad_user_sp.sql SET aad_auth_validate_oids_in_tenant = OFF; CREATE AADUSER '$AZURE_MYSQL_AZURE_AD_SP_USERNAME' IDENTIFIED BY '$AZURE_MYSQL_AZURE_AD_SP_USERID'; GRANT ALL PRIVILEGES ON $AZURE_MYSQL_DATABASE_NAME.* TO '$AZURE_MYSQL_AZURE_AD_SP_USERNAME'@'%'; FLUSH privileges; EOF
Use the following command to run the SQL script to create the Azure AD non-admin user:
mysql -h $AZURE_MYSQL_SERVER_NAME.mysql.database.azure.com --user $CURRENT_USERNAME --enable-cleartext-plugin --password=`az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken` < create_ad_user_sp.sql
Now use the following command to remove the temporary SQL script file:
rm create_ad_user_sp.sql
Configure the following properties in your application.yml file:
spring: cloud: azure: credential: client-id: ${AZURE_CLIENT_ID} client-secret: ${AZURE_CLIENT_SECRET} profile: tenant-id: ${AZURE_TENANT_ID} datasource: url: jdbc:mysql://${AZURE_MYSQL_SERVER_NAME}.mysql.database.azure.com:3306/${AZURE_MYSQL_DATABASE_NAME} username: ${AZURE_MYSQL_AD_SP_USERNAME} azure: passwordless-enabled: true
Connect to Azure MySQL with Managed Identity in Azure Spring Apps
To enable managed identity, see the Assign the managed identity using the Azure portal section.
To grant permissions, see the Assign roles to the managed identity section.
Configure the following properties in your application.yml file:
spring: datasource: url: jdbc:mysql://${AZURE_MYSQL_SERVER_NAME}.mysql.database.azure.com:3306/${AZURE_MYSQL_DATABASE_NAME} username: ${AZURE_MYSQL_AD_MI_USERNAME} azure: passwordless-enabled: true
Samples
See the azure-spring-boot-samples repository on GitHub.
PostgreSQL support
Azure Database for PostgreSQL is a relational database service based on the open-source Postgres database engine. It's a fully managed database-as-a-service that can handle mission-critical workloads with predictable performance, security, high availability, and dynamic scalability.
From version 4.5.0
, Spring Cloud Azure supports various types of credentials for authentication to Azure Database for PostgreSQL Flexible server.
Supported PostgreSQL version
For supported versions, see Supported PostgreSQL major versions in Azure Database for PostgreSQL - Flexible Server.
Core Features
Passwordless connection
Passwordless connection uses Azure Active Directory (Azure AD) authentication for connecting to Azure services without storing any credentials in the application, its configuration files, or in environment variables. Azure AD authentication is a mechanism for connecting to Azure Database for PostgreSQL using identities defined in Azure AD. With Azure AD authentication, you can manage database user identities and other Microsoft services in a central location, which simplifies permission management.
How it works
Spring Cloud Azure will first build one of the following types of credentials depending on the application authentication configuration:
ClientSecretCredential
ClientCertificateCredential
UsernamePasswordCredential
ManagedIdentityCredential
DefaultAzureCredential
If none of these types of credentials are found, the DefaultAzureCredential
credentials will be obtained from application properties, environment variables, managed identities, or the IDE. For detailed information, see the Spring Cloud Azure authentication section.
The following high-level diagram summarizes how authentication works using OAuth credential authentication with Azure Database for PostgreSQL. The arrows indicate communication pathways.
Configuration
Spring Cloud Azure for PostgreSQL supports the following two levels of configuration options:
The global authentication configuration options of
credential
andprofile
with prefixes ofspring.cloud.azure
.Spring Cloud Azure for PostgreSQL common configuration options.
The following table shows the Spring Cloud Azure for PostgreSQL common configuration options:
Name | Description |
---|---|
spring.datasource.azure.passwordless-enabled | Whether to enable passwordless connections to Azure databases by using OAuth2 Azure Active Directory token credentials. |
spring.datasource.azure.credential.client-certificate-password | Password of the certificate file. |
spring.datasource.azure.credential.client-certificate-path | Path of a PEM certificate file to use when performing service principal authentication with Azure. |
spring.datasource.azure.credential.client-id | Client ID to use when performing service principal authentication with Azure. This is a legacy property. |
spring.datasource.azure.credential.client-secret | Client secret to use when performing service principal authentication with Azure. This is a legacy property. |
spring.datasource.azure.credential.managed-identity-enabled | Whether to enable managed identity to authenticate with Azure. If true and the client-id is set, will use the client ID as user assigned managed identity client ID. The default value is false. |
spring.datasource.azure.credential.password | Password to use when performing username/password authentication with Azure. |
spring.datasource.azure.credential.username | Username to use when performing username/password authentication with Azure. |
spring.datasource.azure.profile.cloud-type | Name of the Azure cloud to connect to. |
spring.datasource.azure.profile.environment.active-directory-endpoint | The Azure Active Directory endpoint to connect to. |
spring.datasource.azure.profile.tenant-id | Tenant ID for Azure resources. |
Dependency setup
Add the following dependency to your project. This will automatically include the spring-boot-starter
dependency in your project transitively.
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-jdbc-postgresql</artifactId>
</dependency>
Note
Passwordless connections have been supported since version 4.5.0
.
Remember to add the BOM spring-cloud-azure-dependencies
along with the above dependency. For more information, see the Getting started section.
Basic usage
The following sections show the classic Spring Boot application usage scenarios.
Important
Passwordless connection uses Azure AD authentication. To use Azure AD authentication, you should set the Azure AD admin user first. Only an Azure AD Admin user can create and enable users for Azure AD-based authentication. For more information, see the Create an Azure Database for PostgreSQL instance and set up the admin user section.
Connect to Azure PostgreSQL locally without password
To create users and grant permission, see the Create a PostgreSQL non-admin user and grant permission section.
Configure the following properties in your application.yml file:
spring: datasource: url: jdbc:postgresql://${AZ_DATABASE_SERVER_NAME}.postgres.database.azure.com:5432/${AZ_DATABASE_NAME}?sslmode=require username: ${AZ_POSTGRESQL_AD_NON_ADMIN_USERNAME} azure: passwordless-enabled: true
Connect to Azure PostgreSQL using a service principal
Assign role to service principal:
Create a SQL script called create_ad_user_sp.sql for creating a non-admin user. Add the following contents and save it locally:
Important
Make sure
<service-principal-name>
already exists in your Azure AD tenant, or you won't be able to create the non-admin user.cat << EOF > create_ad_user_sp.sql select * from pgaadauth_create_principal('<service-principal-name>', false, false); EOF
Use the following command to run the SQL script to create the Azure AD non-admin user:
psql "host=$AZ_DATABASE_SERVER_NAME.postgres.database.azure.com user=$CURRENT_USERNAME@$AZ_DATABASE_SERVER_NAME dbname=postgres port=5432 password=`az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken` sslmode=require" < create_ad_user_sp.sql
Now use the following command to remove the temporary SQL script file:
rm create_ad_user_sp.sql
Configure the following properties in your application.yml file:
spring: cloud: azure: credential: client-id: ${AZURE_CLIENT_ID} client-secret: ${AZURE_CLIENT_SECRET} profile: tenant-id: ${AZURE_TENANT_ID} datasource: url: jdbc:postgresql://${AZ_DATABASE_SERVER_NAME}.postgres.database.azure.com:5432/${AZ_DATABASE_NAME}?sslmode=require username: ${AZ_POSTGRESQL_AD_SP_USERNAME} azure: passwordless-enabled: true
Connect to Azure PostgreSQL with Managed Identity in Azure Spring Apps
To enable managed identity, see the Assign the managed identity using the Azure portal section.
To grant permissions, see the Assign role to managed identity section.
Configure the following properties in your application.yml file:
spring: cloud: azure: credential: managed-identity-enabled: true client-id: ${AZURE_CLIENT_ID} datasource: url: jdbc:postgresql://${AZ_DATABASE_SERVER_NAME}.postgres.database.azure.com:5432/${AZ_DATABASE_NAME}?sslmode=require username: ${AZ_POSTGRESQL_AD_MI_USERNAME} azure: passwordless-enabled: true
Note
For more information, see Tutorial: Deploy a Spring application to Azure Spring Apps with a passwordless connection to an Azure database
Samples
See the azure-spring-boot-samples repository on GitHub.
Kafka support
From version 4.3.0, Spring Cloud Azure for Kafka supports various types of credentials to authenticate and connect to Azure Event Hubs.
Supported Kafka version
The current version of the starter should be compatible with Apache Kafka Clients 2.0.0 using Java 8 or above.
Supported authentication types
The following authentication types are supported:
- Plain connection string authentication
- Direct connection string authentication
- ARM-based connection string authentication
- OAuth credential authentication
- Managed identity authentication
- Username/password authentication
- Service principal authentication
DefaultAzureCredential
authentication
How it works
OAuth credential authentication
This section describes the overall workflow of Spring Cloud Azure OAuth authentication.
Spring Cloud Azure will first build one of the following types of credentials depending on the application authentication configuration:
ClientSecretCredential
ClientCertificateCredential
UsernamePasswordCredential
ManagedIdentityCredential
If none of these types of credentials are found, the credential chain via DefaultAzureTokenCredential
will be used to obtain credentials from application properties, environment variables, managed identity, or IDEs. For detailed information, see the Spring Cloud Azure authentication section.
Plain connection string authentication
For the connection string authentication mode, you can use connection string authentication directly or use the Azure Resource Manager to retrieve the connection string. For more information about the usage, see the Basic usage for connection string authentication section.
Note
Since version of 4.3.0, connection string authentication is deprecated in favor of OAuth authentications.
Configuration
Configurable properties when using Kafka support with OAuth authentication
Spring Cloud Azure for Kafka supports the following two levels of configuration options:
- Spring Cloud Azure for Event Hubs Kafka properties.
- The global authentication configuration options of
credential
andprofile
with prefixes ofspring.cloud.azure
. - Kafka-specific level configurations. The Kafka-level configurations are also available for Spring Boot and Spring Cloud Stream binders for
common
,consumer
,producer
, oradmin
scopes, which have different prefixes.
The global properties are exposed via com.azure.spring.cloud.autoconfigure.context.AzureGlobalProperties
. The Kafka-specific properties are exposed via org.springframework.boot.autoconfigure.kafka.KafkaProperties
(Spring Boot) and org.springframework.cloud.stream.binder.kafka.properties.KafkaBinderConfigurationProperties
(Spring Cloud Stream binder).
The following list shows all supported configuration options.
Spring Cloud Azure for Event Hubs Kafka properties.
- Property:
spring.cloud.azure.eventhubs.kafka.enabled
- Description: whether to enable credential free connection to Azure Event Hubs for Kafka, the default value is
true
.
- Property:
The Spring Cloud Azure global authentication configuration options
- Prefix:
spring.cloud.azure
- Supported options:
spring.cloud.azure.credential.*
,spring.cloud.azure.profile.*
For the full list of global configuration options, see Global configuration properties.
- Prefix:
Spring Boot Kafka common configuration
- Prefix:
spring.kafka.properties.azure
- Example:
spring.kafka.properties.azure
.credential.*
- Prefix:
Spring Kafka consumer configuration options
- Prefix:
spring.kafka.consumer.properties.azure
- Example:
spring.kafka.consumer.properties.azure
.credential.*
- Prefix:
Spring Kafka producer configuration options
- Prefix:
spring.kafka.producer.properties.azure
- Example:
spring.kafka.producer.properties.azure
.credential.*
- Prefix:
Spring Kafka admin configuration options
- Prefix:
spring.kafka.admin.properties.azure
- Example:
spring.kafka.admin.properties.azure
.credential.*
- Prefix:
Spring Cloud Stream Kafka Binder common configuration
- Prefix:
spring.cloud.stream.kafka.binder.configuration.azure
- Example:
spring.cloud.stream.kafka.binder.configuration.azure
.credential.*
- Prefix:
Spring Cloud Stream Kafka Binder consumer configuration
- Prefix:
spring.cloud.stream.kafka.binder.consumer-properties.azure
- Example:
spring.cloud.stream.kafka.binder.consumer-properties.azure
.credential.*
- Prefix:
Spring Cloud Stream Kafka Binder producer configuration
- Prefix:
spring.cloud.stream.kafka.binder.producer-properties.azure
- Example:
spring.cloud.stream.kafka.binder.producer-properties.azure
.credential.*
- Prefix:
Spring Cloud Stream Kafka Binder admin configuration
- Prefix: Not supported, should use Spring Boot Kafka common or admin configuration.
The following table shows the Spring Boot Kafka common configuration options:
Name | Description |
---|---|
spring.kafka.properties.azure.credential.client-certificate-password | Password of the certificate file. |
spring.kafka.properties.azure.credential.client-certificate-path | Path of a PEM certificate file to use when performing service principal authentication with Azure. |
spring.kafka.properties.azure.credential.client-id | Client ID to use when performing service principal authentication with Azure. This is a legacy property. |
spring.kafka.properties.azure.credential.client-secret | Client secret to use when performing service principal authentication with Azure. This is a legacy property. |
spring.kafka.properties.azure.credential.managed-identity-enabled | Whether to enable managed identity to authenticate with Azure. If true and the client-id is set, will use the client ID as user assigned managed identity client ID. The default value is false. |
spring.kafka.properties.azure.credential.password | Password to use when performing username/password authentication with Azure. |
spring.kafka.properties.azure.credential.username | Username to use when performing username/password authentication with Azure. |
spring.kafka.properties.azure.profile.environment.active-directory-endpoint | The Azure Active Directory endpoint to connect to. |
spring.kafka.properties.azure.profile.tenant-id | Tenant ID for Azure resources. |
Note
The configuration options in different levels apply the following rules. The more specific configuration options have higher priority than the common ones. For example:
- Spring Kafka common configuration options supersede the global options.
- Spring Kafka consumer configuration options supersede the common options.
- Spring Kafka producer configuration options supersede the common options.
- Spring Kafka admin configuration options supersede the common options.
- The Spring Cloud Stream Kafka Binder options are just like the above.
Configurable properties when using Kafka support with plain connection string authentication
The following table shows the Spring Boot Event Hubs for Kafka common configuration options:
Property | Description |
---|---|
spring.cloud.azure.eventhubs.kafka.enabled | Whether to enable the Azure Event Hubs Kafka support. The default value is true. |
spring.cloud.azure.eventhubs.connection-string | Azure Event Hubs connection string. Provide this value when you want to provide the connection string directly. |
spring.cloud.azure.eventhubs.namespace | Azure Event Hubs namespace. Provide this value when you want to retrieve the connection information through Azure Resource Manager. |
spring.cloud.azure.eventhubs.resource.resource-group | The resource group of Azure Event Hubs namespace. Provide this value when you want to retrieve the connection information through Azure Resource Manager. |
spring.cloud.azure.profile.subscription-id | The subscription ID. Provide this value when you want to retrieve the connection information through Azure Resource Manager. |
Dependency setup
Add the following dependency to your project. This will automatically include the spring-boot-starter
dependency in your project transitively.
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter</artifactId>
</dependency>
Note
Remember to add the BOM spring-cloud-azure-dependencies
along with the above dependency. For details, see the Getting started section.
Basic usage
The following sections show the classic Spring Boot application usage scenarios.
Use OAuth authentication
When you use the OAuth authentication provided by Spring Cloud Azure for Kafka, you can configure the specific credentials using the above configurations. Alternatively, you can choose to configure nothing about credentials, in which case Spring Cloud Azure will load the credentials from the environment. This section describes the usages that load the credentials from the Azure CLI environment or the Azure Spring Apps hosting environment.
Note
If you choose to use a security principal to authenticate and authorize with Azure Active Directory for accessing an Azure resource, see the Authorize access with Azure Active Directory section to make sure the security principal has been granted the sufficient permission to access the Azure resource.
The following section describes the scenarios using different Spring ecosystem libraries with OAuth authentication.
Spring Kafka application support
This section describes the usage scenario for Spring Boot application using Spring Kafka or Spring Integration Kafka library.
Dependency setup
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter</artifactId>
</dependency>
<!-- Using Spring Kafka library only-->
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<version>{version}</version><!--Need to be set, for example:2.8.6-->
</dependency>
<!-- Using Spring Integration library only -->
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-kafka</artifactId>
<version>{version}</version><!--Need to be set, for example:5.5.12-->
</dependency>
Configuration update
To use the OAuth authentication, just specify the Event Hubs endpoint, as shown in the following example:
spring.kafka.bootstrap-servers=<NAMESPACENAME>.servicebus.windows.net:9093
Spring Cloud Stream binder Kafka application support
This section describes the usage scenario for Spring Boot applications using the Spring Cloud Stream binder Kafka library.
Dependency setup
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-kafka</artifactId>
<version>{version}</version><!--Need to be set, for example:3.2.3-->
</dependency>
Configuration
To use the OAuth authentication, just specify the Event Hubs endpoint as shown in the following example:
spring.cloud.stream.kafka.binder.brokers=<NAMESPACENAME>.servicebus.windows.net:9093
Note
If you're using version 4.3.0
, don't forget to set the spring.cloud.stream.binders.<kafka-binder-name>.environment.spring.main.sources=com.azure.spring.cloud.autoconfigure.kafka.AzureKafkaSpringCloudStreamConfiguration
property to enable the whole OAuth authentication workflow, where kafka-binder-name
is kafka
by default in a single Kafka binder application. The configuration AzureKafkaSpringCloudStreamConfiguration
specifies the OAuth security parameters for KafkaBinderConfigurationProperties
, which is used in KafkaOAuth2AuthenticateCallbackHandler
to enable Azure Identity.
For version after 4.4.0
, this property will be added automatically for each Kafka binder environment, so there's no need for you to add it manually.
Samples
See the azure-spring-boot-samples repository on GitHub.
Use connection string authentication
You can use connection string authentication directly or use the Azure Resource Manager to retrieve the connection string.
Note
Since version of 4.3.0, connection string authentication is deprecated in favor of OAuth authentications.
Since version of 4.5.0, when using connection string authentication with Spring Cloud Stream framework, the following property is required to ensure that the connection string can take effect, where the <kafka-binder-name>
placeholder has a value of kafka
by default.
spring.cloud.stream.binders.<kafka-binder-name>.environment.spring.main.sources=com.azure.spring.cloud.autoconfigure.eventhubs.kafka.AzureEventHubsKafkaAutoConfiguration
Dependency setup
Add the following dependencies if you want to migrate your Apache Kafka application to use Azure Event Hubs for Kafka.
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter</artifactId>
</dependency>
If you want to retrieve the connection string using Azure Resource Manager, add the following dependency:
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-resourcemanager</artifactId>
</dependency>
Configuration
Use Event Hubs connection string directly
The simplest way to connect to Event Hubs for Kafka is with the connection string. Just add the following property.
spring.cloud.azure.eventhubs.connection-string=${AZURE_EVENTHUBS_CONNECTION_STRING}
Use Azure Resource Manager to retrieve connection string
If you don't want to configure the connection string in your application, you can use Azure Resource Manager to retrieve the connection string. To authenticate with Azure Resource Manager, you can also use credentials stored in Azure CLI or another local development tool such as Visual Studio Code or Intellij IDEA. Alternately, you can use Managed Identity if your application is deployed to Azure Cloud. Just be sure the principal has sufficient permission to read resource metadata.
Note
If you choose to use a security principal to authenticate and authorize with Azure Active Directory for accessing an Azure resource, see the Authorize access with Azure Active Directory section to be sure the security principal has been granted the sufficient permission to access the Azure resource.
To use Azure Resource Manager to retrieve the connection string, just add the following property.
spring:
cloud:
azure:
profile:
subscription-id: ${AZURE_SUBSCRIPTION_ID}
eventhubs:
namespace: ${AZURE_EVENTHUBS_NAMESPACE}
resource:
resource-group: ${AZURE_EVENTHUBS_RESOURCE_GROUP}
Samples
See the azure-spring-boot-samples repository on GitHub.
Redis support
Connect to Azure Cache for Redis using Spring Redis libraries. With adding spring-cloud-azure-starter
and spring-cloud-azure-resourcemanager
to your application, it's possible to read the Azure Cache for Redis connection information through Azure Resource Manager and auto-configure the Redis properties.
Dependency setup
Add the following dependencies if you want to use the Spring Cloud Azure Redis support to your Spring Boot application using Redis.
<dependencies>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter</artifactId>
</dependency>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-resourcemanager</artifactId>
</dependency>
</dependencies>
Configuration
Note
If you choose to use a security principal to authenticate and authorize with Azure Active Directory for accessing an Azure resource, refer to Authorize access with Azure AD to make sure the security principal has been granted the sufficient permission to access the Azure resource.
Configurable properties when using Redis support:
Property | Description | Default Value | Required |
---|---|---|---|
spring.cloud.azure.redis.enabled | Whether an Azure Cache for Redis is enabled. | true | No |
spring.cloud.azure.redis.name | Azure Cache for Redis instance name. | Yes | |
spring.cloud.azure.redis.resource.resource-group | The resource group of Azure Cache for Redis. | Yes | |
spring.cloud.azure.profile.subscription-id | The subscription ID. | Yes |
Note
Authentication information is also required for authenticating for Azure Resource Manager. The credential related configurations of Resource Manager should be configured under prefix spring.cloud.azure
. For more information, see the Authentication section.
Basic usage
Add the following properties and you are good to go.
spring.cloud.azure.redis.name=${AZURE_CACHE_REDIS_NAME}
spring.cloud.azure.redis.resource.resource-group=${AZURE_CACHE_REDIS_RESOURCE_GROUP}
Samples
See azure-spring-boot-samples for more details.
Azure Resource Manager
Azure Resource Manager (ARM) is the deployment and management service for Azure. It provides a management layer that enables you to create, update, and delete resources in your Azure account. Spring Cloud Azure Resource Manager can help provision resources or retrieve resource metadata.
Dependency setup
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-resourcemanager</artifactId>
</dependency>
Configuration
Note
If you choose to use a security principal to authenticate and authorize with Azure Active Directory for accessing an Azure resource, refer to Authorize access with Azure AD to make sure the security principal has been granted the sufficient permission to access the Azure resource.
Configurable properties of spring-cloud-azure-resourcemanager:
Property | Description |
---|---|
spring.cloud.azure.resource-manager.enabled | Whether the Resource Manager is enabled. Default is true. |
spring.cloud.azure.credential.client-id | Client ID to use when performing service principal authentication with Azure. |
spring.cloud.azure.credential.client-secret | Client secret to use when performing service principal authentication with Azure. |
spring.cloud.azure.credential.client-certificate-path | Path of a PEM certificate file to use when performing service principal authentication with Azure. |
spring.cloud.azure.credential.client-certificate-password | Password of the certificate file. |
spring.cloud.azure.credential.username | Username to use when performing username/password authentication with Azure. |
spring.cloud.azure.credential.password | Password to use when performing username/password authentication. |
spring.cloud.azure.credential.managed-identity-enabled | Whether to enable managed identity. |
spring.cloud.azure.profile.cloud-type | Name of the Azure cloud to connect to. |
spring.cloud.azure.profile.environment.active-directory-endpoint | The Azure Active Directory endpoint to connect to for authentication. |
spring.cloud.azure.profile.subscription-id | Subscription ID to use when connecting to Azure resources. |
spring.cloud.azure.profile.tenant-id | Tenant ID for Azure resources. |
spring.cloud.azure.azure-service.namespace | The namespace of the Azure service to provision resources with. |
spring.cloud.azure.azure-service.resource.resource-group | The resource group holding an Azure service resource. |
Basic usage
Spring Cloud Azure Resource Manager can work together with specific Spring Cloud Azure starters to retrieve connection information, such as connection strings, to connect to Azure services. It can also work together with spring-cloud-azure-starter
and third-party libraries to retrieve metadata like username/password, and to complete authentication. For more information, see the Kafka Support and Redis Support sections.
For example, to retrieve the connection string of an Azure Service, developers can use a service principal as the credential to authenticate and retrieve the connection string. The configuration is listed the follows. The provided service principal should
be assigned a role of Contributor
of the associated namespace at least. See Authorize access with Azure AD to make sure the principal has been granted the sufficient permission to access the Azure resource.
spring:
cloud:
azure:
credential:
client-id: ${AZURE_CLIENT_ID}
client-secret: ${AZURE_CLIENT_SECRET}
profile:
tenant-id: ${AZURE_TENANT_ID}
subscription-id: ${AZURE_SUBSCRIPTION_ID}
<azure-service>:
namespace: ${SERVICEBUS_NAMESPACE}
resource:
resource-group: ${RESOURCE_GROUP}
Samples
See azure-spring-boot-samples for more details.
Configuration properties
To see the list of all Spring Cloud Azure related configuration properties, see Spring Cloud Azure configuration properties.
Appendix
Feedback
Submit and view feedback for