Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save saragluna/7e1754a7d17d0820f223ddba8621e2c7 to your computer and use it in GitHub Desktop.
Save saragluna/7e1754a7d17d0820f223ddba8621e2c7 to your computer and use it in GitHub Desktop.
Spring Cloud Azure autoconfiguration champion scenarios

Spring Cloud Azure Autoconfigurations

  1. Autoconfigure a SecretClient

  2. Autoconfigure a CertificateClient

  3. Autoconfigure a CosmosClient

  4. Autoconfigure a ConfigurationClient

  5. Autoconfigure a BlobServiceClient

  6. Autoconfigure a BlobContainerClient

  7. Autoconfigure a BlobClient

  8. Autoconfigure a ShareServiceClient

  9. Autoconfigure a ShareClient

  10. Autoconfigure a ShareFileClient

  11. Autoconfigure a QueueServiceClient

  12. Autoconfigure an Event Hubs producer

  13. Autoconfigure an Event Hubs consumer

  14. Autoconfigure an Event Hubs processor

  15. Autoconfigure an Event Hubs processor with another checkpoint store implementation

  16. Autoconfigure producer and consumer of different Event Hubs namespaces

  17. Autoconfigure a Service Bus producer

  18. Autoconfigure a Service Bus consumer

  19. Autoconfigure a Service Bus session enabled consumer

  20. Autoconfigure a Service Bus processor

  21. Autoconfigure producer and consumer of different Service Bus namespaces

  22. Authenticate with Azure Identity

    1. DefaultAzureCredential
    2. Authenticate use managed identity
    3. Authenticate use service principal
    4. Authenticate using different methods
  23. Configure proxy

    1. Configure proxy for all clients
    2. Configure proxy for single service client
  24. Use ClientBuilderFactorys

  25. Autoconfigure an Event Hubs Client Builder Factory

Autoconfigure a Key Vault secret client

a. Configure options in application.yaml

spring.cloud.azure:
  keyvault:
    secret: 
      endpoint: ${AZURE_KEYVAULT_ENDPOINT}

b. Autowire SecretClient in Spring Boot application:

@Service 
public class KeyVaultService {
  
  @Autowired 
  private SecretClient secretClient; // SecretAsyncClient is also available for autowire
  
}

Autoconfigure a Key Vault certificate client

a. Configure options in application.yaml

spring.cloud.azure:
  keyvault:
    certificate: 
      endpoint: ${AZURE_KEYVAULT_ENDPOINT}

b. Autowire CertificateClient in Spring Boot application:

@Service 
public class KeyVaultService {
  
  @Autowired 
  private CertificateClient secretClient; // CertificateAsyncClient is also available for autowire
  
}

Autoconfigure a Cosmos Client

a. Configure options in application.yaml

spring.cloud.azure:
  cosmos: 
    endpoint: ${AZURE_COSMOS_ENDPOINT}

b. Autowire CosmosClient in Spring Boot application:

@Service
public class CosmosService {
  
  @Autowired
  private CosmosClient client; // CosmosAsyncClient is also available for autowire
  
}

Autoconfigure an App Configuration Client

a. Configure options in application.yaml

spring.cloud.azure:
  appconfiguration: 
    endpoint: ${AZURE_APPCONFIGURATION_ENDPOINT}

b. Autowire ConfigurationClient in Spring Boot application:

@Service
public class AppConfigurationService {
  
  @Autowired
  private ConfigurationClient client; // ConfigurationAsyncClient is also available for autowire
  
}

Autoconfigure a Storage Blob Service Client

a. Configure options in application.yaml

spring.cloud.azure:
  storage:
    blob: 
      endpoint: ${AZURE_STORAGE_ENDPOINT}

b. Autowire BlobServiceClient in Spring Boot application:

@Service
public class StorageBlobService {
  
  @Autowired
  private BlobServiceClient client; // BlobServiceAsyncClient is also available for autowire
  
}

Autoconfigure a Storage Blob Container Client

a. Configure options in application.yaml

spring.cloud.azure:
  storage:
    blob: 
      endpoint: ${AZURE_STORAGE_ENDPOINT}
      container-name: ${AZURE_STORAGE_CONTAINER_NAME}

b. Autowire BlobContainerClient in Spring Boot application:

@Service
public class StorageBlobService {
  
