Search in sources :

Example 1 with LRA

use of org.eclipse.microprofile.lra.annotation.ws.rs.LRA in project helidon by oracle.

the class ParticipantImpl method getLRAAnnotation.

static Optional<Annotation> getLRAAnnotation(Method m) {
    List<Annotation> found = Arrays.stream(m.getDeclaredAnnotations()).filter(a -> LRA_ANNOTATIONS.contains(a.annotationType())).collect(Collectors.toList());
    if (found.size() == 0) {
        // LRA can be inherited from class or its predecessors
        var clazz = m.getDeclaringClass();
        do {
            LRA clazzLraAnnotation = clazz.getAnnotation(LRA.class);
            if (clazzLraAnnotation != null) {
                return Optional.of(clazzLraAnnotation);
            }
            clazz = clazz.getSuperclass();
        } while (clazz != null);
    }
    return found.stream().findFirst();
}
Also used : Arrays(java.util.Arrays) AfterLRA(org.eclipse.microprofile.lra.annotation.AfterLRA) Participant(io.helidon.lra.coordinator.client.Participant) HashMap(java.util.HashMap) GET(jakarta.ws.rs.GET) PUT(jakarta.ws.rs.PUT) Level(java.util.logging.Level) Path(jakarta.ws.rs.Path) Leave(org.eclipse.microprofile.lra.annotation.ws.rs.Leave) HashSet(java.util.HashSet) Status(org.eclipse.microprofile.lra.annotation.Status) Map(java.util.Map) URI(java.net.URI) Produces(jakarta.ws.rs.Produces) Method(java.lang.reflect.Method) POST(jakarta.ws.rs.POST) Forget(org.eclipse.microprofile.lra.annotation.Forget) Collection(java.util.Collection) Set(java.util.Set) Logger(java.util.logging.Logger) Collectors(java.util.stream.Collectors) List(java.util.List) UriBuilder(jakarta.ws.rs.core.UriBuilder) LRA(org.eclipse.microprofile.lra.annotation.ws.rs.LRA) Compensate(org.eclipse.microprofile.lra.annotation.Compensate) Annotation(java.lang.annotation.Annotation) Optional(java.util.Optional) DELETE(jakarta.ws.rs.DELETE) Complete(org.eclipse.microprofile.lra.annotation.Complete) AfterLRA(org.eclipse.microprofile.lra.annotation.AfterLRA) LRA(org.eclipse.microprofile.lra.annotation.ws.rs.LRA) Annotation(java.lang.annotation.Annotation)

Example 2 with LRA

use of org.eclipse.microprofile.lra.annotation.ws.rs.LRA in project narayana by jbosstm.

the class LRATest method multiLevelNestedActivity.

