Search in sources :

Example 1 with PropagatedHeaders

use of io.helidon.lra.coordinator.client.PropagatedHeaders in project helidon by oracle.

the class LraAnnotationHandler method handleJaxRsBefore.

@Override
public void handleJaxRsBefore(ContainerRequestContext reqCtx, ResourceInfo resourceInfo) {
    Method method = resourceInfo.getResourceMethod();
    URI baseUri = reqCtx.getUriInfo().getBaseUri();
    PropagatedHeaders propagatedHeaders = participantService.prepareCustomHeaderPropagation(reqCtx.getHeaders());
    Participant participant = participantService.participant(baseUri, resourceInfo.getResourceClass());
    Optional<URI> existingLraId = getLraContext(reqCtx);
    long timeLimit = Duration.of(annotation.timeLimit(), annotation.timeUnit()).toMillis();
    String clientId = method.getDeclaringClass().getName() + "#" + method.getName();
    final URI lraId;
    try {
        switch(annotation.value()) {
            case NESTED:
                if (existingLraId.isPresent()) {
                    URI parentLraId = existingLraId.get();
                    setParentContext(reqCtx, parentLraId);
                    lraId = start(parentLraId, clientId, propagatedHeaders, timeLimit);
                } else {
                    lraId = start(clientId, propagatedHeaders, timeLimit);
                }
                join(reqCtx, lraId, propagatedHeaders, timeLimit, participant);
                setLraContext(reqCtx, lraId);
                break;
            case NEVER:
                if (existingLraId.isPresent()) {
                    // If called inside an LRA context, i.e., the method is not executed
                    // and a 412 Precondition Failed is returned
                    reqCtx.abortWith(Response.status(Response.Status.PRECONDITION_FAILED).build());
                    return;
                }
                break;
            case NOT_SUPPORTED:
                reqCtx.getHeaders().remove(LRA_HTTP_CONTEXT_HEADER);
                return;
            case SUPPORTS:
                if (existingLraId.isPresent()) {
                    lraId = existingLraId.get();
                    join(reqCtx, lraId, propagatedHeaders, timeLimit, participant);
                    setLraContext(reqCtx, lraId);
                }
                break;
            case MANDATORY:
                if (existingLraId.isEmpty()) {
                    // If called outside an LRA context the method is not executed and a
                    // 412 Precondition Failed HTTP status code is returned to the caller
                    reqCtx.abortWith(Response.status(Response.Status.PRECONDITION_FAILED).build());
                    return;
                }
            // existing lra, fall through to required
            case REQUIRED:
                if (existingLraId.isPresent()) {
                    lraId = existingLraId.get();
                    join(reqCtx, lraId, propagatedHeaders, timeLimit, participant);
                    setLraContext(reqCtx, lraId);
                    break;
                }
            // non-existing lra, fall through to requires_new
            case REQUIRES_NEW:
                lraId = start(clientId, propagatedHeaders, timeLimit);
                join(reqCtx, lraId, propagatedHeaders, timeLimit, participant);
                setLraContext(reqCtx, lraId);
                break;
            default:
                LOGGER.severe("Unsupported LRA type " + annotation.value() + " on method " + method.getName());
                reqCtx.abortWith(Response.status(500).build());
                break;
        }
    } catch (CoordinatorConnectionException e) {
        throw new WebApplicationException(e.getMessage(), e.getCause(), e.status());
    } finally {
        setHeaderPropagationContext(reqCtx, propagatedHeaders);
    }
}
Also used : PropagatedHeaders(io.helidon.lra.coordinator.client.PropagatedHeaders) Participant(io.helidon.lra.coordinator.client.Participant) WebApplicationException(jakarta.ws.rs.WebApplicationException) CoordinatorConnectionException(io.helidon.lra.coordinator.client.CoordinatorConnectionException) Method(java.lang.reflect.Method) URI(java.net.URI)

Example 2 with PropagatedHeaders

use of io.helidon.lra.coordinator.client.PropagatedHeaders in project helidon by oracle.

the class NonJaxRsResource method createNonJaxRsParticipantResource.