  @Autowired
  private BlobContainerClient client; // BlobContainerAsyncClient is also available for autowire
  
}

Autoconfigure a Storage Blob Client

a. Configure options in application.yaml

spring.cloud.azure:
  storage:
    blob: 
      endpoint: ${AZURE_STORAGE_ENDPOINT}
      container-name: ${AZURE_STORAGE_CONTAINER_NAME}
      blob-name: ${AZURE_STORAGE_BLOB_NAME}

b. Autowire BlobClient in Spring Boot application:

@Service
public class StorageBlobService {
  
  @Autowired
  private BlobClient client; // BlobAsyncClient is also available for autowire
  
}

Autoconfigure a Storage Share Service Client

a. Configure options in application.yaml

spring.cloud.azure:
  storage:
    fileshare: 
      endpoint: ${AZURE_STORAGE_ENDPOINT}

b. Autowire ShareServiceClient in Spring Boot application:

@Service
public class StorageShareService {
  
  @Autowired
  private ShareServiceClient client; // ShareServiceAsyncClient is also available for autowire
  
}

Autoconfigure a Storage Share Client

a. Configure options in application.yaml

spring.cloud.azure:
  storage:
    fileshare: 
      endpoint: ${AZURE_STORAGE_ENDPOINT}
      share-name: ${AZURE_STORAGE_SHARE_NAME}

b. Autowire ShareClient in Spring Boot application:

@Service
public class StorageShareService {
  
  @Autowired
  private ShareClient client; // ShareAsyncClient is also available for autowire
  
}

Autoconfigure a Storage Share File Client

a. Configure options in application.yaml

spring.cloud.azure:
  storage:
    blob: 
      endpoint: ${AZURE_STORAGE_ENDPOINT}
      share-name: ${AZURE_STORAGE_SHARE_NAME}
      file-name: ${AZURE_STORAGE_FILE_NAME}

b. Autowire ShareFileClient in Spring Boot application:

@Service
public class StorageShareService {
  
  @Autowired
  private ShareFileClient client; // ShareFileAsyncClient is also available for autowire
  
}

Autoconfigure a Storage Queue Service Client

a. Configure options in application.yaml

spring.cloud.azure:
  storage:
    queue: 
      endpoint: ${AZURE_STORAGE_ENDPOINT}

b. Autowire QueueServiceClient in Spring Boot application:

@Service
public class StorageQueueService {
  
  @Autowired
  private QueueServiceClient client; // QueueServiceAsyncClient is also available for autowire
  
}

Autoconfigure an Event Hubs producer

a. Configure options in application.yaml

spring.cloud.azure:
  eventhubs: 
    namespace: ${AZURE_EVENTHUBS_NAMESPACE}
    producer:
      event-hub-name: ${AZURE_EVENTHUBS_PRODUCER}

b. Autowire EventHubProducerClient in Spring Boot application:

@Service 
public class EventHubsProducerService {
  
  @Autowired
  private EventHubProducerClient client; // EventHubProducerAsyncClient is also available for autowire
  
}

Autoconfigure an Event Hubs consumer

a. Configure options in application.yaml

spring.cloud.azure:
  eventhubs: 
    namespace: ${AZURE_EVENTHUBS_NAMESPACE}
    consumer:
      event-hub-name: ${AZURE_EVENTHUBS_CONSUMER}
      consumer-group: ${AZURE_EVENTHUBS_CONSUMER_GROUP}

b. Autowire EventHubConsumerClient in Spring Boot application:

@Service 
public class EventHubsConsumerService {
  
  @Autowired
  private EventHubConsumerClient client; // EventHubConsumerAsyncClient is also available for autowire
  
}

Autoconfigure an Event Hubs processor

a. Configure options in application.yaml

spring.cloud.azure:
  eventhubs: 
    namespace: ${AZURE_EVENTHUBS_NAMESPACE}
    processor:
      event-hub-name: ${AZURE_EVENTHUBS_PROCESSOR}
      consumer-group: ${AZURE_EVENTHUBS_CONSUMER_GROUP}
      checkpoint-store:
        account-name: ${AZURE_STORAGE_ACCOUNT_NAME}
        container-name: ${AZURE_STORAGE_CONTAINER_NAME}

b. Provide a EventProcessingListener in Spring Boot application:

@Configuration
public class UserConfiguration {
  
  @Bean
  EventProcessingListener myEventHubEventListener() {
      return (RecordEventProcessingListener) eventContext -> {
          // on event
      };
  }
}

c. Autowire EventProcessorClient in Spring Boot application:

@Service 
public class EventHubsProcessorService {
  
  @Autowired
  private EventProcessorClient client;
  
}

Autoconfigure an Event Hubs processor with another checkpoint store implementation

a. Configure options in application.yaml

spring.cloud.azure:
  eventhubs: 
    namespace: ${AZURE_EVENTHUBS_NAMESPACE}
    processor:
      event-hub-name: ${AZURE_EVENTHUBS_PROCESSOR}
      consumer-group: ${AZURE_EVENTHUBS_CONSUMER_GROUP}

b. Provide a CheckpointStore in Spring Boot application:

@Configuration
public class UserConfiguration {
  
  @Bean
  CheckpointStore myCheckpointStore() {
      // MyCheckpointStore is another implementation of CheckpointStore
      return new MyCheckpointStore();
  }
}

c. Autowire EventProcessorClient in Spring Boot application:

@Service 
public class EventHubsProcessorService {
  
  @Autowired
  private EventProcessorClient client;
  
}

Autoconfigure producer and consumer of different Event Hubs namespaces

a. Configure options in application.yaml

spring.cloud.azure:
  eventhubs:   
    producer:
      namespace: ${AZURE_EVENTHUBS_NAMESPACE_1}
      event-hub-name: ${AZURE_EVENTHUBS_PRODUCER}
    consumer:
      namespace: ${AZURE_EVENTHUBS_NAMESPACE_2}
      event-hub-name: ${AZURE_EVENTHUBS_CONSUMER}

b. Autowire EventHubProducerClient and EventHubConsumerClient in Spring Boot application:

@Service 
public class EventHubsService {
  
  @Autowired
  private EventHubProducerClient producerClient; 
  
  @Autowired
  private EventHubConsumerClient consumerClient;
  
  void receiveAndSend() {
		// Consume events from the first event hub.
    consumerClient.receiveFromPartition(partitionId, 15, EventPosition.earliest(), Duration.ofSeconds(40));
		// processing the events 
    ...
    //and then send to another event hub
    producerClient.send(...);
  }
}

Autoconfigure a Service Bus producer

a. Configure options in application.yaml

spring.cloud.azure:
  servicebus: 
    namespace: ${AZURE_SERVICEBUS_NAMESPACE}
    producer:
      entity-type: QUEUE
      entity-name: ${AZURE_SERVICEBUS_QUEUE_NAME}

b. Autowire ServiceBusSenderClient in Spring Boot application:

@Service 
public class ServiceBusProducerService {
  
  @Autowired
  private ServiceBusSenderClient client; // ServiceBusSenderAsyncClient is also available for autowire
  
}

Autoconfigure a Service Bus consumer

a. Configure options in application.yaml

spring.cloud.azure:
  servicebus: 
    namespace: ${AZURE_SERVICEBUS_NAMESPACE}
    consumer:
      entity-type: QUEUE
      entity-name: ${AZURE_SERVICEBUS_QUEUE_NAME}

b. Autowire ServiceBusReceiverClient in Spring Boot application:

@Service 
public class ServiceBusConsumerService {
  
  @Autowired
  private ServiceBusReceiverClient client; // ServiceBusReceiverAsyncClient is also available for autowire
  
}

Autoconfigure a Service Bus session enabled consumer

a. Configure options in application.yaml

spring.cloud.azure:
  servicebus: 
    namespace: ${AZURE_SERVICEBUS_NAMESPACE}
    consumer:
      entity-type: QUEUE
      entity-name: ${AZURE_SERVICEBUS_QUEUE_NAME}
      session-enabled: true

b. Autowire ServiceBusSessionReceiverClient in Spring Boot application:

@Service 
public class ServiceBusConsumerService {
  
  @Autowired
  private ServiceBusSessionReceiverClient client; // ServiceBusSessionReceiverAsyncClient is also available for autowire
  
}

Autoconfigure a Service Bus processor

a. Configure options in application.yaml

