Introduction to Azure Spring Cloud — Part 2: Inventory Service

This post is part of a series about Azure Spring Cloud and a continuation of the Part 1. The Azure Setup mentioned in the Part 1 is a prerequisite for deploying the application mentioned here.

Sample Applications

Sample Applications

We will start with a simple REST web service and will then add Spring Cloud features. Create a starter project using http://start.spring.io, and select the features Spring Web, Azure Support, lombok. Open the generated project in an IDE.

Create a REST Controller class with a Post method that accepts a List of Inventory objects and returns a response. In this example, I used Lombok to simplify the bean classes. So, check “Enable Annotation Processing” (if using IntelliJ). If Lombok plugin is not already installed, install it from the Plugins section.

Create an Inventory class.

Inventory.java

The @Data annotation adds a getter and setter for all fields and overrides the toString, equals and hashCode methods. The @AllArgsConstructor adds an “all arguments constructor”.

At this point, we have a simple REST App. Now, let’s add the necessary code to interact with an Azure Cosmos Database.

Cosmos DB Integration

Add azure-cosmosdb-spring-boot-starterto the dependency list in your build file.

com.microsoft.azure:azure-cosmosdb-spring-boot-starter

Since we selected Azure Support in the list of dependencies during the app creation, a property named azure.versionwill be present in the <properties> tag. So, we do not need to explicitly mention a version number for any dependency from com.microsoft.azure group.

Next, create a repository interface that extends CosmosRepository from the Azure Cosmos library

InventoryRepository.java

Our idfield is a String type and hence, in the above snippet, you can see the usage of String for ID.

Inject the Repository to the Controller and modify the Controller method to invoke the saveAll method. Create another method to provide a GET interface. This method will return all entries from the database.

InventoryController.java

Even though we haven’t coded any validations or exception scenarios, at this point, we have an app ready to be deployed to Azure.

An important point to note here is that, as a developer, you haven’t written any code or added any configurations to connect to a Cosmos DB. This is where the advantage of using Azure Spring Cloud comes into the picture. Let’s see how to deploy this app and test it in Azure.

Application Deployment

For the purpose of this sample, we will not cover the unit testing, as it requires several configurations to ensure a successful execution of JUnit test cases in the local workspace. So, in order to make it easier, delete the InventoryApplicationTests that got created while generating the project.

Compile and Build a jar.

Navigate to the root of the project in the CLI and execute the command below to deploy the generated jar to Azure Spring Cloud:

az spring-cloud app deploy -n <name_of_app> -s <name_of_azure_spring_cloud> -g <resource_group_name> --jar-path <path_to_generated_jar>

The generated jar will be present under the `target` folder. For ex: `/target/inventory-0.0.1-SNAPSHOT.jar`

Once the command finishes the execution, go to the App Instances section in the Portal and wait for only 1 instance to be in the Running status. The Discovery Status column will show DOWN. We’ll come to that later.

We have completed the deployment of our app, and our app has successfully connected to the Cosmos Database that we created. In order to validate this, you can go to the Data Explorer section of Cosmos DB and you’ll see a new container named inventory under the database. The container name defaults to the name of the Inventory class. We can override this with an annotation, if needed.

Inventory document created inside the DB

As you can see, without any code or configuration, our app was able to connect to the DB and create a collection. This works because Azure Spring Cloud injected the three variables needed for our app to connect to Cosmos (azure.cosmosdb.uri, azure.cosmosdb.database, azure.cosmosdb.key)! You can see these variables if you click on the Service binding entry under the App.

Now, let’s test our application. Using the browser, access the GET interface. You’ll see an empty list. Using cURL or Postman, invoke the POST endpoint with valid data. I used postman with sample data as below.

Now, access the GET endpoint again and you’ll see the response below:

Service Registry Integration

Application Deployment

As indicated above, our app instance shows the Discover Status as DOWN. This is because we have not yet configured any Service Registry. Let’s go ahead and do that now.

Add the below dependencies to the pom.xml:

org.springframework.cloud:spring-cloud-starter-netflix-eureka-clientcom.microsoft.azure:spring-cloud-starter-azure-spring-cloud-client:2.2.0

Since we are adding the Spring Cloud dependencies, add this snippet to the dependencyManagement and to properties section of pom.xml file:

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><spring-cloud.version>Greenwich.SR3</spring-cloud.version>

IMPORTANT: The spring-cloud-starter-azure-spring-cloud-client dependency ensures that the auto configurations happen during startup. Without this, the app will not start in Azure

Add @EnableDiscoveryClient to the InventoryApplication class. This will register our application in the Eureka Service Registry provided by Azure Spring Cloud.

Now, run clean, package and deploy our application. Use the same deploy command as before. Once the deployment is completed, you’ll see that the Discover Status has changed to UP. Now, any other apps deployed in Azure Spring Cloud can discover this app using its name.

Config Server Integration

In order to demonstrate the integration with a Config Server, we’ll create a simple repository with one property — a feature flag which determines whether to enable saving of inventory data in database.

Config Server Setup

Create a new Git repo or use an existing repo. Create a file named ‘inventory-service.yml’ and add the below property:

feature-flag:  saveInventory: false

Note: The formatting in the above snippet has to match the requirements of yml.

Assuming that this file is present in the ‘master’ of the Git repo, let’s add this information to Azure.

Azure Setup

Go to the Azure Spring Cloud resource and access the Config Server option from the Left Navigation.

Add the Git repo URL under Uri and the branch name under Label and click Apply. Wait for the changes to be completed.

Config Server setup

Application Deployment

Now, let’s make changes to the application. Add the following dependency:

org.springframework.cloud:spring-cloud-config-client

In order to take advantage of the auto configuration, let’s add a class named FeatureFlag.

FeatureFlag.java

@Configuration marks the class as a Spring Configuration class. @ConfigurationProperties(prefix = “feature-flag”) will help with auto configuration. Azure Spring Cloud Config Server will inject any property with feature-flag prefix to the variables in this class. Please note that the prefix must follow kebab case. @Data provides the getter and setter methods.

The name of the fields should match with the variable names in the config file (inventory-service.yml).

Now, let’s modify the Controller to inject the class and use it in the POST method to decide whether to save the data in the database.

InventoryController.java

Now, clean, package and deploy our application. Use the same deploy command as before.

Once the deployment is completed, invoke the POST endpoint again and you’ll get a “HTTP 501 — Not Implemented”, error since the feature flag is false. This confirms that Azure Spring Cloud read the configuration from the Git URL we gave and injected into the Application and the Configuration class.

Just to test the change in configuration, modify the file in Git to change the “saveInventory” flag to `true`. Restart the application and invoke the POST endpoint again. This time, the app will return a success response.

The final code for this is available in the Github page

Next, we’ll explore Order Service.

Introduction to Azure Spring Cloud — Part 3: Order Service

Introduction to Azure Spring Cloud — Part 1: Introduction, Azure Setup

Java and Cloud Architect