Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
Copyright The Narayana Authors
SPDX-License-Identifier: Apache-2.0
*/
package com.arjuna.ats.jta.cdi.async;
import com.arjuna.ats.jta.cdi.RunnableWithException;
import com.arjuna.ats.jta.cdi.TransactionHandler;
import io.smallrye.reactive.converters.ReactiveTypeConverter;
import io.smallrye.reactive.converters.Registry;
import org.eclipse.microprofile.reactive.streams.operators.ReactiveStreams;
import org.jboss.logging.Logger;
import org.reactivestreams.Publisher;
import jakarta.transaction.Transaction;
import jakarta.transaction.TransactionManager;
import jakarta.transaction.Transactional;
import java.util.Arrays;
import java.util.Optional;
import java.util.concurrent.CompletionException;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.atomic.AtomicReference;
/**
* Handling asynchronous context propagation calls.
* It extends transactions until the intercepted method's async return type is completed.
*/
public final class ContextPropagationAsyncHandler {
private static final Logger log = Logger.getLogger(ContextPropagationAsyncHandler.class);
// check if classes of reactive streams from smallrye for transaction asynchronous handling are available on classpath
private static final boolean areSmallRyeReactiveClassesAvailable = areSmallRyeReactiveClassesAvailable();
/**
*
* Tries to handle asynchronously the returned type from the @{@link Transactional} call.
* This CDI interceptor method checks the return type intercepted method.
* If it's a asynchronous "type" (objectToHandle is instanceof
e.g. {@link CompletionStage})
* then the transaction completion (committing/roll-backing) will be suspended
* until the asynchronous code finishes.
*
*
* If the interceptor returns nothing or just some "normal" return type then synchronous handling is processed.
* Synchronous means that the transaction is completed just here when the method annotated with @{@link Transactional}
* ends.
*
*
* @param tm transaction manager
* @param tx the original transaction
* @param transactional link to method which is annotated with @{@link Transactional}
* @param objectToHandleRef on interceptor proceed this is the returned type which differentiate the action;
* method changes the object when it was handled asynchronously
* @param returnType
* @param afterEndTransaction a lamda invocation on transaction finalization
* @return @{code true} if async handling is possible and it was proceeded, @{code false} means async processing is not possible;
* the method changes the value referenced by @{code objectToHandleRef}, when @{code true} is returned
* @throws Exception failure on async processing error happens
*/
public static boolean tryHandleAsynchronously(
TransactionManager tm, Transaction tx, Transactional transactional, AtomicReference objectToHandleRef,
Class> returnType, RunnableWithException afterEndTransaction) throws Exception {
Object objectToHandle = objectToHandleRef.get();
if (objectToHandle == null) {
return false;
}
if (objectToHandle instanceof CompletionStage) {
// checking if the returned type is CompletionStage, it's certain to be s on classpath as it's under JDK java.util.concurrent package
objectToHandle = handleAsync(tm, tx, transactional, objectToHandle, afterEndTransaction);
} else if (objectToHandle instanceof CompletionStage == false && areSmallRyeReactiveClassesAvailable) {
// the smallrye reactive classes and converter utility class are available, trying to convert the returned object to the known async type
ReactiveTypeConverter