spring.cloud.azure:
  servicebus: 
    namespace: ${AZURE_SERVICEBUS_NAMESPACE}
    processor:
      entity-type: TOPIC
      entity-name: ${AZURE_SERVICEBUS_TOPIC_NAME}
      subscription-name: ${AZURE_SERVICEBUS_SUBSCRIPTION_NAME}

b. Provide a MessageProcessingListener in Spring Boot application:

@Configuration
public class UserConfiguration {
  
  @Bean
  MessageProcessingListener myServiceBusMessageListener() {
			return (RecordMessageProcessingListener) messageContext -> {
          // on message
      };
  }
}

c. Autowire ServiceBusProcessorClient in Spring Boot application:

@Service 
public class ServiceBusProcessorService {
  
  @Autowired
  private ServiceBusProcessorClient client;
  
}

Autoconfigure producer and consumer of different Service Bus namespaces

a. Configure options in application.yaml

spring.cloud.azure:
  servicebus:   
    producer:
      namespace: ${AZURE_SERVICEBUS_NAMESPACE_1}
      entity-type: TOPIC
      entity-name: ${AZURE_SERVICEBUS_TOPIC_NAME}
    processor:
      namespace: ${AZURE_SERVICEBUS_NAMESPACE_2}    
      entity-type: QUEUE
      entity-name: ${AZURE_SERVICEBUS_QUEUE_NAME}

b. Provide a MessageProcessingListener in Spring Boot application and use the ServiceBusSenderClient:

@Configuration
public class UserConfiguration {
  
  @Bean
  MessageProcessingListener myServiceBusMessageListener(ServiceBusSenderClient senderClient) {
			return (RecordMessageProcessingListener) messageContext -> {
          // on message
          // process message and then send to another entity
          senderClient.sendMessage(...);
      };
  }
}

Authenticate with Azure Idenity

DefaultAzureCredential

DefaultAzureCredential is applied to all SDK clients if no extra authenticating options are provided.

Authenticate use managed identity

spring.cloud.azure:
  eventhubs:   
    namespace: ${AZURE_EVENTHUBS_NAMESPACE}
    credential:
      managed-identity-client-id: ${USER_ASSIGNED_MANAGED_IDENTITY_CLIENT_ID}

Authenticate use service principal

spring.cloud.azure:
  eventhubs:   
    namespace: ${AZURE_EVENTHUBS_NAMESPACE}
    credential:
      client-id: ${AZURE_CLIENT_ID}
      client-serect: ${AZURE_CLIENT_SECRET}

Authenticate to different services using different methods

spring.cloud.azure:
  appconfiguration:
    endpoint: ${AZURE_APPCONFIGURATION_ENDPOINT}
    credential:
      client-id: ${AZURE_CLIENT_ID}
      client-secret: ${AZURE_CLIENT_SECRET}
  eventhubs:  
    namespace: ${AZURE_EVENTHUBS_NAMESPACE}
    credential:
      managed-identity-client-id: ${USER_ASSIGNED_MANAGED_IDENTITY_CLIENT_ID}

Configure Proxy

Configure proxy for all clients

spring.cloud.azure:
  proxy:
    hostname: ${AZURE_PROXY_HOSTNAME}
    port: ${AZURE_PROXY_PORT}

Configure proxy for single service client

spring.cloud.azure:
  keyvault:
    secret: 
      endpoint: ${AZURE_KEYVAULT_ENDPOINT}
      proxy: 
        hostname: ${AZURE_KEYVAULT_PROXY_HOSTNAME}
        port: ${AZURE_KEYVAULT_PROXY_PORT}

Use ClientBuilderFactorys

a. Define a BeanPostProcessor in Spring Boot application

static class AzureServiceClientBuilderFactoryPostProcessor implements BeanPostProcessor, BeanFactoryAware {

        private BeanFactory beanFactory;

        @SuppressWarnings("rawtypes")
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (bean instanceof AbstractAzureCredentialBuilderFactory) {
                return bean;
            }
            if (bean instanceof AbstractAzureServiceClientBuilderFactory
                && beanFactory.containsBean(DEFAULT_TOKEN_CREDENTIAL_BEAN_NAME)) {

                ((AbstractAzureServiceClientBuilderFactory) bean).setDefaultTokenCredential(
                    (TokenCredential) beanFactory.getBean(DEFAULT_TOKEN_CREDENTIAL_BEAN_NAME));
            }
            return bean;
        }

        @Override
        public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
            this.beanFactory = beanFactory;
        }
    }

