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();
}
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();
}
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()));
}
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));
}
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();
}
}
Aggregations