Skip to content

Commit

Permalink
[EAPQE-2697] Add test for MicroProfile LRA with Fault Tolerance
Browse files Browse the repository at this point in the history
  • Loading branch information
mnovak1 committed Dec 3, 2024
1 parent fe9265a commit 652f562
Show file tree
Hide file tree
Showing 18 changed files with 579 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.eap.qe.microprofile.common.setuptasks.MicroProfileFaultToleranceServerConfiguration;
import org.jboss.eap.qe.microprofile.fault.tolerance.deployments.load.LoadService;
import org.jboss.eap.qe.microprofile.fault.tolerance.util.MicroProfileFaultToleranceServerConfiguration;
import org.jboss.eap.qe.microprofile.tooling.cpu.load.HighCPUUtils;
import org.jboss.eap.qe.microprofile.tooling.cpu.load.utils.ProcessUtils;
import org.jboss.eap.qe.microprofile.tooling.cpu.load.utils.ProcessUtilsProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.eap.qe.microprofile.common.setuptasks.MicroProfileFaultToleranceServerConfiguration;
import org.jboss.eap.qe.microprofile.fault.tolerance.deployments.database.DatabaseService;
import org.jboss.eap.qe.microprofile.fault.tolerance.deployments.database.DatabaseServlet;
import org.jboss.eap.qe.microprofile.fault.tolerance.util.MicroProfileFaultToleranceServerConfiguration;
import org.jboss.eap.qe.microprofile.tooling.server.configuration.deployment.ConfigurationUtil;
import org.jboss.eap.qe.ts.common.docker.Docker;
import org.jboss.eap.qe.ts.common.docker.junit.DockerRequiredTests;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.eap.qe.microprofile.common.setuptasks.MicroProfileFaultToleranceServerConfiguration;
import org.jboss.eap.qe.microprofile.fault.tolerance.deployments.v10.HelloFallback;
import org.jboss.eap.qe.microprofile.fault.tolerance.deployments.v10.HelloService;
import org.jboss.eap.qe.microprofile.fault.tolerance.deployments.v10.HelloServlet;
import org.jboss.eap.qe.microprofile.fault.tolerance.deployments.v10.MyContext;
import org.jboss.eap.qe.microprofile.fault.tolerance.util.MicroProfileFaultToleranceServerConfiguration;
import org.jboss.eap.qe.microprofile.tooling.server.configuration.ConfigurationException;
import org.jboss.eap.qe.microprofile.tooling.server.configuration.arquillian.ArquillianContainerProperties;
import org.jboss.eap.qe.microprofile.tooling.server.configuration.arquillian.ArquillianDescriptorWrapper;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
import org.jboss.arquillian.container.test.api.OperateOnDeployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.as.arquillian.api.ServerSetup;
import org.jboss.eap.qe.microprofile.common.setuptasks.FaultToleranceServerSetup;
import org.jboss.eap.qe.microprofile.fault.tolerance.deployments.v10.HelloFallback;
import org.jboss.eap.qe.microprofile.fault.tolerance.deployments.v10.HelloService;
import org.jboss.eap.qe.microprofile.fault.tolerance.deployments.v10.MyContext;
import org.jboss.eap.qe.microprofile.fault.tolerance.util.FaultToleranceServerSetup;
import org.jboss.eap.qe.microprofile.tooling.server.configuration.deployment.ConfigurationUtil;
import org.jboss.eap.qe.microprofile.tooling.server.log.LogChecker;
import org.jboss.shrinkwrap.api.Archive;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.junit.InSequence;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.eap.qe.microprofile.common.setuptasks.MicroProfileFaultToleranceServerConfiguration;
import org.jboss.eap.qe.microprofile.common.setuptasks.MicroProfileTelemetryServerSetup;
import org.jboss.eap.qe.microprofile.fault.tolerance.deployments.v10.HelloService;
import org.jboss.eap.qe.microprofile.fault.tolerance.util.MicroProfileFaultToleranceServerConfiguration;
import org.jboss.eap.qe.microprofile.fault.tolerance.util.MicroProfileTelemetryServerSetup;
import org.jboss.eap.qe.microprofile.tooling.server.configuration.creaper.ManagementClientProvider;
import org.jboss.eap.qe.microprofile.tooling.server.configuration.deployment.ConfigurationUtil;
import org.jboss.eap.qe.microprofile.tooling.server.log.LogChecker;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.eap.qe.microprofile.common.setuptasks.MicroProfileFaultToleranceServerConfiguration;
import org.jboss.eap.qe.microprofile.fault.tolerance.deployments.v10.HelloService;
import org.jboss.eap.qe.microprofile.fault.tolerance.util.MicroProfileFaultToleranceServerConfiguration;
import org.jboss.eap.qe.microprofile.tooling.server.configuration.creaper.ManagementClientProvider;
import org.jboss.eap.qe.microprofile.tooling.server.configuration.deployment.ConfigurationUtil;
import org.jboss.shrinkwrap.api.Archive;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.eap.qe.microprofile.common.setuptasks.MicroProfileFaultToleranceServerConfiguration;
import org.jboss.eap.qe.microprofile.fault.tolerance.deployments.v20.AsyncHelloService;
import org.jboss.eap.qe.microprofile.fault.tolerance.util.MicroProfileFaultToleranceServerConfiguration;
import org.jboss.eap.qe.microprofile.tooling.server.configuration.deployment.ConfigurationUtil;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.eap.qe.microprofile.common.setuptasks.MicroProfileFaultToleranceServerConfiguration;
import org.jboss.eap.qe.microprofile.fault.tolerance.deployments.v20.AsyncHelloService;
import org.jboss.eap.qe.microprofile.fault.tolerance.util.MicroProfileFaultToleranceServerConfiguration;
import org.jboss.eap.qe.microprofile.tooling.server.configuration.deployment.ConfigurationUtil;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.eap.qe.microprofile.common.setuptasks.MicroProfileFaultToleranceServerConfiguration;
import org.jboss.eap.qe.microprofile.fault.tolerance.deployments.v20.AsyncHelloService;
import org.jboss.eap.qe.microprofile.fault.tolerance.deployments.v20.PriorityServlet;
import org.jboss.eap.qe.microprofile.fault.tolerance.deployments.v20.priority.AfterInterceptor;
import org.jboss.eap.qe.microprofile.fault.tolerance.deployments.v20.priority.BeforeInterceptor;
import org.jboss.eap.qe.microprofile.fault.tolerance.deployments.v20.priority.InterceptorsContext;
import org.jboss.eap.qe.microprofile.fault.tolerance.util.MicroProfileFaultToleranceServerConfiguration;
import org.jboss.eap.qe.microprofile.tooling.server.configuration.deployment.ConfigurationUtil;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
Expand Down
5 changes: 5 additions & 0 deletions microprofile-lra/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@
<groupId>org.wildfly.core</groupId>
<artifactId>wildfly-controller</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.microprofile.fault-tolerance</groupId>
<artifactId>microprofile-fault-tolerance-api</artifactId>
</dependency>
</dependencies>

<profiles>
Expand Down Expand Up @@ -141,6 +145,7 @@
<layer>cloud-server</layer>
<layer>microprofile-lra-coordinator</layer>
<layer>microprofile-lra-participant</layer>
<layer>microprofile-fault-tolerance</layer>
</layers>
</configuration>
</execution>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@
import org.eclipse.microprofile.lra.annotation.Complete;
import org.eclipse.microprofile.lra.annotation.ws.rs.LRA;
import org.jboss.eap.qe.microprofile.lra.model.LRAResult;
import org.jboss.logging.Logger;

public class LRAParticipant {

private static final Logger LOGGER = Logger.getLogger(LRAParticipant.class);

public static final String RESULT_PATH = "/result";
public static final String RESET_PATH = "/reset";

Expand All @@ -26,6 +29,7 @@ public class LRAParticipant {
@Path("/compensate")
public Response compensate(@HeaderParam(LRA.LRA_HTTP_CONTEXT_HEADER) URI lraId,
@HeaderParam(LRA.LRA_HTTP_RECOVERY_HEADER) URI recoveryId) {
LOGGER.infof("Compensating action for participant (%s) in LRA %s.", recoveryId, lraId);
lraResult.setCompleted(false);
lraResult.setFinishLraId(lraId);
lraResult.setFinishRecoveryId(recoveryId);
Expand All @@ -37,6 +41,7 @@ public Response compensate(@HeaderParam(LRA.LRA_HTTP_CONTEXT_HEADER) URI lraId,
@Path("/complete")
public Response complete(@HeaderParam(LRA.LRA_HTTP_CONTEXT_HEADER) URI lraId,
@HeaderParam(LRA.LRA_HTTP_RECOVERY_HEADER) URI recoveryId) {
LOGGER.infof("Complete action for participant (%s) in LRA %s.", recoveryId, lraId);
lraResult.setCompleted(true);
lraResult.setFinishLraId(lraId);
lraResult.setFinishRecoveryId(recoveryId);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
package org.jboss.eap.qe.microprofile.lra;

import static org.jboss.eap.qe.microprofile.lra.LRAParticipantWithFaultTolerance1.PATH;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.HeaderParam;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.UriInfo;

import java.net.URI;
import java.time.Duration;
import java.util.concurrent.atomic.AtomicInteger;

import org.eclipse.microprofile.faulttolerance.CircuitBreaker;
import org.eclipse.microprofile.faulttolerance.Fallback;
import org.eclipse.microprofile.faulttolerance.Retry;
import org.eclipse.microprofile.faulttolerance.Timeout;
import org.eclipse.microprofile.lra.annotation.ws.rs.LRA;
import org.jboss.logging.Logger;

@Path(PATH)
@ApplicationScoped
@Produces(MediaType.APPLICATION_JSON)
public class LRAParticipantWithFaultTolerance1 extends LRAParticipant {

private static final Logger LOGGER = Logger.getLogger(LRAParticipantWithFaultTolerance1.class);

public static final String PATH = "lra-participant-with-fault-tolerance-1";
public static final String RETRY_PATH = "work-with-retry";
public static final String TIMEOUT_PATH = "work-with-timeout";
public static final String RETRY_COUNT_PATH = "retry-count";
public static final String FAIL_LRA = "fail-lra";
public static final String RESET_COUNTER_PATH = "reset-counter";
public static final String CIRCUIT_BREAKER_PATH = "work-with-circuit-breaker";
public static final String FALLBACK_PATH = "work-with-fallback";

private final AtomicInteger retryCount = new AtomicInteger(0);

@Context
UriInfo uriInfo;

@LRA(value = LRA.Type.REQUIRED)
@GET
@Path(RETRY_PATH)
@Retry(maxRetries = 3, delay = 100)
public Response workWithRetry(@HeaderParam(LRA.LRA_HTTP_CONTEXT_HEADER) URI lraId,
@HeaderParam(LRA.LRA_HTTP_RECOVERY_HEADER) URI recoveryId,
@QueryParam(LRAParticipantWithFaultTolerance1.FAIL_LRA) boolean failLRA) throws Exception {

LOGGER.infof("Executing action of LRAParticipantWithFaultTolerance1 enlisted in LRA %s " +
"that was assigned %s participant Id. Retried: %s", lraId, recoveryId, retryCount.incrementAndGet());

// check lraId and recoveryId is consistent across retries otherwise return response to fail the test
if (retryCount.get() > 1 && !lraId.equals(lraResult.getLraId())) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity("Wrong lraId across retries. Expected " + lraResult.getLraId() + " but got " + lraId).build();
}

if (retryCount.get() > 1 && !recoveryId.equals(lraResult.getRecoveryId())) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity("Wrong recoveryId across retries. Expected " + lraResult.getRecoveryId() + " but got " + recoveryId)
.build();
}

lraResult.setLraId(lraId);
lraResult.setRecoveryId(recoveryId);

// call Participant 2 to propagate the LRA
try (Client client = ClientBuilder.newClient()) {
client.target(uriInfo.getBaseUri() + "/" + LRAParticipantWithFaultTolerance2.PATH)
.request().get();
}

if (failLRA) {
throw new Exception("Throwing exception to fail participant until maxRetry is reached.");
}

return Response.ok("Method with @Retry ended successfully.").build();
}

@LRA(value = LRA.Type.REQUIRED)
@GET
@Path(TIMEOUT_PATH)
@Timeout(1000)
public Response workWithRetry(@HeaderParam(LRA.LRA_HTTP_CONTEXT_HEADER) URI lraId,
@HeaderParam(LRA.LRA_HTTP_RECOVERY_HEADER) URI recoveryId) throws Exception {

LOGGER.infof("Executing action of LRAParticipantWithFaultTolerance1 enlisted in LRA %s " +
"that was assigned %s participant Id. Retried: %s", lraId, recoveryId, retryCount.incrementAndGet());

lraResult.setLraId(lraId);
lraResult.setRecoveryId(recoveryId);

// call Participant 2 to propagate the LRA
try (Client client = ClientBuilder.newClient()) {
client.target(uriInfo.getBaseUri() + "/" + LRAParticipantWithFaultTolerance2.PATH)
.request().get();
}

// Cause timeout of this method so exception is thrown and LRA is compensated
Thread.sleep(Duration.ofSeconds(10).toMillis());

return Response.ok("Method with @Timeout ended successfully.").build();
}

/**
* If 2 or more calls from last 10 calls fail then circuit is open.
* If circuit is open and 1 call is successful (after 1000 ms) delay then circuit is closed again.
*/
@LRA(value = LRA.Type.REQUIRED)
@GET
@Path(CIRCUIT_BREAKER_PATH)
@CircuitBreaker(requestVolumeThreshold = 10, failureRatio = 0.2, delay = 1000, successThreshold = 10)
public Response workWithCircuitBreaker(@HeaderParam(LRA.LRA_HTTP_CONTEXT_HEADER) URI lraId,
@HeaderParam(LRA.LRA_HTTP_RECOVERY_HEADER) URI recoveryId,
@QueryParam(LRAParticipantWithFaultTolerance1.FAIL_LRA) boolean failLRA) throws Exception {
LOGGER.infof("Executing action of LRAParticipantWithFaultTolerance1 enlisted in LRA %s " +
"that was assigned %s participant Id. Retried: %s", lraId, recoveryId, retryCount.incrementAndGet());

lraResult.setLraId(lraId);
lraResult.setRecoveryId(recoveryId);

// call Participant 2 to propagate the LRA
try (Client client = ClientBuilder.newClient()) {
client.target(uriInfo.getBaseUri() + "/" + LRAParticipantWithFaultTolerance2.PATH)
.request().get();
}

if (failLRA) {
throw new Exception("Throwing exception to fail participant until circuit is open.");
}

return Response.ok("Method with @CircuitBreaker ended successfully.").build();
}

@LRA(value = LRA.Type.REQUIRED)
@GET
@Path(FALLBACK_PATH)
@Fallback(fallbackMethod = "fallback")
public Response workWithFallback(@HeaderParam(LRA.LRA_HTTP_CONTEXT_HEADER) URI lraId,
@HeaderParam(LRA.LRA_HTTP_RECOVERY_HEADER) URI recoveryId,
@QueryParam(LRAParticipantWithFaultTolerance1.FAIL_LRA) boolean failLRA) throws Exception {

LOGGER.infof("Executing action of LRAParticipantWithFaultTolerance1 enlisted in LRA %s " +
"that was assigned %s participant Id. Retried: %s", lraId, recoveryId, retryCount.incrementAndGet());

lraResult.setLraId(lraId);
lraResult.setRecoveryId(recoveryId);

// call Participant 2 to propagate the LRA
try (Client client = ClientBuilder.newClient()) {
client.target(uriInfo.getBaseUri() + "/" + LRAParticipantWithFaultTolerance2.PATH)
.request().get();
}
if (failLRA) {
throw new Exception("Throwing exception to fail participant so fallback method is called.");
}
return Response.ok("Method ended successfully without calling method in @Fallback.").build();
}

public Response fallback(@HeaderParam(LRA.LRA_HTTP_CONTEXT_HEADER) URI lraId,
@HeaderParam(LRA.LRA_HTTP_RECOVERY_HEADER) URI recoveryId,
@QueryParam(LRAParticipantWithFaultTolerance1.FAIL_LRA) boolean failLRA) {
// check lraId and recoveryId is the same
if (!lraId.equals(lraResult.getLraId())) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity("Wrong lraId across retries. Expected " + lraResult.getLraId() + " but got " + lraId).build();
}

if (!recoveryId.equals(lraResult.getRecoveryId())) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity("Wrong recoveryId across retries. Expected " + lraResult.getRecoveryId() + " but got " + recoveryId)
.build();
}
lraResult.setLraId(lraId);
lraResult.setRecoveryId(recoveryId);
return Response.ok("Method defined in @Fallback ended successfully.").build();
}

@GET
@Path(RETRY_COUNT_PATH)
public int getRetryCount() {
return retryCount.get();
}

@GET
@Path(RESET_COUNTER_PATH)
public void resetCounter() {
retryCount.set(0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.jboss.eap.qe.microprofile.lra;

import static org.jboss.eap.qe.microprofile.lra.LRAParticipantWithFaultTolerance2.PATH;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.HeaderParam;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;

import java.net.URI;

import org.eclipse.microprofile.lra.annotation.ws.rs.LRA;
import org.jboss.logging.Logger;

@Path(PATH)
@ApplicationScoped
@Produces(MediaType.APPLICATION_JSON)
public class LRAParticipantWithFaultTolerance2 extends LRAParticipant {

private static final Logger LOGGER = Logger.getLogger(LRAParticipantWithFaultTolerance2.class);

public static final String PATH = "lra-participant-with-fault-tolerance-2";

@LRA(value = LRA.Type.MANDATORY, end = false)
@GET
public Response doLRA(@HeaderParam(LRA.LRA_HTTP_CONTEXT_HEADER) URI lraId,
@HeaderParam(LRA.LRA_HTTP_RECOVERY_HEADER) URI recoveryId) {
LOGGER.infof("Executing action of Participant 2 enlisted in LRA %s " +
"that was assigned %s participant Id.", lraId, recoveryId);

lraResult.setLraId(lraId);
lraResult.setRecoveryId(recoveryId);

return Response.ok().build();
}
}
Loading

0 comments on commit 652f562

Please sign in to comment.