Search in sources :

Example 1 with LRAData

use of io.narayana.lra.LRAData in project narayana by jbosstm.

the class Coordinator method getLRAInfo.

@GET
@Path("{LraId}")
@Produces(MediaType.APPLICATION_JSON)
@Operation(summary = "Obtain the information about an LRA as a JSON structure")
@APIResponses({ @APIResponse(responseCode = "200", description = "The LRA exists and the information is packed as JSON in the content body.", content = @Content(schema = @Schema(implementation = LRAData.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 getLRAInfo(@Parameter(name = "LraId", description = "The unique identifier of the LRA", 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) {
    URI lraIdURI = toURI(lraId);
    LRAData lraData = lraService.getLRA(lraIdURI);
    return Response.status(OK).entity(lraData).header(NARAYANA_LRA_API_VERSION_HEADER_NAME, version).build();
}
Also used : URI(java.net.URI) 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 2 with LRAData

use of io.narayana.lra.LRAData 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 LRAData

use of io.narayana.lra.LRAData in project narayana by jbosstm.

the class CoordinatorApiIT method getAllLRAs.

/**
 * GET - /
 * To gets all active LRAs.
 */
@Test
public void getAllLRAs() {
    // be aware of risk of non monotonic java time, ie. https://www.javaadvent.com/2019/12/measuring-time-from-java-to-kernel-and-back.html
    long beforeTime = Instant.now().toEpochMilli();
    String clientId1 = testRule.getMethodName() + "_OK_1";
    String clientId2 = testRule.getMethodName() + "_OK_2";
    URI lraId1 = lraClient.startLRA(clientId1);
    URI lraId2 = lraClient.startLRA(lraId1, clientId2, 0L, null);
    // lraId2 is nested and will be closed in regards to lraId1
    lrasToAfterFinish.add(lraId1);
    List<LRAData> data;
    try (Response response = client.target(coordinatorUrl).request().header(LRA_API_VERSION_HEADER_NAME, version).get()) {
        Assert.assertEquals("Expected that the call succeeds, GET/200.", Status.OK.getStatusCode(), response.getStatus());
        Assert.assertEquals("Provided API header, expected that one is returned", version, response.getHeaderString(LRA_API_VERSION_HEADER_NAME));
        data = response.readEntity(new GenericType<List<LRAData>>() {
        });
    }
    Optional<LRAData> lraTopOptional = data.stream().filter(record -> record.getLraId().equals(lraId1)).findFirst();
    Assert.assertTrue("Expected to find the top-level LRA id " + lraId1 + " from REST get all call", lraTopOptional.isPresent());
    LRAData lraTop = lraTopOptional.get();
    Optional<LRAData> lraNestedOptional = data.stream().filter(record -> record.getLraId().equals(lraId2)).findFirst();
    Assert.assertTrue("Expected to find the nested LRA id " + lraId2 + " from REST get all call", lraNestedOptional.isPresent());
    LRAData lraNested = lraNestedOptional.get();
    Assert.assertEquals("Expected top-level LRA '" + lraTop + "'  being active", LRAStatus.Active, lraTop.getStatus());
    Assert.assertEquals("Expected top-level LRA '" + lraTop + "'  being active, HTTP status 204.", Status.NO_CONTENT.getStatusCode(), lraTop.getHttpStatus());
    Assert.assertFalse("Expected top-level LRA '" + lraTop + "' not being recovering", lraTop.isRecovering());
    Assert.assertTrue("Expected top-level LRA '" + lraTop + "' to be top level", lraTop.isTopLevel());
    MatcherAssert.assertThat("Expected the start time of top-level LRA '" + lraTop + "' is after the test start time", beforeTime, lessThan(lraTop.getStartTime()));
    Assert.assertEquals("Expected nested LRA '" + lraNested + "'  being active", LRAStatus.Active, lraNested.getStatus());
    Assert.assertEquals("Expected nested LRA '" + lraNested + "'  being active, HTTP status 204.", Status.NO_CONTENT.getStatusCode(), lraNested.getHttpStatus());
    Assert.assertFalse("Expected nested LRA '" + lraNested + "' not being recovering", lraNested.isRecovering());
    Assert.assertFalse("Expected nested LRA '" + lraNested + "' to be nested", lraNested.isTopLevel());
    MatcherAssert.assertThat("Expected the start time of nested LRA '" + lraNested + "' is after the test start time", beforeTime, lessThan(lraNested.getStartTime()));
}
Also used : Response(javax.ws.rs.core.Response) Arrays(java.util.Arrays) URLDecoder(java.net.URLDecoder) Logger(org.jboss.logging.Logger) RunWith(org.junit.runner.RunWith) TestBase(io.narayana.lra.arquillian.TestBase) RunAsClient(org.jboss.arquillian.container.test.api.RunAsClient) IsCollectionContaining.hasItem(org.hamcrest.core.IsCollectionContaining.hasItem) LRAData(io.narayana.lra.LRAData) LRAConstants(io.narayana.lra.LRAConstants) Matchers.lessThan(org.hamcrest.Matchers.lessThan) Matchers.emptyCollectionOf(org.hamcrest.Matchers.emptyCollectionOf) URI(java.net.URI) Status(javax.ws.rs.core.Response.Status) Parameterized(org.junit.runners.Parameterized) IsNot.not(org.hamcrest.core.IsNot.not) ArquillianParametrized(io.narayana.lra.arquillian.ArquillianParametrized) Collection(java.util.Collection) Test(org.junit.Test) Instant(java.time.Instant) Entity(javax.ws.rs.client.Entity) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) GenericType(javax.ws.rs.core.GenericType) URLEncoder(java.net.URLEncoder) List(java.util.List) LRAStatus(org.eclipse.microprofile.lra.annotation.LRAStatus) MatcherAssert(org.hamcrest.MatcherAssert) Rule(org.junit.Rule) HttpHeaders(javax.ws.rs.core.HttpHeaders) Response(javax.ws.rs.core.Response) IsCollectionContaining.hasItems(org.hamcrest.core.IsCollectionContaining.hasItems) Optional(java.util.Optional) Matchers.greaterThan(org.hamcrest.Matchers.greaterThan) Assert(org.junit.Assert) UnsupportedEncodingException(java.io.UnsupportedEncodingException) Matchers.containsString(org.hamcrest.Matchers.containsString) Link(javax.ws.rs.core.Link) GenericType(javax.ws.rs.core.GenericType) Matchers.containsString(org.hamcrest.Matchers.containsString) URI(java.net.URI) LRAData(io.narayana.lra.LRAData) Test(org.junit.Test)

Example 4 with LRAData

use of io.narayana.lra.LRAData in project narayana by jbosstm.

the class CoordinatorApiIT method renewTimeLimit.

/**
 * PUT - /renew?TimeLimit=
 * Renewing the time limit of the started LRA.
 */
@Test
public void renewTimeLimit() throws UnsupportedEncodingException {
    URI lraId = lraClient.startLRA(testRule.getMethodName());
    lrasToAfterFinish.add(lraId);
    Optional<LRAData> data = lraClient.getAllLRAs().stream().filter(l -> l.getLraId().equals(lraId)).findFirst();
    Assert.assertTrue("Expected the started LRA will be retrieved by LRA client get", data.isPresent());
    Assert.assertEquals("Expected not defined finish time", 0L, data.get().getFinishTime());
    String encodedLraId = URLEncoder.encode(lraId.toString(), StandardCharsets.UTF_8.name());
    try (Response response = client.target(coordinatorUrl).path(encodedLraId).path("renew").queryParam(TIME_LIMIT_PARAM_NAME, Integer.MAX_VALUE).request().header(LRA_API_VERSION_HEADER_NAME, version).put(null)) {
        Assert.assertEquals("Expected time limit request to succeed, PUT/200 is expected.", Status.OK.getStatusCode(), response.getStatus());
        Assert.assertEquals("Expected API header to be returned with the version provided in request", version, response.getHeaderString(LRA_API_VERSION_HEADER_NAME));
        MatcherAssert.assertThat("Expected the found LRA id is returned", response.readEntity(String.class), containsString(lraId.toString()));
    }
    data = lraClient.getAllLRAs().stream().filter(l -> l.getLraId().equals(lraId)).findFirst();
    Assert.assertTrue("Expected the started LRA will be retrieved by LRA client get", data.isPresent());
    MatcherAssert.assertThat("Expected finish time to not be 0 as time limit was defined", data.get().getFinishTime(), greaterThan(0L));
}
Also used : Arrays(java.util.Arrays) URLDecoder(java.net.URLDecoder) Logger(org.jboss.logging.Logger) RunWith(org.junit.runner.RunWith) TestBase(io.narayana.lra.arquillian.TestBase) RunAsClient(org.jboss.arquillian.container.test.api.RunAsClient) IsCollectionContaining.hasItem(org.hamcrest.core.IsCollectionContaining.hasItem) LRAData(io.narayana.lra.LRAData) LRAConstants(io.narayana.lra.LRAConstants) Matchers.lessThan(org.hamcrest.Matchers.lessThan) Matchers.emptyCollectionOf(org.hamcrest.Matchers.emptyCollectionOf) URI(java.net.URI) Status(javax.ws.rs.core.Response.Status) Parameterized(org.junit.runners.Parameterized) IsNot.not(org.hamcrest.core.IsNot.not) ArquillianParametrized(io.narayana.lra.arquillian.ArquillianParametrized) Collection(java.util.Collection) Test(org.junit.Test) Instant(java.time.Instant) Entity(javax.ws.rs.client.Entity) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) GenericType(javax.ws.rs.core.GenericType) URLEncoder(java.net.URLEncoder) List(java.util.List) LRAStatus(org.eclipse.microprofile.lra.annotation.LRAStatus) MatcherAssert(org.hamcrest.MatcherAssert) Rule(org.junit.Rule) HttpHeaders(javax.ws.rs.core.HttpHeaders) Response(javax.ws.rs.core.Response) IsCollectionContaining.hasItems(org.hamcrest.core.IsCollectionContaining.hasItems) Optional(java.util.Optional) Matchers.greaterThan(org.hamcrest.Matchers.greaterThan) Assert(org.junit.Assert) UnsupportedEncodingException(java.io.UnsupportedEncodingException) Matchers.containsString(org.hamcrest.Matchers.containsString) Link(javax.ws.rs.core.Link) Response(javax.ws.rs.core.Response) Matchers.containsString(org.hamcrest.Matchers.containsString) URI(java.net.URI) LRAData(io.narayana.lra.LRAData) Test(org.junit.Test)

Example 5 with LRAData

use of io.narayana.lra.LRAData in project narayana by jbosstm.

the class RecoveryCoordinator method deleteFailedLRA.

@DELETE
@Path("{LraId}")
@Operation(summary = "Remove the log for a failed LRA")
@APIResponses({ @APIResponse(responseCode = "204", description = "If the LRA log was successfully removed"), @APIResponse(responseCode = "412", description = "If the LRA is not in an end state (in which case the response " + "entity will indicate the current state at the time of the request)"), @APIResponse(responseCode = "412", description = "If the input LRA does not correspond to a valid URI (in which case the " + "response entity will contain the error message)"), @APIResponse(responseCode = "500", description = "If the attempt to remove the LRA log failed. This return code does not " + "discriminate between a failure at the log storage level or if the log did not exist)") })
public Response deleteFailedLRA(@Parameter(name = "LraId", description = "The unique identifier of the LRA", required = true) @PathParam("LraId") String lraId) throws NotFoundException {
    URI lra;
    try {
        lra = new URI(lraId);
        // verify that the LRA is not still being processed
        // will throw NotFoundException if it's unknown (to be caught and processed in the catch block)
        LRAData lraData = lraService.getLRA(lra);
        LRAStatus status = lraData.getStatus();
        // 412 the LRA is not in an end state (return 412 and the actual status of the LRA)
        if (status == LRAStatus.FailedToCancel || status == LRAStatus.FailedToClose) {
            return removeLog(lraId);
        }
        return Response.status(PRECONDITION_FAILED).entity(lraData.getStatus().name()).build();
    } catch (NotFoundException e) {
        // the LRA has finished and, if it corresponds to a failure record, it is safe to delete it
        return removeLog(lraId);
    } catch (URISyntaxException e) {
        // 412 the user provided URI was invalid
        if (LRALogger.logger.isDebugEnabled()) {
            LRALogger.logger.debugf("%s#deleteLRA: %s: %s", getClass().getCanonicalName(), lraId, e.getMessage());
        }
        return Response.status(PRECONDITION_FAILED).entity(String.format("%s: %s", lraId, e.getMessage())).build();
    }
}
Also used : LRAStatus(org.eclipse.microprofile.lra.annotation.LRAStatus) NotFoundException(javax.ws.rs.NotFoundException) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI) LRAData(io.narayana.lra.LRAData) Path(javax.ws.rs.Path) DELETE(javax.ws.rs.DELETE) APIResponses(org.eclipse.microprofile.openapi.annotations.responses.APIResponses) Operation(org.eclipse.microprofile.openapi.annotations.Operation)

Aggregations

LRAData (io.narayana.lra.LRAData)13 URI (java.net.URI)12 Test (org.junit.Test)9 List (java.util.List)6 Response (javax.ws.rs.core.Response)6 LRAStatus (org.eclipse.microprofile.lra.annotation.LRAStatus)6 Matchers.containsString (org.hamcrest.Matchers.containsString)6 TestBase (io.narayana.lra.arquillian.TestBase)5 Logger (org.jboss.logging.Logger)5 Assert (org.junit.Assert)5 Rule (org.junit.Rule)5 LRAConstants (io.narayana.lra.LRAConstants)4 ArquillianParametrized (io.narayana.lra.arquillian.ArquillianParametrized)4 UnsupportedEncodingException (java.io.UnsupportedEncodingException)4 URLDecoder (java.net.URLDecoder)4 URLEncoder (java.net.URLEncoder)4 StandardCharsets (java.nio.charset.StandardCharsets)4 Instant (java.time.Instant)4 Arrays (java.util.Arrays)4 Collection (java.util.Collection)4