Skip to main contentModernization   Playbook

Refactoring Java EE Applications

Using the strangler pattern

Using the strangler pattern

Introduction

In this phase the backend application was analyzed and the Catalog service was identified as a candidate to be extracted in to it’s own Micro Service. The code was strangled from the monolith and deployed using Quarkus allowing the service to be developed, deployed and scaled independently of the rest of the application code.

Refactor the Catalog service to Quarkus

The Mono2Micro tool was used to identify the Catalog service as a good candidate to become it’s own service. In this scenario, the Catalog service handles information about the items in the store such as prices, titles, ratings and descriptions. When this information changes the store front as well as the items in the users carts should be updated.

Step 6

Analyze the Mono2Micro results

Running Mono2Micro is out of the scope of this article but detailed steps can be found here.

m2m

The purple rectangle is essentially the catalog service (except of the missing Category class).

The green classes make up the remaining monolith (except of Address).

The red classes need to be assigned to either the catalog service of the remaining monolith dependent of class dependencies. Most of them are exceptions which weren’t covered in the use cases.

The Quarkus Event Producer

In order to display the new price, the order service (the remaining monolith) could invoke a synchronous REST API of the catalog service. However, in order to minimize the coupling between the components, we will use events instead.

Here is the code of the ‘strangled’ catalog service which has been implemented with Quarkus. The application uses MicroProfile and Kafka to send events asynchronously.

@PUT
@Consumes("application/json")
@Produces("application/json")
@Path("/CustomerOrderServicesWeb/jaxrs/Product/{id}")
@Transactional
public Product update(@PathParam("id") Long id, Product updatedProduct) {
Product existingProduct = entityManager.find(Product.class, id);
if (existingProduct == null) {
throw new WebApplicationException(Response.Status.BAD_REQUEST);

The Event Consumer

The remaining monolith runs on Open Liberty. In order to prevent synchronous invocations of the catalog service, it caches the changed prices in it’s own Db2 database in a new column.

db2

Here is the code of the remaining monolith which also uses MicroProfile.

import org.eclipse.microprofile.reactive.messaging.Incoming;
import javax.enterprise.context.ApplicationScoped;
import org.pwte.example.service.CustomerOrderServicesImpl;
import javax.inject.Inject;
@ApplicationScoped
public class ProductPriceChanged {
@Inject

Run this solution

Use the following steps to run this solution locally on Docker

$ git clone https://github.com/IBM/application-modernization-javaee-quarkus.git && cd application-modernization-javaee-quarkus
$ ROOT_FOLDER=$(pwd)
$ sh ${ROOT_FOLDER}/scripts-docker/build-and-run-monolith-db2.sh
$ sh ${ROOT_FOLDER}/scripts-docker/run-database-postgres-catalog.sh
$ sh ${ROOT_FOLDER}/scripts-docker/run-kafka.sh
$ sh ${ROOT_FOLDER}/scripts-docker/build-and-run-catalog.sh

Summary

This application has been refactored in a series of steps from the original WebSphere ND v8.5.5 version to run as Micro Services on Red Hat OpenShift.