CDI EJB-Remote Context for wildfly
This article shows how ejb remote clients can be configured and connected in a more dynamic way.
- the standard way with jboss-ejb-client.properties
https://docs.jboss.org/author/display/WFLY8/Remote+EJB+invocations+via+JNDI+-+EJB+client+API+or+remote-naming+project - a programmatic way
http://alexbischoftechwriteups.blogspot.de/2013/11/jboss-as-7-programmatic-ejb-remote.html
The Problem
You have an application for two (or more) tenants which are identical but are deployed on different machines. Customers should be able to switch between those tenants without restarting the application. Additionally the code itself should not depend on tenant specific code.
As far as i know this would be necessary with the standard approach (jboss-ejb-client.properties) given above.
A Solution
After some consideration i have identified the following five components which are needed to implement this feature.
- Component that creates WildFly ejb remote connections
- Component that produces the JNDI-Context
- Component that holds the selected tenant-key for the client
- Component that maps the tenant-keys to connection properties
- CDI-Modul Qualifier
Putting them together leads to the following UML:
To keep the example as simple as possible i have decided to use the ejb-remote-quickstart example and extend it with the jndicontext module. The current implementation uses a simple property file which holds the following data.
tenant1.host=localhost tenant1.port=8080 tenant1.username=test tenant1.password=test tenant1.noanonymous=false tenant2.host=192.168.0.104 tenant2.port=8080 tenant2.username=test tenant2.password=test tenant2.noanonymous=false
The Fazit
The resulting service locator just has to use the JndiSession (in this example the RemoteEJBClient) which technically holds the tenant key and can be set from the GUI.
public class RemoteEJBClient { @Inject @JndiContextAnno Instance<Context> contextInstance; @Inject JndiSession jndiSession; //...snip private RemoteCalculator lookupRemoteStatelessCalculator() throws NamingException { Context context = contextInstance.get(); //...snip } } public class CDIBootStrapper { public static void main(String[] args) throws Exception { WeldContainer weld = new Weld().initialize(); RemoteEJBClient client = weld.instance().select(RemoteEJBClient.class).get(); client.getJndiSession().setTenantKey("tenant1"); client.invokeStatelessBean(); client.getJndiSession().setTenantKey("tenant2"); client.invokeStatelessBean(); } )
The sources can be found on https://bitbucket.org/abischof/injectablejndicontext.
Have fun coding... ;)
Kommentare
Kommentar veröffentlichen