use of org.jboss.as.ejb3.component.stateful.StatefulSessionComponent in project wildfly by wildfly.
the class StatefulSessionSynchronizationInterceptor method processInvocation.
@Override
public Object processInvocation(final InterceptorContext context) throws Exception {
final StatefulSessionComponent component = getComponent(context, StatefulSessionComponent.class);
final StatefulSessionComponentInstance instance = getComponentInstance(context);
final OwnableReentrantLock lock = instance.getLock();
final Object threadLock = instance.getThreadLock();
final AtomicInteger invocationSyncState = instance.getInvocationSynchState();
final TransactionSynchronizationRegistry transactionSynchronizationRegistry = component.getTransactionSynchronizationRegistry();
final Object lockOwner = getLockOwner(transactionSynchronizationRegistry);
final AccessTimeoutDetails timeout = component.getAccessTimeout(context.getMethod());
boolean toDiscard = false;
if (ROOT_LOGGER.isTraceEnabled()) {
ROOT_LOGGER.trace("Trying to acquire lock: " + lock + " for stateful component instance: " + instance + " during invocation: " + context);
}
// we obtain a lock in this synchronization interceptor because the lock needs to be tied to the synchronization
// so that it can released on the tx synchronization callbacks
boolean acquired = lock.tryLock(timeout.getValue(), timeout.getTimeUnit(), lockOwner);
if (!acquired) {
throw EjbLogger.ROOT_LOGGER.failToObtainLock(component.getComponentName(), timeout.getValue(), timeout.getTimeUnit());
}
synchronized (threadLock) {
// invocation in progress
invocationSyncState.set(SYNC_STATE_INVOCATION_IN_PROGRESS);
if (ROOT_LOGGER.isTraceEnabled()) {
ROOT_LOGGER.trace("Acquired lock: " + lock + " for stateful component instance: " + instance + " during invocation: " + context);
}
Object currentTransactionKey = null;
boolean wasTxSyncRegistered = false;
try {
// so enrolling in an existing transaction is not correct
if (containerManagedTransactions) {
if (!instance.isSynchronizationRegistered()) {
// get the key to current transaction associated with this thread
currentTransactionKey = transactionSynchronizationRegistry.getTransactionKey();
final int status = transactionSynchronizationRegistry.getTransactionStatus();
// if the thread is currently associated with a tx, then register a tx synchronization
if (currentTransactionKey != null && status != Status.STATUS_COMMITTED && status != Status.STATUS_ROLLEDBACK) {
// register a tx synchronization for this SFSB instance
final Synchronization statefulSessionSync = new StatefulSessionSynchronization(instance);
transactionSynchronizationRegistry.registerInterposedSynchronization(statefulSessionSync);
wasTxSyncRegistered = true;
if (ROOT_LOGGER.isTraceEnabled()) {
ROOT_LOGGER.trace("Registered tx synchronization: " + statefulSessionSync + " for tx: " + currentTransactionKey + " associated with stateful component instance: " + instance);
}
// invoke the afterBegin callback on the SFSB
instance.afterBegin();
instance.setSynchronizationRegistered(true);
context.putPrivateData(StatefulTransactionMarker.class, StatefulTransactionMarker.of(true));
}
} else {
context.putPrivateData(StatefulTransactionMarker.class, StatefulTransactionMarker.of(false));
}
}
// handle exceptions to coincide with exception handling in StatefulComponentInstanceInterceptor
try {
return context.proceed();
} catch (Exception ex) {
if (component.shouldDiscard(ex, context.getMethod())) {
toDiscard = true;
}
throw ex;
} catch (Error e) {
// discard bean cache state on error
toDiscard = true;
throw e;
} catch (Throwable t) {
// discard bean cache state on error
toDiscard = true;
throw t;
}
} finally {
// case: sync was not registered in this invocation nor in a previous one
if (!wasTxSyncRegistered && !instance.isSynchronizationRegistered()) {
ROOT_LOGGER.tracef("Calling release from synchronization interceptor (#1), instance id K = %s", instance.getId());
releaseInstance(instance, toDiscard);
} else if (!wasTxSyncRegistered) {
// case: sync was not registered in this invocation but in a previous one
// if we don't release the lock here then it will be acquired multiple times and only released once
releaseLock(instance);
// we also call the cache release to decrease the usage count
if (!instance.isDiscarded() && !toDiscard) {
ROOT_LOGGER.tracef("Calling release from synchronization interceptor (#2), instance id K = %s", instance.getId());
instance.getComponent().getCache().release(instance);
}
}
for (; ; ) {
int state = invocationSyncState.get();
if (state == SYNC_STATE_INVOCATION_IN_PROGRESS && invocationSyncState.compareAndSet(SYNC_STATE_INVOCATION_IN_PROGRESS, SYNC_STATE_NO_INVOCATION)) {
break;
} else if (state == SYNC_STATE_AFTER_COMPLETE_DELAYED_COMMITTED || state == SYNC_STATE_AFTER_COMPLETE_DELAYED_NO_COMMIT) {
try {
// invoke the after completion method, other after completion syncs may have already run
handleAfterCompletion(state == SYNC_STATE_AFTER_COMPLETE_DELAYED_COMMITTED, instance, toDiscard);
} finally {
invocationSyncState.set(SYNC_STATE_NO_INVOCATION);
}
} else {
EjbLogger.ROOT_LOGGER.unexpectedInvocationState(state);
break;
}
}
}
}
}
use of org.jboss.as.ejb3.component.stateful.StatefulSessionComponent in project wildfly by wildfly.
the class EjbCorbaServant method prepareInterceptorContext.
private void prepareInterceptorContext(final SkeletonStrategy op, final Object[] params, final InterceptorContext interceptorContext) throws IOException, ClassNotFoundException {
if (!home && componentView.getComponent() instanceof StatefulSessionComponent) {
final SessionID sessionID = (SessionID) unmarshalIdentifier();
interceptorContext.putPrivateData(SessionID.class, sessionID);
}
interceptorContext.setContextData(new HashMap<>());
interceptorContext.setParameters(params);
interceptorContext.setMethod(op.getMethod());
interceptorContext.putPrivateData(ComponentView.class, componentView);
interceptorContext.putPrivateData(Component.class, componentView.getComponent());
interceptorContext.putPrivateData(InvocationType.class, InvocationType.REMOTE);
interceptorContext.setTransaction(inboundTxCurrent == null ? null : inboundTxCurrent.getCurrentTransaction());
}
use of org.jboss.as.ejb3.component.stateful.StatefulSessionComponent in project wildfly by wildfly.
the class LocalEjbReceiver method createSession.
protected SessionID createSession(final EJBReceiverSessionCreationContext receiverContext) throws Exception {
final StatelessEJBLocator<?> statelessLocator = receiverContext.getClientInvocationContext().getLocator().asStateless();
final EjbDeploymentInformation ejbInfo = findBean(statelessLocator);
final EJBComponent component = ejbInfo.getEjbComponent();
if (!(component instanceof StatefulSessionComponent)) {
throw EjbLogger.ROOT_LOGGER.notStatefulSessionBean(statelessLocator.getAppName(), statelessLocator.getModuleName(), statelessLocator.getDistinctName(), statelessLocator.getBeanName());
}
component.waitForComponentStart();
return ((StatefulSessionComponent) component).createSession();
}
use of org.jboss.as.ejb3.component.stateful.StatefulSessionComponent in project wildfly by wildfly.
the class AssociationImpl method updateAffinities.
private void updateAffinities(InvocationRequest invocationRequest, Map<String, Object> attachments, EJBLocator<?> ejbLocator, ComponentView componentView) {
Affinity legacyAffinity = null;
Affinity weakAffinity = null;
Affinity strongAffinity = null;
if (ejbLocator.isStateful() && componentView.getComponent() instanceof StatefulSessionComponent) {
final StatefulSessionComponent statefulSessionComponent = (StatefulSessionComponent) componentView.getComponent();
strongAffinity = getStrongAffinity(statefulSessionComponent);
weakAffinity = legacyAffinity = getWeakAffinity(statefulSessionComponent, ejbLocator.asStateful());
} else if (componentView.getComponent() instanceof StatelessSessionComponent) {
// Stateless invocations no not require strong affinity, only weak affinity to nodes within the same cluster, if present.
// However, since V3, the Jakarta Enterprise Beans client does not support weak affinity updates referencing a cluster (and even then, only via Affinity.WEAK_AFFINITY_CONTEXT_KEY), only a node.
// Until this is corrected, we need to use the strong affinity instead.
strongAffinity = legacyAffinity = this.getStatelessAffinity(invocationRequest);
}
// cause the affinity values to get sent back to the client
if (strongAffinity != null && !(strongAffinity instanceof NodeAffinity)) {
invocationRequest.updateStrongAffinity(strongAffinity);
}
if (weakAffinity != null && !weakAffinity.equals(Affinity.NONE)) {
invocationRequest.updateWeakAffinity(weakAffinity);
}
if (legacyAffinity != null && !legacyAffinity.equals(Affinity.NONE)) {
attachments.put(Affinity.WEAK_AFFINITY_CONTEXT_KEY, legacyAffinity);
}
EjbLogger.EJB3_INVOCATION_LOGGER.debugf("Called receiveInvocationRequest ( bean = %s ): strong affinity = %s, weak affinity = %s \n", componentView.getComponent().getClass().getName(), strongAffinity, weakAffinity);
}
use of org.jboss.as.ejb3.component.stateful.StatefulSessionComponent in project wildfly by wildfly.
the class AbstractEJBComponentResourceDefinition method registerAttributes.
@Override
public void registerAttributes(ManagementResourceRegistration resourceRegistration) {
final AbstractEJBComponentRuntimeHandler<?> handler = componentType.getRuntimeHandler();
resourceRegistration.registerReadOnlyAttribute(COMPONENT_CLASS_NAME, handler);
resourceRegistration.registerReadOnlyAttribute(SECURITY_DOMAIN, handler);
resourceRegistration.registerReadOnlyAttribute(RUN_AS_ROLE, handler);
resourceRegistration.registerReadOnlyAttribute(DECLARED_ROLES, handler);
resourceRegistration.registerReadOnlyAttribute(TRANSACTION_TYPE, handler);
if (!componentType.equals(EJBComponentType.MESSAGE_DRIVEN)) {
resourceRegistration.registerReadOnlyAttribute(JNDI_NAMES, handler);
resourceRegistration.registerReadOnlyAttribute(BUSINESS_LOCAL, handler);
resourceRegistration.registerReadOnlyAttribute(BUSINESS_REMOTE, handler);
resourceRegistration.registerReadOnlyAttribute(ASYNC_METHODS, handler);
}
if (componentType.hasTimer()) {
resourceRegistration.registerReadOnlyAttribute(TimerAttributeDefinition.INSTANCE, handler);
resourceRegistration.registerReadOnlyAttribute(TIMEOUT_METHOD, handler);
}
if (componentType.hasPool()) {
resourceRegistration.registerReadOnlyAttribute(POOL_AVAILABLE_COUNT, handler);
resourceRegistration.registerReadOnlyAttribute(POOL_CREATE_COUNT, handler);
resourceRegistration.registerReadOnlyAttribute(POOL_NAME, handler);
resourceRegistration.registerReadOnlyAttribute(POOL_REMOVE_COUNT, handler);
resourceRegistration.registerReadOnlyAttribute(POOL_CURRENT_SIZE, handler);
resourceRegistration.registerReadWriteAttribute(POOL_MAX_SIZE, handler, handler);
}
if (componentType.equals(EJBComponentType.STATEFUL)) {
resourceRegistration.registerMetric(CACHE_SIZE, new AbstractRuntimeMetricsHandler() {
@Override
protected void executeReadMetricStep(final OperationContext context, final ModelNode operation, final EJBComponent component) {
context.getResult().set(((StatefulSessionComponent) component).getCache().getCacheSize());
}
});
resourceRegistration.registerMetric(PASSIVATED_SIZE, new AbstractRuntimeMetricsHandler() {
@Override
protected void executeReadMetricStep(final OperationContext context, final ModelNode operation, final EJBComponent component) {
context.getResult().set(((StatefulSessionComponent) component).getCache().getPassivatedCount());
}
});
resourceRegistration.registerMetric(TOTAL_SIZE, new AbstractRuntimeMetricsHandler() {
@Override
protected void executeReadMetricStep(final OperationContext context, final ModelNode operation, final EJBComponent component) {
context.getResult().set(((StatefulSessionComponent) component).getCache().getTotalSize());
}
});
}
resourceRegistration.registerMetric(EXECUTION_TIME, new AbstractRuntimeMetricsHandler() {
@Override
protected void executeReadMetricStep(final OperationContext context, final ModelNode operation, final EJBComponent component) {
context.getResult().set(component.getInvocationMetrics().getExecutionTime());
}
});
resourceRegistration.registerMetric(INVOCATIONS, new AbstractRuntimeMetricsHandler() {
@Override
protected void executeReadMetricStep(final OperationContext context, final ModelNode operation, final EJBComponent component) {
context.getResult().set(component.getInvocationMetrics().getInvocations());
}
});
resourceRegistration.registerMetric(PEAK_CONCURRENT_INVOCATIONS, new AbstractRuntimeMetricsHandler() {
@Override
protected void executeReadMetricStep(final OperationContext context, final ModelNode operation, final EJBComponent component) {
context.getResult().set(component.getInvocationMetrics().getPeakConcurrent());
}
});
resourceRegistration.registerMetric(WAIT_TIME, new AbstractRuntimeMetricsHandler() {
@Override
protected void executeReadMetricStep(final OperationContext context, final ModelNode operation, final EJBComponent component) {
context.getResult().set(component.getInvocationMetrics().getWaitTime());
}
});
resourceRegistration.registerMetric(METHODS, new AbstractRuntimeMetricsHandler() {
@Override
protected void executeReadMetricStep(final OperationContext context, final ModelNode operation, final EJBComponent component) {
context.getResult().setEmptyObject();
for (final Map.Entry<String, InvocationMetrics.Values> entry : component.getInvocationMetrics().getMethods().entrySet()) {
final InvocationMetrics.Values values = entry.getValue();
final ModelNode result = new ModelNode();
result.get("execution-time").set(values.getExecutionTime());
result.get("invocations").set(values.getInvocations());
result.get("wait-time").set(values.getWaitTime());
context.getResult().get(entry.getKey()).set(result);
}
}
});
}
Aggregations