private void multiLevelNestedActivity(CompletionType how, int nestedCnt) throws WebApplicationException, URISyntaxException {
    WebTarget resourcePath = client.target(TestPortProvider.generateURL("/base/test/multiLevelNestedActivity"));
    if (how == CompletionType.mixed && nestedCnt <= 1) {
        how = CompletionType.complete;
    }
    URI lra = new URI(client.target(TestPortProvider.generateURL("/base/test/start")).request().get(String.class));
    Response response = resourcePath.queryParam("nestedCnt", nestedCnt).request().header(LRA_HTTP_CONTEXT_HEADER, lra).put(Entity.text(""));
    // the response is a comma separated list of URIs (parent, children)
    String lraStr = response.readEntity(String.class);
    assertNotNull("expecting a LRA string returned from " + resourcePath.getUri(), lraStr);
    URI[] uris = Arrays.stream(lraStr.split(",")).map(s -> {
        try {
            return new URI(s);
        } catch (URISyntaxException e) {
            fail(e.getMessage());
            return null;
        }
    }).toArray(URI[]::new);
    // check that the multiLevelNestedActivity method returned the mandatory LRA followed by any nested LRAs
    assertEquals("multiLevelNestedActivity: step 1 (the test call went to " + resourcePath.getUri() + ")", nestedCnt + 1, uris.length);
    // first element should be the mandatory LRA
    assertEquals("multiLevelNestedActivity: step 2 (the test call went to " + resourcePath.getUri() + ")", lra, uris[0]);
    // and the mandatory lra seen by the multiLevelNestedActivity method
    assertFalse("multiLevelNestedActivity: top level LRA should be active (path called " + resourcePath.getUri() + ")", isFinished(uris[0]));
    // check that all nested activities were told to complete
    assertEquals("multiLevelNestedActivity: step 3 (called test path " + resourcePath.getUri() + ")", nestedCnt, completeCount.get());
    assertEquals("multiLevelNestedActivity: step 4 (called test path " + resourcePath.getUri() + ")", 0, compensateCount.get());
    // close the LRA
    if (how == CompletionType.compensate) {
        lraClient.cancelLRA(lra);
        // validate that the top level and nested LRAs are gone
        assertAllFinished(uris);
        /*
             * the test starts LRA1 calls a @Mandatory method multiLevelNestedActivity which enlists in LRA1
             * multiLevelNestedActivity then calls an @Nested method which starts L2 and enlists another participant
             *   when the method returns the nested participant is completed (ie completed count is incremented)
             * Canceling L1 should then compensate the L1 enlistment (ie compensate count is incremented)
             * which will then tell L2 to compensate (ie the compensate count is incremented again)
             */
        // each nested participant should have completed (the +nestedCnt)
        assertEquals("multiLevelNestedActivity: step 7 (called test path " + resourcePath.getUri() + ")", nestedCnt, completeCount.get());
        // each nested participant should have compensated. The top level enlistment should have compensated (the +1)
        assertEquals("multiLevelNestedActivity: step 8 (called test path " + resourcePath.getUri() + ")", nestedCnt + 1, compensateCount.get());
    } else if (how == CompletionType.complete) {
        lraClient.closeLRA(lra);
        // validate that the top level and nested LRAs are gone
        assertAllFinished(uris);
        // each nested participant and the top level participant should have completed (nestedCnt + 1) at least once
        assertTrue("multiLevelNestedActivity: step 5a (called test path " + resourcePath.getUri() + ")", completeCount.get() >= nestedCnt + 1);
        // each nested participant should have been told to forget
        assertEquals("multiLevelNestedActivity: step 5b (called test path " + resourcePath.getUri() + ")", forgetCount.get(), nestedCnt);
        // and that neither were still not told to compensate
        assertEquals("multiLevelNestedActivity: step 6 (called test path " + resourcePath.getUri() + ")", 0, compensateCount.get());
    } else {
        // compensate the first nested LRA in the enlisted resource
        try (Response r = client.target(TestPortProvider.generateURL("/base/test/end")).queryParam("cancel", true).request().header(LRA_HTTP_CONTEXT_HEADER, uris[1]).put(Entity.text(""))) {
            assertEquals("compensate the first nested LRA", 500, r.getStatus());
        }
        // should not complete any nested LRAs (since they have already completed via the interceptor)
        lraClient.closeLRA(lra);
        /*
             * Expect nestedCnt + 1 completions, 1 for the top level and one for each nested LRA
             * (NB the first nested LRA is completed and compensated)
             * Note that the top level complete should not call complete again on the nested LRA
             */
        assertEquals("multiLevelNestedActivity: step 10 (called test path " + resourcePath.getUri() + ")", nestedCnt + 1, completeCount.get());
        /*
             * The test is calling for a mixed outcome:
             * - the top level LRA was closed
             * - one of the nested LRAs was compensated the rest should have been completed
             */
        // there should be just 1 compensation (the first nested LRA)
        assertEquals("multiLevelNestedActivity: step 9 (called test path " + resourcePath.getUri() + ")", 1, compensateCount.get());
    }
}
Also used : Response(javax.ws.rs.core.Response) Arrays(java.util.Arrays) Produces(javax.ws.rs.Produces) AfterLRA(org.eclipse.microprofile.lra.annotation.AfterLRA) LRAService(io.narayana.lra.coordinator.domain.service.LRAService) URISyntaxException(java.net.URISyntaxException) Path(javax.ws.rs.Path) COORDINATOR_PATH_NAME(io.narayana.lra.LRAConstants.COORDINATOR_PATH_NAME) Application(javax.ws.rs.core.Application) com.arjuna.ats.arjuna.common.arjPropertyManager(com.arjuna.ats.arjuna.common.arjPropertyManager) ParticipantStatusOctetStreamProvider(io.narayana.lra.provider.ParticipantStatusOctetStreamProvider) MediaType(javax.ws.rs.core.MediaType) QueryParam(javax.ws.rs.QueryParam) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) After(org.junit.After) DefaultValue(javax.ws.rs.DefaultValue) HeaderParam(javax.ws.rs.HeaderParam) UndertowJaxrsServer(org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer) Assert.fail(org.junit.Assert.fail) URI(java.net.URI) DELETE(javax.ws.rs.DELETE) ServerLRAFilter(io.narayana.lra.filter.ServerLRAFilter) Forget(org.eclipse.microprofile.lra.annotation.Forget) LRA_HTTP_RECOVERY_HEADER(org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_RECOVERY_HEADER) Set(java.util.Set) Entity(javax.ws.rs.client.Entity) NotFoundException(javax.ws.rs.NotFoundException) Objects(java.util.Objects) NarayanaLRAClient(io.narayana.lra.client.NarayanaLRAClient) Response(javax.ws.rs.core.Response) Assert.assertFalse(org.junit.Assert.assertFalse) WebApplicationException(javax.ws.rs.WebApplicationException) Complete(org.eclipse.microprofile.lra.annotation.Complete) Link(javax.ws.rs.core.Link) IntStream(java.util.stream.IntStream) LRA_HTTP_CONTEXT_HEADER(org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER) BeforeClass(org.junit.BeforeClass) GET(javax.ws.rs.GET) Client(javax.ws.rs.client.Client) HashSet(java.util.HashSet) LRARecoveryModule(io.narayana.lra.coordinator.internal.LRARecoveryModule) ClientBuilder(javax.ws.rs.client.ClientBuilder) TestName(org.junit.rules.TestName) StringTokenizer(java.util.StringTokenizer) Coordinator(io.narayana.lra.coordinator.api.Coordinator) LRA_HTTP_PARENT_CONTEXT_HEADER(org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_PARENT_CONTEXT_HEADER) Before(org.junit.Before) ParticipantStatus(org.eclipse.microprofile.lra.annotation.ParticipantStatus) TestPortProvider(org.jboss.resteasy.test.TestPortProvider) Assert.assertNotNull(org.junit.Assert.assertNotNull) ApplicationPath(javax.ws.rs.ApplicationPath) Assert.assertTrue(org.junit.Assert.assertTrue) Test(org.junit.Test) File(java.io.File) LRAStatus(org.eclipse.microprofile.lra.annotation.LRAStatus) Rule(org.junit.Rule) ChronoUnit(java.time.temporal.ChronoUnit) Assert.assertNull(org.junit.Assert.assertNull) LRA(org.eclipse.microprofile.lra.annotation.ws.rs.LRA) Compensate(org.eclipse.microprofile.lra.annotation.Compensate) LRALogger(io.narayana.lra.logging.LRALogger) PUT(javax.ws.rs.PUT) WebTarget(javax.ws.rs.client.WebTarget) Assert(org.junit.Assert) Assert.assertEquals(org.junit.Assert.assertEquals) WebTarget(javax.ws.rs.client.WebTarget) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI)