Service createNonJaxRsParticipantResource() {
    return rules -> rules.any("/{type}/{fqdn}/{methodName}", (req, res) -> {
        LOGGER.log(Level.FINE, () -> "Non JAX-RS LRA resource " + req.method().name() + " " + req.absoluteUri());
        RequestHeaders headers = req.headers();
        HttpRequest.Path path = req.path();
        URI lraId = headers.first(LRA_HTTP_CONTEXT_HEADER).or(() -> headers.first(LRA_HTTP_ENDED_CONTEXT_HEADER)).map(URI::create).orElse(null);
        URI parentId = headers.first(LRA_HTTP_PARENT_CONTEXT_HEADER).map(URI::create).orElse(null);
        PropagatedHeaders propagatedHeaders = participantService.prepareCustomHeaderPropagation(headers.toMap());
        String fqdn = path.param("fqdn");
        String method = path.param("methodName");
        String type = path.param("type");
        switch(type) {
            case "compensate":
            case "complete":
                Single.<Optional<?>>empty().observeOn(exec).onCompleteResumeWithSingle(o -> participantService.invoke(fqdn, method, lraId, parentId, propagatedHeaders)).forSingle(result -> result.ifPresentOrElse(r -> sendResult(res, r), res::send)).exceptionallyAccept(t -> sendError(lraId, req, res, t));
                break;
            case "afterlra":
                req.content().as(String.class).map(LRAStatus::valueOf).observeOn(exec).flatMapSingle(s -> Single.defer(() -> participantService.invoke(fqdn, method, lraId, s, propagatedHeaders))).onComplete(res::send).onError(t -> sendError(lraId, req, res, t)).ignoreElement();
                break;
            case "status":
                Single.<Optional<?>>empty().observeOn(exec).onCompleteResumeWithSingle(o -> participantService.invoke(fqdn, method, lraId, null, propagatedHeaders)).forSingle(result -> result.ifPresentOrElse(r -> sendResult(res, r), // or in the case of non-JAX-RS method returning ParticipantStatus null.
                () -> res.status(Response.Status.GONE.getStatusCode()).send())).exceptionallyAccept(t -> sendError(lraId, req, res, t));
                break;
            case "forget":
                Single.<Optional<?>>empty().observeOn(exec).onCompleteResumeWithSingle(o -> participantService.invoke(fqdn, method, lraId, parentId, propagatedHeaders)).onComplete(res::send).onError(t -> sendError(lraId, req, res, t)).ignoreElement();
                break;
            default:
                LOGGER.severe(() -> "Unexpected non Jax-Rs LRA compensation type " + type + ": " + req.absoluteUri());
                res.status(404).send();
                break;
        }
    });
}
Also used : LRAResponse(org.eclipse.microprofile.lra.LRAResponse) LRA_HTTP_CONTEXT_HEADER(org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER) PropagatedHeaders(io.helidon.lra.coordinator.client.PropagatedHeaders) LRA_HTTP_ENDED_CONTEXT_HEADER(org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_ENDED_CONTEXT_HEADER) Supplier(java.util.function.Supplier) Level(java.util.logging.Level) Response(jakarta.ws.rs.core.Response) Map(java.util.Map) ServerResponse(io.helidon.webserver.ServerResponse) Single(io.helidon.common.reactive.Single) URI(java.net.URI) Service(io.helidon.webserver.Service) Reflected(io.helidon.common.Reflected) ExecutorService(java.util.concurrent.ExecutorService) LRA_HTTP_PARENT_CONTEXT_HEADER(org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_PARENT_CONTEXT_HEADER) ParticipantStatus(org.eclipse.microprofile.lra.annotation.ParticipantStatus) Config(io.helidon.config.Config) PreDestroy(jakarta.annotation.PreDestroy) Logger(java.util.logging.Logger) RequestHeaders(io.helidon.webserver.RequestHeaders) Collectors(java.util.stream.Collectors) ServerRequest(io.helidon.webserver.ServerRequest) TimeUnit(java.util.concurrent.TimeUnit) LRAStatus(org.eclipse.microprofile.lra.annotation.LRAStatus) Optional(java.util.Optional) ConfigProperty(org.eclipse.microprofile.config.inject.ConfigProperty) Inject(jakarta.inject.Inject) ThreadPoolSupplier(io.helidon.common.configurable.ThreadPoolSupplier) HttpRequest(io.helidon.common.http.HttpRequest) HttpRequest(io.helidon.common.http.HttpRequest) PropagatedHeaders(io.helidon.lra.coordinator.client.PropagatedHeaders) Optional(java.util.Optional) RequestHeaders(io.helidon.webserver.RequestHeaders) URI(java.net.URI)

