use of fish.payara.notification.requesttracing.RequestTraceSpan in project Payara by payara.
the class StandardWrapper method constructWebServiceRequestSpan.
// END IASRI 4665318
private RequestTraceSpan constructWebServiceRequestSpan(HttpServletRequest httpServletRequest) {
RequestTraceSpan span = new RequestTraceSpan("processWebserviceRequest");
span.addSpanTag("URL", httpServletRequest.getRequestURL().toString());
Enumeration<String> headerNames = httpServletRequest.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
span.addSpanTag(headerName, list(httpServletRequest.getHeaders(headerName)).toString());
}
span.addSpanTag("Method", httpServletRequest.getMethod());
return span;
}
use of fish.payara.notification.requesttracing.RequestTraceSpan in project Payara by payara.
the class BulkheadInterceptor method bulkhead.
/**
* Proceeds the context under Bulkhead semantics.
* @param invocationContext The context to proceed.
* @return The outcome of the invocationContext
* @throws Exception
*/
private Object bulkhead(InvocationContext invocationContext) throws Exception {
Object proceededInvocationContext = null;
FaultToleranceService faultToleranceService = Globals.getDefaultBaseServiceLocator().getService(FaultToleranceService.class);
Bulkhead bulkhead = FaultToleranceCdiUtils.getAnnotation(beanManager, Bulkhead.class, invocationContext);
Config config = null;
try {
config = ConfigProvider.getConfig();
} catch (IllegalArgumentException ex) {
logger.log(Level.INFO, "No config could be found", ex);
}
int value = (Integer) FaultToleranceCdiUtils.getOverrideValue(config, Bulkhead.class, "value", invocationContext, Integer.class).orElse(bulkhead.value());
int waitingTaskQueue = (Integer) FaultToleranceCdiUtils.getOverrideValue(config, Bulkhead.class, "waitingTaskQueue", invocationContext, Integer.class).orElse(bulkhead.waitingTaskQueue());
InvocationManager invocationManager = Globals.getDefaultBaseServiceLocator().getService(InvocationManager.class);
String appName = faultToleranceService.getApplicationName(invocationManager, invocationContext);
Semaphore bulkheadExecutionSemaphore = faultToleranceService.getBulkheadExecutionSemaphore(appName, invocationContext.getMethod(), value);
// If the Asynchronous annotation is present, use threadpool style, otherwise use semaphore style
if (FaultToleranceCdiUtils.getAnnotation(beanManager, Asynchronous.class, invocationContext) != null) {
Semaphore bulkheadExecutionQueueSemaphore = faultToleranceService.getBulkheadExecutionQueueSemaphore(appName, invocationContext.getMethod(), waitingTaskQueue);
// Check if there are any free permits for concurrent execution
if (!bulkheadExecutionSemaphore.tryAcquire(0, TimeUnit.SECONDS)) {
logger.log(Level.FINER, "Attempting to acquire bulkhead queue semaphore.");
// If there aren't any free permits, see if there are any free queue permits
if (bulkheadExecutionQueueSemaphore.tryAcquire(0, TimeUnit.SECONDS)) {
logger.log(Level.FINER, "Acquired bulkhead queue semaphore.");
// If there is a free queue permit, queue for an executor permit
try {
logger.log(Level.FINER, "Attempting to acquire bulkhead execution semaphore.");
faultToleranceService.startFaultToleranceSpan(new RequestTraceSpan("obtainBulkheadSemaphore"), invocationManager, invocationContext);
try {
bulkheadExecutionSemaphore.acquire();
} finally {
// Make sure we end the trace right here
faultToleranceService.endFaultToleranceSpan();
}
logger.log(Level.FINER, "Acquired bulkhead queue semaphore.");
// Release the queue permit
bulkheadExecutionQueueSemaphore.release();
// Proceed the invocation and wait for the response
try {
logger.log(Level.FINER, "Proceeding bulkhead context");
proceededInvocationContext = invocationContext.proceed();
} catch (Exception ex) {
logger.log(Level.FINE, "Exception proceeding Bulkhead context", ex);
// Generic catch, as we need to release the semaphore permits
bulkheadExecutionSemaphore.release();
bulkheadExecutionQueueSemaphore.release();
// Let the exception propagate further up - we just want to release the semaphores
throw ex;
}
// Release the execution permit
bulkheadExecutionSemaphore.release();
} catch (InterruptedException ex) {
logger.log(Level.INFO, "Interrupted acquiring bulkhead semaphore", ex);
throw new BulkheadException(ex);
}
} else {
throw new BulkheadException("No free work or queue permits.");
}
} else {
// Proceed the invocation and wait for the response
try {
logger.log(Level.FINER, "Proceeding bulkhead context");
proceededInvocationContext = invocationContext.proceed();
} catch (Exception ex) {
logger.log(Level.FINE, "Exception proceeding Bulkhead context", ex);
// Generic catch, as we need to release the semaphore permits
bulkheadExecutionSemaphore.release();
// Let the exception propagate further up - we just want to release the semaphores
throw ex;
}
// Release the permit
bulkheadExecutionSemaphore.release();
}
} else {
// Try to get an execution permit
if (bulkheadExecutionSemaphore.tryAcquire(0, TimeUnit.SECONDS)) {
// Proceed the invocation and wait for the response
try {
logger.log(Level.FINER, "Proceeding bulkhead context");
proceededInvocationContext = invocationContext.proceed();
} catch (Exception ex) {
logger.log(Level.FINE, "Exception proceeding Bulkhead context", ex);
// Generic catch, as we need to release the semaphore permits
bulkheadExecutionSemaphore.release();
// Let the exception propagate further up - we just want to release the semaphores
throw ex;
}
// Release the permit
bulkheadExecutionSemaphore.release();
} else {
throw new BulkheadException("No free work permits.");
}
}
return proceededInvocationContext;
}
use of fish.payara.notification.requesttracing.RequestTraceSpan in project Payara by payara.
the class RetryInterceptor method retry.
/**
* Proceeds the given invocation context with Retry semantics.
* @param invocationContext The invocation context to proceed
* @return The proceeded invocation context
* @throws Exception If the invocation throws an exception that shouldn't be retried, or if all retry attempts are
* expended
*/
private Object retry(InvocationContext invocationContext) throws Exception {
Object proceededInvocationContext = null;
Retry retry = FaultToleranceCdiUtils.getAnnotation(beanManager, Retry.class, invocationContext);
FaultToleranceService faultToleranceService = Globals.getDefaultBaseServiceLocator().getService(FaultToleranceService.class);
InvocationManager invocationManager = Globals.getDefaultBaseServiceLocator().getService(InvocationManager.class);
try {
proceededInvocationContext = invocationContext.proceed();
} catch (Exception ex) {
Config config = null;
try {
config = ConfigProvider.getConfig();
} catch (IllegalArgumentException iae) {
logger.log(Level.INFO, "No config could be found", ex);
}
Class<? extends Throwable>[] retryOn = retry.retryOn();
try {
String retryOnString = ((String) FaultToleranceCdiUtils.getOverrideValue(config, Retry.class, "retryOn", invocationContext, String.class).get());
List<Class> classList = new ArrayList<>();
// Remove any curly or square brackets from the string, as well as any spaces and ".class"es
for (String className : retryOnString.replaceAll("[\\{\\[ \\]\\}]", "").replaceAll("\\.class", "").split(",")) {
classList.add(Class.forName(className));
}
retryOn = classList.toArray(retryOn);
} catch (NoSuchElementException nsee) {
logger.log(Level.FINER, "Could not find element in config", nsee);
} catch (ClassNotFoundException cnfe) {
logger.log(Level.INFO, "Could not find class from retryOn config, defaulting to annotation. " + "Make sure you give the full canonical class name.", cnfe);
}
Class<? extends Throwable>[] abortOn = retry.abortOn();
try {
String abortOnString = (String) FaultToleranceCdiUtils.getOverrideValue(config, Retry.class, "abortOn", invocationContext, String.class).get();
List<Class> classList = new ArrayList<>();
// Remove any curly or square brackets from the string, as well as any spaces and ".class"es
for (String className : abortOnString.replaceAll("[\\{\\[ \\]\\}]", "").replaceAll("\\.class", "").split(",")) {
classList.add(Class.forName(className));
}
abortOn = classList.toArray(abortOn);
} catch (NoSuchElementException nsee) {
logger.log(Level.FINER, "Could not find element in config", nsee);
} catch (ClassNotFoundException cnfe) {
logger.log(Level.INFO, "Could not find class from abortOn config, defaulting to annotation. " + "Make sure you give the full canonical class name.", cnfe);
}
if (!shouldRetry(retryOn, abortOn, ex)) {
logger.log(Level.FINE, "Exception is contained in retryOn or abortOn, not retrying.", ex);
throw ex;
}
int maxRetries = (Integer) FaultToleranceCdiUtils.getOverrideValue(config, Retry.class, "maxRetries", invocationContext, Integer.class).orElse(retry.maxRetries());
long delay = (Long) FaultToleranceCdiUtils.getOverrideValue(config, Retry.class, "delay", invocationContext, Long.class).orElse(retry.delay());
ChronoUnit delayUnit = (ChronoUnit) FaultToleranceCdiUtils.getOverrideValue(config, Retry.class, "delayUnit", invocationContext, ChronoUnit.class).orElse(retry.delayUnit());
long maxDuration = (Long) FaultToleranceCdiUtils.getOverrideValue(config, Retry.class, "maxDuration", invocationContext, Long.class).orElse(retry.maxDuration());
ChronoUnit durationUnit = (ChronoUnit) FaultToleranceCdiUtils.getOverrideValue(config, Retry.class, "durationUnit", invocationContext, ChronoUnit.class).orElse(retry.durationUnit());
long jitter = (Long) FaultToleranceCdiUtils.getOverrideValue(config, Retry.class, "jitter", invocationContext, Long.class).orElse(retry.jitter());
ChronoUnit jitterDelayUnit = (ChronoUnit) FaultToleranceCdiUtils.getOverrideValue(config, Retry.class, "jitterDelayUnit", invocationContext, ChronoUnit.class).orElse(retry.jitterDelayUnit());
long delayMillis = Duration.of(delay, delayUnit).toMillis();
long jitterMillis = Duration.of(jitter, jitterDelayUnit).toMillis();
long timeoutTime = System.currentTimeMillis() + Duration.of(maxDuration, durationUnit).toMillis();
Exception retryException = ex;
faultToleranceService.startFaultToleranceSpan(new RequestTraceSpan("retryMethod"), invocationManager, invocationContext);
try {
if (maxRetries == -1 && maxDuration > 0) {
logger.log(Level.FINER, "Retrying until maxDuration is breached.");
while (System.currentTimeMillis() < timeoutTime) {
try {
proceededInvocationContext = invocationContext.proceed();
break;
} catch (Exception caughtException) {
retryException = caughtException;
if (!shouldRetry(retryOn, abortOn, caughtException)) {
break;
}
if (delayMillis > 0 || jitterMillis > 0) {
faultToleranceService.startFaultToleranceSpan(new RequestTraceSpan("delayRetry"), invocationManager, invocationContext);
try {
Thread.sleep(delayMillis + ThreadLocalRandom.current().nextLong(0, jitterMillis));
} finally {
faultToleranceService.endFaultToleranceSpan();
}
}
}
}
} else if (maxRetries == -1 && maxDuration == 0) {
logger.log(Level.INFO, "Retrying potentially forever!");
while (true) {
try {
proceededInvocationContext = invocationContext.proceed();
break;
} catch (Exception caughtException) {
retryException = caughtException;
if (!shouldRetry(retryOn, abortOn, caughtException)) {
break;
}
if (delayMillis > 0 || jitterMillis > 0) {
faultToleranceService.startFaultToleranceSpan(new RequestTraceSpan("delayRetry"), invocationManager, invocationContext);
try {
Thread.sleep(delayMillis + ThreadLocalRandom.current().nextLong(0, jitterMillis));
} finally {
faultToleranceService.endFaultToleranceSpan();
}
}
}
}
} else if (maxRetries != -1 && maxDuration > 0) {
logger.log(Level.INFO, "Retrying as long as maxDuration ({0}ms) isn''t breached, and no more than {1} times", new Object[] { Duration.of(maxDuration, durationUnit).toMillis(), maxRetries });
while (maxRetries > 0 && System.currentTimeMillis() < timeoutTime) {
try {
proceededInvocationContext = invocationContext.proceed();
break;
} catch (Exception caughtException) {
retryException = caughtException;
if (!shouldRetry(retryOn, abortOn, caughtException)) {
break;
}
if (delayMillis > 0 || jitterMillis > 0) {
faultToleranceService.startFaultToleranceSpan(new RequestTraceSpan("delayRetry"), invocationManager, invocationContext);
try {
Thread.sleep(delayMillis + ThreadLocalRandom.current().nextLong(0, jitterMillis));
} finally {
faultToleranceService.endFaultToleranceSpan();
}
}
maxRetries--;
}
}
} else {
logger.log(Level.INFO, "Retrying no more than {0} times", maxRetries);
while (maxRetries > 0) {
try {
proceededInvocationContext = invocationContext.proceed();
break;
} catch (Exception caughtException) {
retryException = caughtException;
if (!shouldRetry(retryOn, abortOn, caughtException)) {
break;
}
if (delayMillis > 0 || jitterMillis > 0) {
faultToleranceService.startFaultToleranceSpan(new RequestTraceSpan("delayRetry"), invocationManager, invocationContext);
try {
Thread.sleep(delayMillis + ThreadLocalRandom.current().nextLong(0, jitterMillis));
} finally {
faultToleranceService.endFaultToleranceSpan();
}
}
maxRetries--;
}
}
}
} finally {
faultToleranceService.endFaultToleranceSpan();
}
if (proceededInvocationContext == null) {
throw retryException;
}
}
return proceededInvocationContext;
}
use of fish.payara.notification.requesttracing.RequestTraceSpan in project Payara by payara.
the class ContextSetupProviderImpl method constructConcurrentContextSpan.
private RequestTraceSpan constructConcurrentContextSpan(ComponentInvocation invocation) {
RequestTraceSpan span = new RequestTraceSpan(EventType.TRACE_START, "executeConcurrentContext");
span.addSpanTag("App Name", invocation.getAppName());
span.addSpanTag("Component ID", invocation.getComponentId());
span.addSpanTag("Module Name", invocation.getModuleName());
Object instance = invocation.getInstance();
if (instance != null) {
span.addSpanTag("Class Name", instance.getClass().getName());
}
span.addSpanTag("Thread Name", Thread.currentThread().getName());
return span;
}
use of fish.payara.notification.requesttracing.RequestTraceSpan in project Payara by payara.
the class ContextSetupProviderImpl method setup.
@Override
public ContextHandle setup(ContextHandle contextHandle) throws IllegalStateException {
if (!(contextHandle instanceof InvocationContext)) {
logger.log(Level.SEVERE, LogFacade.UNKNOWN_CONTEXT_HANDLE);
return null;
}
InvocationContext handle = (InvocationContext) contextHandle;
String appName = null;
if (handle.getInvocation() != null) {
appName = handle.getInvocation().getAppName();
}
if (appName == null && handle.getInvocation().getJNDIEnvironment() != null) {
appName = DOLUtils.getApplicationFromEnv((JndiNameEnvironment) handle.getInvocation().getJNDIEnvironment()).getName();
}
ClassLoader backupClassLoader = null;
if (appName == null) {
// try to get environment from component ID
if (handle.getInvocation().getComponentId() != null && compEnvMgr != null) {
JndiNameEnvironment currJndiEnv = compEnvMgr.getJndiNameEnvironment(handle.getInvocation().getComponentId());
if (currJndiEnv != null) {
com.sun.enterprise.deployment.Application appInfo = DOLUtils.getApplicationFromEnv(currJndiEnv);
if (appInfo != null) {
appName = appInfo.getName();
// cache JNDI environment
handle.getInvocation().setJNDIEnvironment(currJndiEnv);
backupClassLoader = appInfo.getClassLoader();
}
}
}
}
// Check whether the application component submitting the task is still running. Throw IllegalStateException if not.
if (!isApplicationEnabled(appName)) {
throw new IllegalStateException("Module " + appName + " is disabled");
}
ClassLoader resetClassLoader = null;
SecurityContext resetSecurityContext = null;
if (handle.getContextClassLoader() != null) {
resetClassLoader = Utility.setContextClassLoader(handle.getContextClassLoader());
} else if (backupClassLoader != null) {
resetClassLoader = Utility.setContextClassLoader(backupClassLoader);
}
if (handle.getSecurityContext() != null) {
resetSecurityContext = SecurityContext.getCurrent();
SecurityContext.setCurrent(handle.getSecurityContext());
}
ComponentInvocation invocation = handle.getInvocation();
if (invocation != null && !handle.isUseTransactionOfExecutionThread()) {
// Each invocation needs a ResourceTableKey that returns a unique hashCode for TransactionManager
invocation.setResourceTableKey(new PairKey(invocation.getInstance(), Thread.currentThread()));
invocationManager.preInvoke(invocation);
}
// Ensure that there is no existing transaction in the current thread
if (transactionManager != null) {
transactionManager.clearThreadTx();
}
if (requestTracing != null && requestTracing.isRequestTracingEnabled()) {
RequestTraceSpan span = constructConcurrentContextSpan(invocation);
requestTracing.startTrace(span);
}
if (stuckThreads != null) {
stuckThreads.registerThread(Thread.currentThread().getId());
}
return new InvocationContext(invocation, resetClassLoader, resetSecurityContext, handle.isUseTransactionOfExecutionThread());
}
Aggregations