Example 3 with LRA

use of org.eclipse.microprofile.lra.annotation.ws.rs.LRA in project narayana by jbosstm.

the class LRAAnnotationAdjuster method processWithClass.

/**
 * Take the clazz, check if contains the {@link LRA} annotation.
 * The LRA annotation is then replaced by wrapped {@link LRAWrapped}.
 */
static void processWithClass(Class<?> clazz) {
    LRA lraAnnotation = clazz.getDeclaredAnnotation(LRA.class);
    if (lraAnnotation != null) {
        LRAAnnotationAdjuster.adjustLRAAnnotation(clazz, lraAnnotation);
    }
    Arrays.stream(clazz.getMethods()).forEach(method -> {
        LRA lraAnnotationMethod = method.getDeclaredAnnotation(LRA.class);
        if (lraAnnotationMethod != null) {
            LRAAnnotationAdjuster.adjustLRAAnnotation(method, lraAnnotationMethod);
        }
    });
}
Also used : LRA(org.eclipse.microprofile.lra.annotation.ws.rs.LRA)

Example 4 with LRA

use of org.eclipse.microprofile.lra.annotation.ws.rs.LRA in project narayana by jbosstm.

the class LRAParticipant method beginLRAWithRemoteCalls.

@GET
@Path(CREATE_OR_CONTINUE_LRA)
@LRA(value = LRA.Type.REQUIRED, end = false)
public Response beginLRAWithRemoteCalls(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lra1) {
    valididateLRAIsActive("lra1 should be active", lraClient.getStatus(lra1));
    // start a new LRA
    URI lra2 = remoteInvocation(lra1, START_NEW_LRA);
    valididateLRAIsActive("lra1 should still be active", lraClient.getStatus(lra1));
    valididateLRAIsActive("lra2 should be active", lraClient.getStatus(lra2));
    // lra1 should be the current context for remote invocations even though lra2 is active
    if (!lra1.equals(lraClient.getCurrent())) {
        throw new WebApplicationException(Response.status(Response.Status.PRECONDITION_FAILED).entity("lra1 should be current").build());
    }
    // lra2 is still active, use it for the next invocation
    URI lra3 = remoteInvocation(lra2, CONTINUE_LRA);
    valididateLRAIsActive("lra2 should still be active", lraClient.getStatus(lra2));
    if (!lra2.equals(lra3)) {
        // lra3 was a continuation of lra2
        throw new WebApplicationException(Response.status(Response.Status.PRECONDITION_FAILED).entity("lra2 should equal lra3").build());
    }
    // use the (proprietary) client API to close the LRA started above (START_NEW_LRA)
    lraClient.closeLRA(lra2);
    // the status of lra2 should be NOT_FOUND or not active
    try {
        // verify that the LRA is no longer active
        valididateLRAIsNotActive("lra2 should no longer be active", lraClient.getStatus(lra2));
    } catch (NotFoundException ignore) {
    // LRA is not active
    }
    // the original LRA (lra1) will still be active (because of the end = false attribute)
    return Response.status(Response.Status.OK).entity(lra1.toASCIIString()).build();
}
Also used : WebApplicationException(javax.ws.rs.WebApplicationException) NotFoundException(javax.ws.rs.NotFoundException) URI(java.net.URI) Path(javax.ws.rs.Path) GET(javax.ws.rs.GET) LRA(org.eclipse.microprofile.lra.annotation.ws.rs.LRA)