Example 3 with PropagatedHeaders

use of io.helidon.lra.coordinator.client.PropagatedHeaders in project helidon by oracle.

the class NoopAnnotationHandler method handleJaxRsBefore.

@Override
public void handleJaxRsBefore(ContainerRequestContext requestContext, ResourceInfo resourceInfo) {
    // Custom headers propagation
    PropagatedHeaders propagatedHeaders = participantService.prepareCustomHeaderPropagation(requestContext.getHeaders());
    String key = PropagatedHeaders.class.getName();
    requestContext.setProperty(key, propagatedHeaders);
    Contexts.context().ifPresent(context -> context.register(key, propagatedHeaders));
}
Also used : PropagatedHeaders(io.helidon.lra.coordinator.client.PropagatedHeaders)

Example 4 with PropagatedHeaders

use of io.helidon.lra.coordinator.client.PropagatedHeaders in project helidon by oracle.

the class ParticipantService method prepareCustomHeaderPropagation.

PropagatedHeaders prepareCustomHeaderPropagation(Map<String, List<String>> headers) {
    PropagatedHeaders propagatedHeaders = PropagatedHeaders.create(propagationPrefixes);
    // Scan for compatible headers
    propagatedHeaders.scan(headers);
    return propagatedHeaders;
}
Also used : PropagatedHeaders(io.helidon.lra.coordinator.client.PropagatedHeaders)

Example 5 with PropagatedHeaders

use of io.helidon.lra.coordinator.client.PropagatedHeaders in project helidon by oracle.

the class LeaveAnnotationHandler method handleJaxRsBefore.

@Override
public void handleJaxRsBefore(ContainerRequestContext reqCtx, ResourceInfo resourceInfo) {
    getLraContext(reqCtx).ifPresent(lraId -> {
        URI baseUri = reqCtx.getUriInfo().getBaseUri();
        Participant p = participantService.participant(baseUri, resourceInfo.getResourceClass());
        coordinatorClient.leave(lraId, p);
        reqCtx.getHeaders().add(LRA_HTTP_CONTEXT_HEADER, lraId.toASCIIString());
        reqCtx.setProperty(LRA_HTTP_CONTEXT_HEADER, lraId);
    });
    // Custom headers propagation
    PropagatedHeaders propagatedHeaders = participantService.prepareCustomHeaderPropagation(reqCtx.getHeaders());
    String key = PropagatedHeaders.class.getName();
    reqCtx.setProperty(key, propagatedHeaders);
    Contexts.context().ifPresent(context -> context.register(key, propagatedHeaders));
}
Also used : PropagatedHeaders(io.helidon.lra.coordinator.client.PropagatedHeaders) Participant(io.helidon.lra.coordinator.client.Participant) URI(java.net.URI)

Aggregations

PropagatedHeaders (io.helidon.lra.coordinator.client.PropagatedHeaders)7 URI (java.net.URI)4 Participant (io.helidon.lra.coordinator.client.Participant)3 Single (io.helidon.common.reactive.Single)2 CoordinatorConnectionException (io.helidon.lra.coordinator.client.CoordinatorConnectionException)2 WebApplicationException (jakarta.ws.rs.WebApplicationException)2 Response (jakarta.ws.rs.core.Response)2 Method (java.lang.reflect.Method)2 Optional (java.util.Optional)2 Logger (java.util.logging.Logger)2 LRA_HTTP_CONTEXT_HEADER (org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_CONTEXT_HEADER)2 LRA_HTTP_PARENT_CONTEXT_HEADER (org.eclipse.microprofile.lra.annotation.ws.rs.LRA.LRA_HTTP_PARENT_CONTEXT_HEADER)2 Reflected (io.helidon.common.Reflected)1 ThreadPoolSupplier (io.helidon.common.configurable.ThreadPoolSupplier)1 Contexts (io.helidon.common.context.Contexts)1 HttpRequest (io.helidon.common.http.HttpRequest)1 Config (io.helidon.config.Config)1 CoordinatorClient (io.helidon.lra.coordinator.client.CoordinatorClient)1 RequestHeaders (io.helidon.webserver.RequestHeaders)1 ServerRequest (io.helidon.webserver.ServerRequest)1