b. Now this BeanPostProcessor can set the credential for all *ClientBuilderFactorys.

Autoconfigure an Event Hubs Client Builder Factory

a. Configure options in application.yaml

spring.cloud.azure:
  eventhubs:  
    namespace: ${AZURE_EVENTHUBS_NAMESPACE}

b. Autowire EventHubClientBuilderFactory in Spring Boot application:

@Service 
public class EventHubsService {
  
  @Autowired
  private EventHubClientBuilderFactory factory; 
    
  void createBuilder() {
    // builder1 and builder2 share the same configurations set up in the `application.yaml`
    EventHubClientBuilder builder1 = factory.build();
    EventHubClientBuilder builder2 = factory.build();
  }
}
@srnagar
Copy link

srnagar commented Dec 28, 2021

  • How does the customer discover the names of the properties to use? Is this documented somewhere?
    For e.g. how does the customer know the property name is spring.cloud.azure.eventhubs.processor.checkpoint-store.account-name?
spring.cloud.azure:
  eventhubs: 
    namespace: ${AZURE_EVENTHUBS_NAMESPACE}
    processor:
      event-hub-name: ${AZURE_EVENTHUBS_PROCESSOR}
      checkpoint-store:
        account-name: ${AZURE_STORAGE_ACCOUNT_NAME}
        container-name: ${AZURE_STORAGE_CONTAINER_NAME}
  • Add an example to show how to autoconfigure

    • KeyClient
    • CryptographyClient
  • Event Hubs:
    consumer-group should be included in the configuration when creating a consumer and should be made mandatory as that is what is recommended by the EH service team.

    Autoconfigure an Event Hubs processor

    • Checkpoint store is a pluggable module. Current configuration ties this to Blob Storage. We should allow for other types of checkpoint stores too.
    • Why is checkpoint store using account-name but the Storage Blob Container client using endpoint
  • Service Bus
    data-plane SDK uses receiver but spring configuration uses consumer. consumer is used by Event Hubs and Service Bus uses receiver. It might be better to align with the data-plane names to make the configuration intuitive depending on what client customers want.

  • Authentication
    We have TokenCredential, Key Credential, Named Key Credential supported by different clients. credential is too generic and won't be extensible for other formats. So, we should consider using token-credential, key-credential or named-key-credential.

spring.cloud.azure:
  eventhubs:   
    namespace: ${AZURE_EVENTHUBS_NAMESPACE}
    credential:
      managed-identity-client-id: ${USER_ASSIGNED_MANAGED_IDENTITY_CLIENT_ID}
  • Storage
    How do I create a BlobClient and a ContainerClient?
    If I have the following in application.yaml, will this allow autowiring both BlobClient and ContainerClient? If yes, how can I disambiguate when I need a container client with a different container name?
spring.cloud.azure:
  storage:
    blob: 
      endpoint: ${AZURE_STORAGE_ENDPOINT}
      container-name: ${AZURE_STORAGE_CONTAINER_NAME}
      blob-name: ${AZURE_STORAGE_BLOB_NAME}     

@saragluna
Copy link
Author

saragluna commented Dec 29, 2021

  • The full list of configuration properties is documented here https://microsoft.github.io/spring-cloud-azure/docs/current/reference/html/appendix.html#configuration-properties. This document is auto-generated using an annotation processor agent when compiling the source code, and the descriptions are JavaDocs on these fields. There are some missing descriptions now, this is because the released 4.0.0-beta.2 version is missing some JavaDocs, but we've added the JavaDocs now.
  • We haven't supported the KeyClient and CryptographyClient in 4.0 yet.
  • Event Hubs:
  • We are trying to unify the configuration properties naming for all messaging components in Spring Cloud Azure. There are a producer, a consumer and a processor. Just like what we did to unify all uri and endpoint properties to endpoint. And Spring users are more familiar with the concept consumer.
  • This is because we are trying to hide the type of credential in this property prefix.
  • Yes, when providing these properties a BlobClient and a ContainerClient will be auto-configured.
spring.cloud.azure:
  storage:
    blob: 
      endpoint: ${AZURE_STORAGE_ENDPOINT}
      container-name: ${AZURE_STORAGE_CONTAINER_NAME}
      blob-name: ${AZURE_STORAGE_BLOB_NAME}     

