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