Passar Contexto de Aplicativo Padrão para o EJB Remoto de Forma Anônima

Eu tenho um cenário complicado, para o qual eu não tenho idéia de como ir:

Eu tenho meu ejbs em execução em um servidor remoto.

E meu aplicativo da web em execução em um servidor diferente.

Eu tenho um ApplicationContext, que será diferente com base no domínio, idioma, país etc.

Eu gostaria que esse contexto de aplicativo fosse passado para o EJB remoto anonimamente, de tal forma que os desenvolvedores não precisassem invocar todos os seus pedidos de backend com o ApplicationContext como um parâmetro.

Este é o scenarion, diz que eu tenho um EJB sem estado remoto:

@Stateless public class MyStateless implements MyStatelessRemote{ //The application context that needs to be supplied form the front-end @Inject //probably define a producer method to always supply a new one. private ApplicationContext applicationContext; public void doCheckSomething(final MySomethingData data){} } 

E no frontend:

 @SessionScoped @Named public class MyController implements Serializable{ @EJB private MyStatelessRemote statelessRemote //The current application/session context to be passed to the Stateless ejb on every invocation. @Inject private ApplicationContext executionContext; public void doSomeOrderOrSomethingSimilar(){ //At this point, the current application context needs to be supplied to the remote EJB //Which it may use to check on order validity based on configurations such as country //language etc. statelessRemote.doCheckSomething(mySomething); } } 

Com mais de 20 EJBS e cada um com uma média de 8 a 10 methods, e considerando a probabilidade de que quase todos os ejb precisem conhecer o contexto de execução do chamador, é possível analisar o contexto de execução atual, por meio de configuração ou de outra forma ejb durante a invocação de qualquer método?

  1. Estou usando o Wildfly8 com o eJb3.1 remoto, CDI1.1, JSF2.2
  2. O contexto do aplicativo pode mudar quando, por exemplo, o usuário altera seu idioma

EDITAR:

Eu estou procurando por algo semelhante aos interceptadores de input e saída de serviço da Web.

O que você está descrevendo não é possível usando CDI / EJB, sem passar parâmetros para o seu EJB remoto.

Depois de alguns meses trabalhando no servidor jboss / wildfly, eu finalmente encontrei uma distância para conseguir essa funcionalidade:

Código do lado do cliente: (Baseado no jboss ejbclient)

 package com.mycompany.view.service.wildfly.invocationcontext; import com.mycompany.ejb.internal.MyCompanyAccount; import com.mycompany.view.service.account.LoggedInAccount; import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.PostConstruct; import javax.ejb.Singleton; import javax.ejb.Startup; import javax.enterprise.inject.Instance; import javax.inject.Inject; import org.jboss.ejb.client.AttachmentKey; import org.jboss.ejb.client.EJBClientContext; import org.jboss.ejb.client.EJBClientInterceptor; import org.jboss.ejb.client.EJBClientInvocationContext; import static com.mycompany.management.wildfly.invocationcontext.MyCompanyInvocationContextKey.MYCOMPANY_ACCOUNT_NUMBER; /** * Registers itself as a jboss client interceptor. * @author marembo */ @Singleton @Startup public class MyCompanyInvocationContextInterceptor implements EJBClientInterceptor { private static final Logger LOG = Logger.getLogger(MyCompanyInvocationContextInterceptor.class.getName()); private static final AttachmentKey MYCOMPANY_ACCOUNT_NUMBER_KEY = new AttachmentKey<>(); @Inject @LoggedInAccount private Instance loggedInAccount; @PostConstruct void registerSelf() { EJBClientContext.requireCurrent().registerInterceptor(0, this); } @Override public void handleInvocation(final EJBClientInvocationContext ejbcic) throws Exception { LOG.log(Level.INFO, "Intercepting invocation on: {0}", ejbcic.getInvokedMethod()); final EJBClientContext clientContext = ejbcic.getClientContext(); if (!loggedInAccount.isUnsatisfied()) { final MyCompanyAccount mycompanyAccount = loggedInAccount.get(); if (mycompanyAccount != null) { final Long accountNumber = mycompanyAccount.getAccountNumber(); clientContext.putAttachment(MYCOMPANY_ACCOUNT_NUMBER_KEY, accountNumber); } } ejbcic.getContextData().put(MYCOMPANY_ACCOUNT_NUMBER, "348347878483"); ejbcic.sendRequest(); } @Override public Object handleInvocationResult(final EJBClientInvocationContext ejbcic) throws Exception { return ejbcic.getResult(); } } 

No lado do servidor, eu registro um interceptor global:

 package com.mycompany.management.wildfly.extension; import com.mycompany.management.facade.account.MyCompanyAccountFacade; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Resource; import javax.ejb.EJB; import javax.ejb.EJBContext; import javax.interceptor.AroundInvoke; import javax.interceptor.InvocationContext; /** * Default interceptor does not require @Interceptor * @author marembo */ public class MyCompanyInvocationContextReceiver { private static final Logger LOG = Logger.getLogger(MyCompanyInvocationContextReceiver.class.getName()); @Resource private EJBContext ejbContext; @EJB private MyCompanyInvocationContext mycompanyInvocationContext; @EJB private MyCompanyAccountFacade mycompanyAccountFacade; @AroundInvoke public Object setMyCompanyAccount(final InvocationContext invocationContext) throws Exception { final Map contextData = ejbContext.getContextData(); LOG.log(Level.INFO, "EJBContext data: {0}", contextData); LOG.log(Level.INFO, "InvocationContext data: {0}", invocationContext.getContextData()); return invocationContext.proceed(); } } 

e o ejb-jar.xml:

     com.mycompany.management.wildfly.extension.MyCompanyInvocationContextReceiver     * com.mycompany.management.wildfly.extension.MyCompanyInvocationContextReceiver    

Conforme indicado no interceptador do lado do servidor, você pode obter os dados enviados pelo cliente a partir do InvocationContext ou do EJBContext.