Example 5 with LRA

use of org.eclipse.microprofile.lra.annotation.ws.rs.LRA in project narayana by jbosstm.

the class LRAParticipant method beginLRAWithRemoteCalls2.

@GET
@Path(CREATE_OR_CONTINUE_LRA2)
@LRA(value = LRA.Type.REQUIRED, end = false)
public Response beginLRAWithRemoteCalls2(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) URI lra1) {
    valididateLRAIsActive("lra1 should be active", lraClient.getStatus(lra1));
    URI lra2 = lraClient.startLRA("lra");
    // use the (proprietary) client API to close the LRA started above (START_NEW_LRA)
    lraClient.closeLRA(lra2);
    valididateLRAIsNotActive("lra2 should no longer be active", lraClient.getStatus(lra2));
    // the original LRA (lra1) will still be active (because of the end = false attribute)
    return Response.status(Response.Status.OK).entity(lra1.toASCIIString()).build();
}
Also used : URI(java.net.URI) Path(javax.ws.rs.Path) GET(javax.ws.rs.GET) LRA(org.eclipse.microprofile.lra.annotation.ws.rs.LRA)

Aggregations

LRA (org.eclipse.microprofile.lra.annotation.ws.rs.LRA)9 URI (java.net.URI)6 AfterLRA (org.eclipse.microprofile.lra.annotation.AfterLRA)5 Compensate (org.eclipse.microprofile.lra.annotation.Compensate)5 Complete (org.eclipse.microprofile.lra.annotation.Complete)5 Method (java.lang.reflect.Method)4 Arrays (java.util.Arrays)4 HashSet (java.util.HashSet)4 Set (java.util.Set)4 NotFoundException (javax.ws.rs.NotFoundException)4 WebApplicationException (javax.ws.rs.WebApplicationException)4 Forget (org.eclipse.microprofile.lra.annotation.Forget)4 URISyntaxException (java.net.URISyntaxException)3 ChronoUnit (java.time.temporal.ChronoUnit)3 Map (java.util.Map)3 Objects (java.util.Objects)3 GET (javax.ws.rs.GET)3 Path (javax.ws.rs.Path)3 com.arjuna.ats.arjuna.common.arjPropertyManager (com.arjuna.ats.arjuna.common.arjPropertyManager)2 COORDINATOR_PATH_NAME (io.narayana.lra.LRAConstants.COORDINATOR_PATH_NAME)2