Football-player-microservice-lra

This service is an evolution of the service that we implemented in Chapter 3, Cloud-Native Applications.

Its goal is to handle the football player registry; in this version, we will use the MicroProfile specifications to build the LRA saga specifications. To make it easy to understand the use of the specifications, we will only change the edit method's management of the transaction.

To use LRA specifications, we will change the Maven pom.xml; the following code snippet shows the changes we've made:

<?xml version="1.0"   encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
...

<properties>
<version.thorntail>2.1.0.Final</version.thorntail>
...
<lra.http.host>localhost</lra.http.host>
<lra.http.port>8580</lra.http.port>
</properties>

<build>
<finalName>football-player-microservice-lra</finalName>
<plugins>
<plugin>
<groupId>io.thorntail</groupId>
<artifactId>thorntail-maven-plugin</artifactId>
<version>${version.thorntail}</version>
<executions>
<execution>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
<configuration>
<properties> <lra.http.host>${lra.http.host}</lra.http.host> <lra.http.port>${lra.http.port}</lra.http.port>
</properties>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
...
<dependency>
<groupId>io.thorntail</groupId>
<artifactId>microprofile</artifactId>
</dependency>
...
<!-- LRA JAXRS filters -->
<dependency>
<groupId>org.jboss.narayana.rts</groupId>
<artifactId>lra-filters</artifactId>
<version>5.9.0.Final</version>
</dependency>
...
</dependencies>
</project>

The main changes are as follows:

  • The Thorntail version needed to use the MicroProfile specification—2.1.0
  •  The host and port needed to connect with the LRA coordinator (in our case, localhost and 8580)
  • The new dependencies related to MicroProfile and lra-filters

Then, we need to update the domain model, FootballPlayer.java, introducing two new fields—the status of the football player (free, reserved, or purchased) and the lraId that represents the unique identifier of the long-running action that's needed to update the status of the record associated with the right action.

Also, in this case, we will propose the code of the changes made, as follows:

public class FootballPlayer {   
    ...

@Column(name = "status")
private String status;

@Basic(optional = true)
@Size(min = 1, max = 100)
@Column(name = "lraId")
private String lraId;

...

public FootballPlayer(String name, String surname, int age, String team, String position,
BigInteger price, String status, String lraId) {
this.name = name;
this.surname = surname;
this.age = age;
this.team = team;
this.position = position;
this.price = price;
this.status = status;
this.lraId = lraId;
}

public String getStatus() {
return status;
}

public void setStatus(String status) {
this.status = status;
}

public String getLraId() {
return lraId;
}

public void setLraId(String lraId) {
this.lraId = lraId;
}

...
}

Finally, we will change the REST endpoint (only the edit/PUT method) to handle the saga implementation with the LRA model. The code is as follows:

@ApplicationScoped
@Path("/footballplayer")
public class FootballPlayerFacadeREST extends AbstractFacade<FootballPlayer> {
...

@PUT
@Path("{id}")
@Consumes({MediaType.APPLICATION_JSON})
@Transactional(Transactional.TxType.REQUIRES_NEW)
@LRA(LRA.Type.SUPPORTS)
public void edit(@PathParam("id") Integer id, FootballPlayer entity) {
super.edit(entity);
}

...

@GET
@Path("lraId/{id}")
@Produces({MediaType.APPLICATION_JSON})
public FootballPlayer findByLraId(@PathParam("id") String lraId) {
TypedQuery<FootballPlayer> query = getEntityManager().createQuery(
"SELECT f FROM FootballPlayer f WHERE f.lraId = :lraId",
FootballPlayer.class);
return query.setParameter("lraId", lraId).getSingleResult();
}

...
}

I have introduced the @LRA annotation with the SUPPORTS value; this means that, if called outside of an LRA context, the bean method's execution must then continue outside of an LRA context. Otherwise, it must continue inside of that LRA context. The LRA context will be created by the coarse-grained API gateway that we will build later on.

I have also implemented the findByLraId method, which is needed to retrieve the record associated with the LRA context to perform the operation.

Now, we are ready to run the microservice with the following command:

$ java -jar target/football-player-microservice-lra-thorntail.jar -Dlra.http.port=8580   

Remember to set the lra.http.port parameter to connect your service with the LRA coordinator.

You can find the full code implementation in the GitHub repository, at https://github.com/Hands-on-MSA-JakartaEE/ch5.git.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset