The LRA business method

The LRA business method is where we will define the business logic.

We will organize the invocation into other microservices, implementing the following steps:

  1. Create the offer for the desired football player, and set its status to "SEND".
  2. Retrieve the football player data.
  1. Set the status of the football player to "Reserved"; in this phase, the player is in negotiation, and therefore, cannot be sought after by other football managers.
  2. Persist the "Reserved" intermediate status, and mark the record with the LRA ID to be associated with this LRA context.
  3. Simulate the outcome of the negotiation with a check of the value of the offer made; if it is less than 80% of the value of the football player, the offer will be refused, and the LRA coordinator will execute the compensate phase. Otherwise, it will be accepted, and the LRA coordinator will execute the complete phase:
/**
* Business method that performs the send offer business logic.
* The method implement the business logic related to create the football
* player offer domain record and sets the status to a non final status, "SEND".
* It also set the status of the football player to Reserved.
* The LRA coordinator, based on the Response.Status, will decide how to
* complete or compensate the business logic setting the definitive status.
*
* @param footballPlayerOffer The POJO that maps the football player offer data.
*/
@POST
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
@LRA(value = LRA.Type.REQUIRED,
cancelOn = {Response.Status.INTERNAL_SERVER_ERROR}, // cancel on a 500 code
cancelOnFamily = {Response.Status.Family.CLIENT_ERROR} // cancel on any 4xx code)
public void sendOffer(FootballPlayerOffer footballPlayerOffer) {
LOG.log(Level.INFO, "Start method sendOffer");
LOG.log(Level.FINE, "Retrieving football player with id {0}",
footballPlayerOffer.getIdFootballPlayer());

String lraIdUrl = lraClient.getCurrent().toString();
String lraId = lraIdUrl.substring(lraIdUrl.lastIndexOf('/') + 1);

LOG.log(Level.FINE, "Value of LRA_ID {0}", lraId);

// Create the offer
LOG.log(Level.FINE, "Creating offer ...");
footballPlayerOffer.setStatus("SEND");
footballPlayerOffer.setLraId(lraId);
Response response = footballPlayerOfferTarget.request().post(Entity.entity(
footballPlayerOffer, MediaType.APPLICATION_JSON_TYPE));

LOG.log(Level.FINE, "Offer created with response code {0}", response.getStatus());

if (response.getStatus() == Response.Status.NO_CONTENT.getStatusCode()) {
FootballPlayer player = footballPlayerTarget.path(footballPlayerOffer.
getIdFootballPlayer().toString()).
request().get(new GenericTypeFootballPlayerImpl());

LOG.log(Level.FINE, "Got football player {0}", player);

player.setStatus("Reserved");
player.setLraId(lraId);

LOG.log(Level.FINE, "Changing football player status ...");

footballPlayerTarget.path(footballPlayerOffer.
getIdFootballPlayer().toString()).request().put(Entity.
entity(player, MediaType.APPLICATION_JSON_TYPE));

// Check about the price of the offer: if it is less than 80% of the
// value of the football player I will refuse the offer
BigInteger price = footballPlayerOffer.getPrice();

LOG.log(Level.FINE, "Value of offer price {0}", price);
LOG.log(Level.FINE, "Value of football player price {0}", player.getPrice());

if ((price.multiply(new BigInteger("100")).divide(player.getPrice())).intValue() < 80) {
throw new WebApplicationException("The offer is unacceptable!",
Response.Status.INTERNAL_SERVER_ERROR);
}
} else {
throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
}
LOG.log(Level.INFO, "End method sendOffer");
}

We defined the value of LRA.Type.REQUIRED; this means that, if it is called outside of an LRA context, a JAX-RS filter will begin a new LRA for the duration of the method call; and, when the call completes, another JAX-RS filter will complete the LRA. The key point of the method is the use of the @LRA annotation that handles the life cycles of LRAs.

We also defined the cases in which the business method can be considered failed to instruct the LRA coordinator to execute the compensate phase through cancelOn = {Response.Status.INTERNAL_SERVER_ERROR}, which cancels the operation on a 500 code, and cancelOnFamily = {Response.Status.Family.CLIENT_ERROR}, which cancels on any 4xx code.

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

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