Search in sources :

Example 1 with Affinity

use of org.jboss.ejb.client.Affinity in project wildfly by wildfly.

the class AssociationImpl method receiveInvocationRequest.

@Override
public CancelHandle receiveInvocationRequest(@NotNull final InvocationRequest invocationRequest) {
    final EJBIdentifier ejbIdentifier = invocationRequest.getEJBIdentifier();
    final String appName = ejbIdentifier.getAppName();
    final String moduleName = ejbIdentifier.getModuleName();
    final String distinctName = ejbIdentifier.getDistinctName();
    final String beanName = ejbIdentifier.getBeanName();
    final EjbDeploymentInformation ejbDeploymentInformation = findEJB(appName, moduleName, distinctName, beanName);
    if (ejbDeploymentInformation == null) {
        invocationRequest.writeNoSuchEJB();
        return CancelHandle.NULL;
    }
    final ClassLoader classLoader = ejbDeploymentInformation.getDeploymentClassLoader();
    final InvocationRequest.Resolved requestContent;
    try {
        requestContent = invocationRequest.getRequestContent(classLoader);
    } catch (IOException | ClassNotFoundException e) {
        invocationRequest.writeException(new EJBException(e));
        return CancelHandle.NULL;
    }
    final Map<String, Object> attachments = requestContent.getAttachments();
    final EJBLocator<?> ejbLocator = requestContent.getEJBLocator();
    final String viewClassName = ejbLocator.getViewType().getName();
    if (!ejbDeploymentInformation.isRemoteView(viewClassName)) {
        invocationRequest.writeWrongViewType();
        return CancelHandle.NULL;
    }
    final ComponentView componentView = ejbDeploymentInformation.getView(viewClassName);
    final Method invokedMethod = findMethod(componentView, invocationRequest.getMethodLocator());
    if (invokedMethod == null) {
        invocationRequest.writeNoSuchMethod();
        return CancelHandle.NULL;
    }
    final boolean isAsync = componentView.isAsynchronous(invokedMethod);
    final boolean oneWay = isAsync && invokedMethod.getReturnType() == void.class;
    if (oneWay) {
        // send immediate response
        requestContent.writeInvocationResult(null);
    }
    final CancellationFlag cancellationFlag = new CancellationFlag();
    Runnable runnable = () -> {
        if (!cancellationFlag.runIfNotCancelled()) {
            if (!oneWay)
                invocationRequest.writeCancelResponse();
            return;
        }
        // invoke the method
        final Object result;
        // the Remoting connection that is set here is only used for legacy purposes
        SecurityActions.remotingContextSetConnection(invocationRequest.getProviderInterface(Connection.class));
        try {
            result = invokeMethod(componentView, invokedMethod, invocationRequest, requestContent, cancellationFlag);
        } catch (EJBComponentUnavailableException ex) {
            // if the EJB is shutting down when the invocation was done, then it's as good as the EJB not being available. The client has to know about this as
            // a "no such EJB" failure so that it can retry the invocation on a different node if possible.
            EjbLogger.EJB3_INVOCATION_LOGGER.debugf("Cannot handle method invocation: %s on bean: %s due to EJB component unavailability exception. Returning a no such EJB available message back to client", invokedMethod, beanName);
            if (!oneWay)
                invocationRequest.writeNoSuchEJB();
            return;
        } catch (ComponentIsStoppedException ex) {
            EjbLogger.EJB3_INVOCATION_LOGGER.debugf("Cannot handle method invocation: %s on bean: %s due to EJB component stopped exception. Returning a no such EJB available message back to client", invokedMethod, beanName);
            if (!oneWay)
                invocationRequest.writeNoSuchEJB();
            return;
        // TODO should we write a specifc response with a specific protocol letting client know that server is suspending?
        } catch (CancellationException ex) {
            if (!oneWay)
                invocationRequest.writeCancelResponse();
            return;
        } catch (Exception exception) {
            if (oneWay)
                return;
            // write out the failure
            final Exception exceptionToWrite;
            final Throwable cause = exception.getCause();
            if (componentView.getComponent() instanceof StatefulSessionComponent && exception instanceof EJBException && cause != null) {
                if (!(componentView.getComponent().isRemotable(cause))) {
                    // Avoid serializing the cause of the exception in case it is not remotable
                    // Client might not be able to deserialize and throw ClassNotFoundException
                    exceptionToWrite = new EJBException(exception.getLocalizedMessage());
                } else {
                    exceptionToWrite = exception;
                }
            } else {
                exceptionToWrite = exception;
            }
            invocationRequest.writeException(exceptionToWrite);
            return;
        }
        // invocation was successful
        if (!oneWay)
            try {
                // attach any weak affinity if available
                Affinity weakAffinity = null;
                if (ejbLocator.isStateful() && componentView.getComponent() instanceof StatefulSessionComponent) {
                    final StatefulSessionComponent statefulSessionComponent = (StatefulSessionComponent) componentView.getComponent();
                    weakAffinity = getWeakAffinity(statefulSessionComponent, ejbLocator.asStateful());
                } else if (componentView.getComponent() instanceof StatelessSessionComponent) {
                    final StatelessSessionComponent statelessSessionComponent = (StatelessSessionComponent) componentView.getComponent();
                    weakAffinity = statelessSessionComponent.getWeakAffinity();
                }
                if (weakAffinity != null && !weakAffinity.equals(Affinity.NONE)) {
                    attachments.put(Affinity.WEAK_AFFINITY_CONTEXT_KEY, weakAffinity);
                }
                requestContent.writeInvocationResult(result);
            } catch (Throwable ioe) {
                EjbLogger.REMOTE_LOGGER.couldNotWriteMethodInvocation(ioe, invokedMethod, beanName, appName, moduleName, distinctName);
            }
    };
    // invoke the method and write out the response, possibly on a separate thread
    execute(invocationRequest, runnable, isAsync);
    return cancellationFlag::cancel;
}
Also used : ComponentIsStoppedException(org.jboss.as.ee.component.ComponentIsStoppedException) StatelessSessionComponent(org.jboss.as.ejb3.component.stateless.StatelessSessionComponent) EJBComponentUnavailableException(org.jboss.as.ejb3.component.EJBComponentUnavailableException) EjbDeploymentInformation(org.jboss.as.ejb3.deployment.EjbDeploymentInformation) InvocationRequest(org.jboss.ejb.server.InvocationRequest) StatefulSessionComponent(org.jboss.as.ejb3.component.stateful.StatefulSessionComponent) IOException(java.io.IOException) Method(java.lang.reflect.Method) EJBComponentUnavailableException(org.jboss.as.ejb3.component.EJBComponentUnavailableException) CancellationException(java.util.concurrent.CancellationException) EJBException(javax.ejb.EJBException) ComponentIsStoppedException(org.jboss.as.ee.component.ComponentIsStoppedException) IOException(java.io.IOException) ComponentView(org.jboss.as.ee.component.ComponentView) CancellationException(java.util.concurrent.CancellationException) Affinity(org.jboss.ejb.client.Affinity) CancellationFlag(org.jboss.as.ejb3.component.interceptors.CancellationFlag) EJBException(javax.ejb.EJBException) EJBIdentifier(org.jboss.ejb.client.EJBIdentifier)

Aggregations

IOException (java.io.IOException)1 Method (java.lang.reflect.Method)1 CancellationException (java.util.concurrent.CancellationException)1 EJBException (javax.ejb.EJBException)1 ComponentIsStoppedException (org.jboss.as.ee.component.ComponentIsStoppedException)1 ComponentView (org.jboss.as.ee.component.ComponentView)1 EJBComponentUnavailableException (org.jboss.as.ejb3.component.EJBComponentUnavailableException)1 CancellationFlag (org.jboss.as.ejb3.component.interceptors.CancellationFlag)1 StatefulSessionComponent (org.jboss.as.ejb3.component.stateful.StatefulSessionComponent)1 StatelessSessionComponent (org.jboss.as.ejb3.component.stateless.StatelessSessionComponent)1 EjbDeploymentInformation (org.jboss.as.ejb3.deployment.EjbDeploymentInformation)1 Affinity (org.jboss.ejb.client.Affinity)1 EJBIdentifier (org.jboss.ejb.client.EJBIdentifier)1 InvocationRequest (org.jboss.ejb.server.InvocationRequest)1