Skip to content

Spring Cloud Azure 4.0 Design

Xiaolu Dai edited this page Nov 11, 2022 · 1 revision

Overview

The vision of Spring Cloud Azure is offering a convenient way to interact with Azure provided services using well-known Spring idioms and APIs for Spring developers. With this vision, we can confidently tell experienced Spring developers, "you already know how to create value with Azure."

Where we fall short of delivering this vision

  • We do not enable the complete set of Azure configurations using only Spring configuration mechanism. One of the main features in Spring Cloud Azure is to autoconfigure the SDK clients, but some autoconfigurations are not supported with our libraries, which will result our user fall back to sdk.

    • Our modules don't cover all SDK's configurations.
      • For example: CosmosClientBuilder support permissions and gatewayMode in sdk, but azure-spring-boot-starter-cosmos doesn't support user configure, if users want to configure these properties, they have to build azure sdk client by themselves instead of leverage our auto-configuration's support.
    • Our modules don't support some credentials supported by sdk.
      • For example: azure-spring-boot-starter-cosmos only support AzureKeyCredential but azure-cosmos also support TokenCredential.
  • We limit our modules to require Spring Boot in all cases. Our modules are all based on spring boot, which limits the user's scenarios to use our libaries.

    • For example: If user only use spring-integration with eventhubs through azure-spring-integration-eventhubs library, it should not import spring boot libraries, but azure-spring-integration-eventhubs dependends on Spring boot.
  • We force users to understand inconsistencies that arise from haphazard development choices. As an open source project base on Spring eco-system, in some scenarios, our modules don't follow Spring's well-known convention, which will increase the learning cost for users who are familiar with Spring.

    • Naming of modules. For starters, we have modules named azure-spring-boot-starter-cosmos,azure-spring-cloud-starter-eventhubs.

    • Starters should have pom only.

      The spring boot starter convention is that it is responsible for dependency management only. If we look at the code for spring-cloud-gcp-starters, we will see that their starters are very simple, which allows the user to see very visually what dependencies are introduced by the starter. We should follow this convention too.

    • Our dependency structure doesn't have a clear and layered structure compared with Spring.

      • azure-spring-cloud-messaging depends on azure-spring-integration-core, which is incorrect and confusing to users. If we look at how Spring organizes these modules, we will find spring has a spring-messaging module and a spring-integration-kafka module, spring-integration-kafka is dependent on spring-messaging.
    • For historical reasons, our modules are divided into azure-spring-boot-xxx and azure-spring-cloud-xxx
      • This increases user's learning cost, users may not know the difference between the two and don't how to choose.
      • This increase maintenance costs, some codes need to be maintained in two modules that can't be shared very well.

Goals

The main goal is to make it easier and more convenient for users to use Azure service with Spring.

  1. Simplify users' configuration, make it easier for users to configure Azure service.

  2. Users are not blocked to use Azure SDK features.

  3. Support all credentials supported by Azure SDKs.

  4. Make it easy to support a new azure sdk.

  5. Support all programming models supported by Spring which can be integrated with our Azure service.

  6. Make the dependency structure between azure Spring modules clearer, each project has clear responsibility.

  7. Enable users with different Spring abstractions such as Spring Data, Spring Integration to integrate Azure service easily.

  8. Make our modules more Spring native, follow Spring's convention, reduce our customer's learning effort.

Analysis

In order to achieve the goals, we are going to making the following changes:

  1. In order to achieve the goals 1~4, we redesigned our spring cloud azure core module, which provides an abstraction layer between upper Azure Spring projects and Azure SDKs.
  2. In order to achieve the goals 5~7, we redesigned our directories, module structures, naming and dependencies.
    1. We divided our modules from one folder into several different folders, which is align with spring project.
    2. We unified the naming of our modules.
    3. We changed the structure of modules' dependencies.
  3. In order to achieve the goals 8, We changed the content in our starter modules, to make the starter modules contain pom only.

1. Design Spring Cloud Azure Core

There are two design docs for the spring cloud azure core module:

The spring cloud azure core module is the key component to achive goals 1~4, to be more specific, it needs to cover below sub-goals:

  • Provide a common template of configuring all the Azure SDK clients, no matter which protocol it uses, HTTP or AMQP.
  • Provide the ability to configure every single configuration item the Azure SDK clients expose. To be more specific:
    • All the authentication methods each Service or SDK supports.
    • Proxy configurations.
    • Retry configurations.
    • Logging configurations.
    • Underlying client configurations, for example, HttpClient.
    • Other sdk configurations.
  • Provide an extensible way for replacing Azure SDK provided implementations with Spring common implementations, such as using WebClient as HttpClient and configuring loggings with Spring properties.
  • Provide abstraction support for upper-layer functions, such as:
    • spring-retry support
    • micrometer
    • tracing

2. Design modules' structure

2.1 Break down the directory from one to several different folders

We have only one folder called spring before, we placed all our modules into this folder, there are more than 50 modules in the folder. We created several more folders to categorize our modules, below is the overall structure.

image

image

2.2 Unified the naming of our modules.

We unified our module names to follow the same convention: spring-[cloud|messaging|integration|security]-azure-xxx, below is the detailed list. image

2.3 Change the structure of modules' dependencies.

2.3.1 Why to redesign the modules' dependencies.

  • Spring provides different layered abstractions such as Spring integration, Spring Data, Spring Cloud Stream, etc. We should enable users to integrate our Azure services with these different abstractions.
  • Below is an example to demonstrate Spring's layered structure. image
  • To integrate with Kafka, user may use spring-kafka,spring-integration-kafka,spring-cloud-stream-binder-kafka. It all depends on the programming model user want to use.
  • User should only care spring's abstraction, user don't need to care about interface in AzureSDKs, in order to achieve this goal, we need to redesign our modules' dependencies.

2.3.2 The Expected structure for each projects

Expected structure for Spring Cloud Azure Starters.
  • This is the expected structure about Spring Cloud Azure starters.
  • image
Expected structure for Azure EventHubs.
  • This is the expected structure for Azure EventHubs. Check this design doc for more info. mermaid-diagram-20211013135354
Expected structure for Service Bus
  • This is the expected structure for Service Bus. Check this design doc for more info. mermaid-diagram-20211013135242

3. Make the starter modules contain pom only

Remove all unrelated files in starters, to keep pom only in starters.

image

Design each module based on Spring framework

Design Doc Developer
Spring Cloud Azure Core design saragluna
Design for directory, module name and package path for Spring Cloud Azure messaging yiliuTo
Spring Cloud Azure auto configure design chenrujun
Spring Cloud Azure Messaging design yiliuTo

Success Criteria

  • All Spring cloud azure 4.0 libraries release.
  • All tests(IT/UT) pass with test Coverage > 90%
Clone this wiki locally