But the auto-configuration of Spring Boot is to cover the most common use case, so configuring two container clients are not supported by design. But users can do this to create another Container client.

@Autowired
private BlobServiceClient blobServiceClient;

private void createAnotherContainerClient() {
    blobServiceClient.getBlobContainerAsyncClient("another-container-name");
    // ....
}

@srnagar
Copy link

srnagar commented Dec 30, 2021

  • The names of configuration properties should be treated as public APIs and changing the name is considered a breaking change. So, we need to ensure that the names in the annotations are included in the API view and revapi is configured to catch name changes to these properties.
  • What's the plan for supporting KeyClient and CryptographyClient?
  • Event Hubs
    • The example for custom checkpoint store is fine. It makes sense to manually create the checkpoint store bean when not using one of the checkpoint stores that we provide. However, if we create another standard checkpoint store (like Storage Tables for example), which can also be a common type of checkpoint store, then we won't be able to support this through configuration. So, my suggestion was to change the property name from checkpoint-store to blob-checkpoint-store. This allows us to introduce another type of store later if required.
  • Makes sense to keep the names consistent for all messaging libraries and use consumer for both EH and SB.
  • Why do we want to hide the type of credential? It is important to distinguish between the different types of credentials because some clients support two or more types of authentication. See Text Analytics for example. The type of credential used also dictates the level of access the client has.
  • Makes sense. So, requiring multiple clients with different containers/blobs is an advanced scenario and isn't supported through auto configuration?

Some thoughts on the list of property names:

  • Why do we have enabled for each service? spring.cloud.azure.*.enabled. What happens when this is set to false?
  • What happens when spring.cloud.azure.eventhubs.processor.checkpoint-store.enabled is false but spring.cloud.azure.eventhubs.processor.enabled is true? The processor cannot run without a checkpoint store.
  • We should be consistent with the naming spring.cloud.azure.eventhub.checkpoint-container uses singular (eventhub) while spring.cloud.azure.eventhubs.consumer.namespace uses plural (eventhubs)
  • spring.cloud.azure.eventhubs.processor.partition-ownership-expiration-interval should be ``spring.cloud.azure.eventhubs.processor.load-balancing.partition-ownership-expiration-interval`
  • Properties like spring.cloud.azure.keyvault.secret.proxy.hostname are repetitive for every service. Have we considered inverting the property to spring.cloud.azure.proxy.hostname.<service> ?

@saragluna
Copy link
Author

saragluna commented Dec 30, 2021

  • Let me try to set up the API view for this autoconfiguration module.
  • Our first plan is to support some other data plane SDKs in next semester.
  • If we change to blob-checkpoint-store and add table-checkpoint-store, these two will be configurable at the same time, this is also confusing. Let us find some better way to support this scenario.
  • Take Text Analytics for example, user can specify the key credential by setting:
    spring.cloud.azure:
      textanalytics: 
        key: xxx
    or token credential:
     spring.cloud.azure:
      textanalytics: 
        credential:
          client-id: xxx
          client-secret: xxx
    The consideration here is if we use token-credential, users may wonder what is a token credential. And our plan is to move all the credential properties under this prefix.

@kasobol-msft
Copy link

  1. In KeyVault yaml is secred and certificate endpoint different ? If not, then should we just have spring.cloud.azure.keyvault.endpoint?
  2. In Storage Share. Should file-name be file-path ? It can have directories (https://docs.microsoft.com/en-us/rest/api/storageservices/operations-on-directories - directory is a concept there, which is different from blobs).
  3. Storage Queues - should user be able to provide queue-name and autowire QueueClient ?
  4. Could you ellaborate more on MyCheckpointStore - how would user implement one? I.e. how do they extend from CheckpointStore . Is CheckpointStore Azure type?

@lmolkova
Copy link

lmolkova commented Jan 3, 2022

Is it possible to autowire a client builder?

@saragluna
Copy link
Author

@kasobol-msft

@saragluna
Copy link
Author

saragluna commented Jan 4, 2022

@lmolkova
Yes, it is possible. Take key vault secret client builder as an example:

@Autowired
private SecretClientBuilder builder;

@saragluna
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment