Search in sources :

Example 1 with LRAStatus

use of org.eclipse.microprofile.lra.annotation.LRAStatus in project narayana by jbosstm.

the class Coordinator method getLRAStatus.

@GET
@Path("{LraId}/status")
@Produces(MediaType.TEXT_PLAIN)
@Operation(summary = "Obtain the status of an LRA as a string")
@APIResponses({ @APIResponse(responseCode = "200", description = "The LRA exists. The status is reported in the content body.", content = @Content(schema = @Schema(implementation = String.class)), headers = { @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), @APIResponse(responseCode = "404", description = "The coordinator has no knowledge of this LRA", content = @Content(schema = @Schema(implementation = String.class))), @APIResponse(responseCode = "417", description = "The requested version provided in HTTP Header is not supported by this end point", content = @Content(schema = @Schema(implementation = String.class))) })
public Response getLRAStatus(@Parameter(name = "LraId", description = "The unique identifier of the LRA." + "Expecting to be a valid URL where the participant can be contacted at. If not in URL format it will be considered " + "to be an id which will be declared to exist at URL where coordinator is deployed at.", required = true) @PathParam("LraId") String lraId, @Parameter(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @HeaderParam(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @DefaultValue(CURRENT_API_VERSION_STRING) String version) throws NotFoundException {
    // throws NotFoundException -> response 404
    LongRunningAction transaction = lraService.getTransaction(toURI(lraId));
    LRAStatus status = transaction.getLRAStatus();
    if (status == null) {
        status = LRAStatus.Active;
    }
    return Response.ok().entity(status.name()).header(NARAYANA_LRA_API_VERSION_HEADER_NAME, version).build();
}
Also used : LRAStatus(org.eclipse.microprofile.lra.annotation.LRAStatus) LongRunningAction(io.narayana.lra.coordinator.domain.model.LongRunningAction) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) APIResponses(org.eclipse.microprofile.openapi.annotations.responses.APIResponses) Operation(org.eclipse.microprofile.openapi.annotations.Operation)

Example 2 with LRAStatus

use of org.eclipse.microprofile.lra.annotation.LRAStatus in project narayana by jbosstm.

the class Coordinator method getAllLRAs.

@GET
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
@Operation(summary = "Returns all LRAs", description = "Gets both active and recovering LRAs")
@APIResponses({ @APIResponse(responseCode = "200", description = "The LRAData json array which is known to coordinator", content = @Content(schema = @Schema(type = SchemaType.ARRAY, implementation = LRAData.class)), headers = { @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), @APIResponse(responseCode = "400", description = "Provided Status is not recognized as a valid LRA status value", content = @Content(schema = @Schema(implementation = String.class)), headers = { @Header(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) }), @APIResponse(responseCode = "417", description = "The requested version provided in HTTP Header is not supported by this end point", content = @Content(schema = @Schema(implementation = String.class))) })
public Response getAllLRAs(@Parameter(name = STATUS_PARAM_NAME, description = "Filter the returned LRAs to only those in the give state (see CompensatorStatus)") @QueryParam(STATUS_PARAM_NAME) @DefaultValue("") String state, @Parameter(ref = LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @HeaderParam(LRAConstants.NARAYANA_LRA_API_VERSION_HEADER_NAME) @DefaultValue(CURRENT_API_VERSION_STRING) String version) {
    LRAStatus requestedLRAStatus = null;
    if (!state.isEmpty()) {
        try {
            requestedLRAStatus = LRAStatus.valueOf(state);
        } catch (IllegalArgumentException e) {
            String errorMsg = "Status " + state + " is not a valid LRAStatus value";
            LRALogger.logger.debugf(errorMsg);
            throw new WebApplicationException(errorMsg, e, Response.status(BAD_REQUEST).header(NARAYANA_LRA_API_VERSION_HEADER_NAME, version).entity(errorMsg).build());
        }
    }
    List<LRAData> lras = lraService.getAll(requestedLRAStatus);
    return Response.ok().entity(lras).header(NARAYANA_LRA_API_VERSION_HEADER_NAME, version).build();
}
Also used : LRAStatus(org.eclipse.microprofile.lra.annotation.LRAStatus) WebApplicationException(javax.ws.rs.WebApplicationException) LRAData(io.narayana.lra.LRAData) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) APIResponses(org.eclipse.microprofile.openapi.annotations.responses.APIResponses) Operation(org.eclipse.microprofile.openapi.annotations.Operation)

Example 3 with LRAStatus

use of org.eclipse.microprofile.lra.annotation.LRAStatus in project narayana by jbosstm.

the class LRACoordinatorRecoveryIT method lraCoordinatorShortTimeoutLRA.

@Test
public void lraCoordinatorShortTimeoutLRA(@ArquillianResource @OperateOnDeployment(LRA_PARTICIPANT_DEPLOYMENT_QUALIFIER) URL baseURL) throws URISyntaxException {
    String lraId;
    URI lraListenerURI = UriBuilder.fromUri(baseURL.toURI()).path(LRAListener.LRA_LISTENER_PATH).build();
    // Starts an LRA with a short time limit by invoking a resource annotated with @LRA. The time limit is
    // defined as LRAListener.LRA_SHORT_TIMELIMIT
    Response response = client.target(lraListenerURI).path(LRAListener.LRA_LISTENER_ACTION).request().put(null);
    Assert.assertEquals("LRA participant action", 200, response.getStatus());
    // Restarts lra-coordinator to simulate a crash
    restartContainer(LRA_COORDINATOR_CONTAINER_QUALIFIER);
    // Waits for a period of time longer than the timeout of the LRA Transaction
    doWait((LRAListener.LRA_SHORT_TIMELIMIT + 1L) * 1000);
    // The LRA transaction could have been started via lraClient but it is useful to test the filters as well
    lraId = getFirstLRAFromFS();
    assertNotNull("A new LRA should have been added to the object store before the JVM was halted.", lraId);
    lraId = String.format("%s/%s", lraClient.getCoordinatorUrl(), lraId);
    // Waits for a period of time longer than the timeout of the LRA Transaction
    doWait((LRAListener.LRA_SHORT_TIMELIMIT + 1L) * 1000);
    // Checks recovery
    LRAStatus status = getStatus(new URI(lraId));
    LRALogger.logger.infof("%s: Status after restart is %s%n", status == null ? "GONE" : status.name());
    if (status == null || status == LRAStatus.Cancelling) {
        int sc = recover();
        if (sc != 0) {
            recover();
        }
    }
    // LRA with short timeout should have timed out and cancelled
    status = getStatus(new URI(lraId));
    Assert.assertTrue(String.format("LRA %s should have cancelled", lraId), status == null || status == LRAStatus.Cancelled);
    // Verifies that the resource was notified that the LRA finished
    String listenerStatus = getStatusFromListener(lraListenerURI);
    assertEquals(String.format("The service lra-listener should have been told that the final state of the LRA %s was cancelled", lraId), LRAStatus.Cancelled.name(), listenerStatus);
}
Also used : Response(javax.ws.rs.core.Response) LRAStatus(org.eclipse.microprofile.lra.annotation.LRAStatus) URI(java.net.URI) Test(org.junit.Test)

Example 4 with LRAStatus

use of org.eclipse.microprofile.lra.annotation.LRAStatus in project narayana by jbosstm.

the class LRACoordinatorRecoveryIT method lraCoordinatorRecoveryTwoLRAs.

@Test
public void lraCoordinatorRecoveryTwoLRAs(@ArquillianResource @OperateOnDeployment(LRA_PARTICIPANT_DEPLOYMENT_QUALIFIER) URL deploymentUrl) throws URISyntaxException {
    URI lraListenerURI = UriBuilder.fromUri(deploymentUrl.toURI()).path(LRAListener.LRA_LISTENER_PATH).build();
    // Starts an LRA with a long timeout to validate that long LRAs do not finish early during recovery
    URI longLRA = lraClient.startLRA(null, "Long Timeout Recovery Test", LONG_TIMEOUT, ChronoUnit.MILLIS);
    // Starts an LRA with a short timeout to validate that short LRAs (which timed out when the coordinator was unavailable) are cancelled
    URI shortLRA = lraClient.startLRA(null, "Short Timeout Recovery Test", SHORT_TIMEOUT, ChronoUnit.MILLIS);
    // Restarts lra-coordinator to simulate a crash
    restartContainer(LRA_COORDINATOR_CONTAINER_QUALIFIER);
    // Waits for a period of time longer than the timeout of the short LRA transaction
    doWait((LRAListener.LRA_SHORT_TIMELIMIT + 1L) * 1000);
    int sc = recover();
    if (sc != 0) {
        recover();
    }
    LRAStatus longStatus = getStatus(longLRA);
    LRAStatus shortStatus = getStatus(shortLRA);
    Assert.assertEquals("LRA with long timeout should still be active", LRAStatus.Active.name(), longStatus.name());
    Assert.assertTrue("LRA with short timeout should not be active", shortStatus == null || LRAStatus.Cancelled.equals(shortStatus) || LRAStatus.Cancelling.equals(shortStatus));
    // state of this new transaction.
    try (Response response = client.target(lraListenerURI).path(LRA_LISTENER_UNTIMED_ACTION).request().header(LRA_HTTP_CONTEXT_HEADER, longLRA).put(Entity.text(""))) {
        Assert.assertEquals("LRA participant action", 200, response.getStatus());
    }
    lraClient.closeLRA(longLRA);
    lraClient.closeLRA(shortLRA);
    // Checks that lra-participant was notified when the long LRA transaction was closed
    String listenerStatus = getStatusFromListener(lraListenerURI);
    assertEquals("LRA listener should have been told that the final state of the LRA was closed", LRAStatus.Closed.name(), listenerStatus);
}
Also used : Response(javax.ws.rs.core.Response) LRAStatus(org.eclipse.microprofile.lra.annotation.LRAStatus) URI(java.net.URI) Test(org.junit.Test)

Example 5 with LRAStatus

use of org.eclipse.microprofile.lra.annotation.LRAStatus in project narayana by jbosstm.

the class LRARecoveryModule method doRecoverTransaction.

private void doRecoverTransaction(Uid recoverUid) {
    // Retrieve the transaction status from its original process.
    int theStatus = _transactionStatusConnectionMgr.getTransactionStatus(_transactionType, recoverUid);
    try {
        RecoveringLRA lra = new RecoveringLRA(service, recoverUid, theStatus);
        boolean inFlight = (lra.getLRAStatus() == LRAStatus.Active);
        LRAStatus lraStatus = lra.getLRAStatus();
        if (LRAStatus.FailedToCancel.equals(lraStatus) || LRAStatus.FailedToClose.equals(lraStatus)) {
            moveEntryToFailedLRAPath(recoverUid);
            return;
        }
        if (!service.hasTransaction(lra.getId())) {
            // make sure LRAService knows about it
            service.addTransaction(lra);
        }
        if (LRALogger.logger.isDebugEnabled()) {
            LRALogger.logger.debug("LRARecoverModule: transaction type is " + _transactionType + " uid is " + recoverUid.toString() + "\n Status is " + lraStatus + " in flight is " + inFlight);
        }
        if (!inFlight && lra.hasPendingActions()) {
            lra.replayPhase2();
            if (!lra.isRecovering()) {
                service.finished(lra, false);
            }
        }
    } catch (Exception e) {
        if (LRALogger.logger.isInfoEnabled()) {
            LRALogger.logger.infof("LRARecoverModule: Error '%s' while recovering LRA record %s", e.getMessage(), recoverUid.fileStringForm());
        }
    }
}
Also used : LRAStatus(org.eclipse.microprofile.lra.annotation.LRAStatus) IOException(java.io.IOException) ObjectStoreException(com.arjuna.ats.arjuna.exceptions.ObjectStoreException)

Aggregations

LRAStatus (org.eclipse.microprofile.lra.annotation.LRAStatus)16 URI (java.net.URI)11 Test (org.junit.Test)6 Path (javax.ws.rs.Path)5 GET (javax.ws.rs.GET)4 WebApplicationException (javax.ws.rs.WebApplicationException)4 Response (javax.ws.rs.core.Response)4 LongRunningAction (io.narayana.lra.coordinator.domain.model.LongRunningAction)3 URISyntaxException (java.net.URISyntaxException)3 ObjectStoreException (com.arjuna.ats.arjuna.exceptions.ObjectStoreException)2 LRAData (io.narayana.lra.LRAData)2 LRAService (io.narayana.lra.coordinator.domain.service.LRAService)2 LRALogger (io.narayana.lra.logging.LRALogger)2 IOException (java.io.IOException)2 DELETE (javax.ws.rs.DELETE)2 NotFoundException (javax.ws.rs.NotFoundException)2 Produces (javax.ws.rs.Produces)2 Client (javax.ws.rs.client.Client)2 Operation (org.eclipse.microprofile.openapi.annotations.Operation)2 APIResponses (org.eclipse.microprofile.openapi.annotations.responses.APIResponses)2