All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ch.inftec.ju.ee.client.ServiceLocatorBuilder Maven / Gradle / Ivy

There is a newer version: 6.1-S-5
Show newest version
package ch.inftec.ju.ee.client;

import java.lang.annotation.Annotation;
import java.util.List;
import java.util.Properties;
import java.util.Set;

import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.naming.Context;
import javax.naming.InitialContext;

import org.jboss.ejb.client.ContextSelector;
import org.jboss.ejb.client.EJBClientConfiguration;
import org.jboss.ejb.client.EJBClientContext;
import org.jboss.ejb.client.PropertiesBasedEJBClientConfiguration;
import org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ch.inftec.ju.util.JuRuntimeException;
import ch.inftec.ju.util.JuUtils;
import ch.inftec.ju.util.PropertyChain;

/**
 * Builder to create ServiceLocator instances.
 * @author Martin
 *
 */
public final class ServiceLocatorBuilder {
	/**
	 * Gets a builder to create a new Remote ServiceLocator, i.e. a ServiceLocator
	 * that will perform remote JBoss lookups.
	 * 

* Uses remote-naming for the lookup. * @return Builder instance */ public static RemoteServiceLocatorBuilder buildRemote() { return new RemoteServiceLocatorBuilder(); } /** * Builds a remote service locator based on the values of configuration properties * using the default JU Property chain. * * @return Remote service locator */ public static JndiServiceLocator createRemoteByConfigurationFiles() { PropertyChain pc = JuUtils.getJuPropertyChain(); Integer port = pc.get("ju-util-ee.remote.port", Integer.class, true); Integer portOffset = pc.get("ju-util-ee.portOffset", Integer.class, true); return buildRemote() .remoteServer(pc.get("ju-util-ee.remote.host", true), port + portOffset) .appName(pc.get("ju-util-ee.remote.appName", true)) .moduleName(pc.get("ju-util-ee.remote.moduleName", true)) .createServiceLocator(); } /** * Gets a builder to create a new Local ServiceLocator, i.e. a ServiceLocator * that will perform local JNDI and CDI lookups. * @return Builder instance */ public static LocalServiceLocatorBuilder buildLocal() { return new LocalServiceLocatorBuilder(); } /** * Creates a local (CDI) ServiceLocator using the specified BeanManager implementation. *

* The BeanManager should be provided by the CDI container implementation we're using (e.g. Weld) * @param bm BeanManager used to perform the CDI lookups * @return ServiceLocator to perform local CDI lookups */ public static ServiceLocator createLocalByBeanManager(BeanManager bm) { return new LocalServiceLocatorImpl(bm); } /** * Helper class to build remote ServiceLocator instances * @author Martin * */ public static class RemoteServiceLocatorBuilder { private Logger logger = LoggerFactory.getLogger(RemoteServiceLocatorBuilder.class); private String host = "localhost"; private int port = 8080; private String appName; private String moduleName; /** * Initializes the remote service locator based on the values of configuration properties * using the default JU Property chain. * * @return Builder to adapt configuration */ public RemoteServiceLocatorBuilder initByConfigurationFiles() { PropertyChain pc = JuUtils.getJuPropertyChain(); Integer port = pc.get("ju-util-ee.remote.port", Integer.class, true); Integer portOffset = pc.get("ju-util-ee.portOffset", Integer.class, true); this.remoteServer(pc.get("ju-util-ee.remote.host", true), port + portOffset); this.appName(pc.get("ju-util-ee.remote.appName", true)); this.moduleName(pc.get("ju-util-ee.remote.moduleName", true)); return this; } /** * Sets the remote host and port for the lookup. * @param host Remote host. Default is localhost * @param port Remote port. Default is 4447 * @return This builder to allow for chaining */ public RemoteServiceLocatorBuilder remoteServer(String host, int port) { this.host = host; this.port = port; return this; } /** * Sets the application name. This is usually the name of the EAR without * the .ear suffix, e.g. 'test' for test.ear * @param appName Application name * @return This builder to allow for chaining */ public RemoteServiceLocatorBuilder appName(String appName) { this.appName = appName; return this; } /** * Sets the module name. This is usually the name of the EJB jar that contains * the EJB bean without the .jar suffix, e.g. 'test' for test.jar * @param moduleName Module name * @return This builder to allow for chaining */ public RemoteServiceLocatorBuilder moduleName(String moduleName) { this.moduleName = moduleName; return this; } /** * Creates a new RemoteServiceLocator instance with the attributes specified * to the builder. * @return JndiServiceLocator instance */ public JndiServiceLocator createServiceLocator() { try { // Set EJB Client API properties programmatically instead of using // jboss-ejb-client.properties file Properties clientProp = new Properties(); clientProp.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false"); clientProp.put("remote.connections", "default"); clientProp.put("remote.connection.default.port", Integer.toString(this.port)); // Not working if not a String... clientProp.put("remote.connection.default.host", this.host); // clientProp.put("remote.connection.default.username", "ejbUser"); // clientProp.put("remote.connection.default.password", "ejbPassword"); clientProp.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "false"); // PR-284 Don't seem to need this anymore... EJBClientConfiguration cc = new PropertiesBasedEJBClientConfiguration(clientProp); ContextSelector selector = new ConfigBasedEJBClientContextSelector(cc); EJBClientContext.setSelector(selector); logger.debug("JBoss EJB Client Properties (used for remote lookup)" + clientProp); Properties props = new Properties(); props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming"); Context ctx = new InitialContext(props); // Properties jndiProps = new Properties(); // jndiProps.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory"); // jndiProps.put(Context.PROVIDER_URL, String.format("remote://%s:%d", this.host, this.port)); // // create a context passing these properties // Context ctx = new InitialContext(jndiProps); logger.debug("Creating RemoteServiceLocator [host={}:{}, app={} / module={}" , new Object[] {this.host, this.port, this.appName, this.moduleName}); return new RemoteServiceLocatorImpl(ctx, this.appName, this.moduleName); } catch (Exception ex) { throw new JuRuntimeException("Couldn't create ServiceLocator", ex); } } } /** * Helper class to build local ServiceLocator instances * @author Martin * */ public static class LocalServiceLocatorBuilder { private String moduleName; /** * Sets the module name. This is usually the name of the EJB jar that contains * the EJB bean without the .jar suffix, e.g. 'test' for test.jar *

* Is used to look up remote interfaces in the same (local) app. * @param moduleName Module name * @return This builder to allow for chaining */ public LocalServiceLocatorBuilder moduleName(String moduleName) { this.moduleName = moduleName; return this; } /** * Creates a new LocalServiceLocatorBuilder instance with the attributes specified * to the builder. * @return ServiceLocator instance */ public ServiceLocator createServiceLocator() { return new LocalServiceLocatorImpl(this.moduleName); } } private static abstract class AbstractJndiServiceLocator implements JndiServiceLocator { protected Logger logger = LoggerFactory.getLogger(this.getClass()); private final Context ctx; protected AbstractJndiServiceLocator(Context ctx) { this.ctx = ctx; } /** * Gets the absolute JNDI name (i.e. the JNDI name that will actually be used * for the lookup) based on the submitted relative JNDI name. *

* The default implementation just returns the same JNDI * @param jndiName (Relative) JNDI name * @return Absolute JNDI name used to perform the lookup */ protected String getAbsoluteJndiName(String jndiName) { return jndiName; } @Override public T lookup(String jndiName) { String absoluteJndiName = this.getAbsoluteJndiName(jndiName); logger.debug(String.format("JNDI lookup (relative: %s, absolute: %s)", jndiName, absoluteJndiName)); try { @SuppressWarnings("unchecked") T obj = (T) this.ctx.lookup(absoluteJndiName); return obj; } catch (Exception ex) { throw new JuRuntimeException(ex); } } } private static class RemoteServiceLocatorImpl extends AbstractJndiServiceLocator { private final String appName; private final String moduleName; public RemoteServiceLocatorImpl(Context ctx, String appName, String moduleName) { super(ctx); this.appName = appName; this.moduleName = moduleName; } @Override protected String getAbsoluteJndiName(String jndiName) { // See https://github.com/wildfly/quickstart/blob/10.x/ejb-remote/client/src/main/java/org/jboss/as/quickstarts/ejb/remote/client/RemoteEJBClient.java // The app name is the application name of the deployed EJBs. This is typically the ear name // without the .ear suffix. However, the application name could be overridden in the application.xml of the // EJB deployment on the server. // Since we haven't deployed the application as a .ear, the app name for us will be an empty string final String appName = this.appName; // This is the module name of the deployed EJBs on the server. This is typically the jar name of the // EJB deployment, without the .jar suffix, but can be overridden via the ejb-jar.xml // In this example, we have deployed the EJBs in a jboss-as-ejb-remote-app.jar, so the module name is // jboss-as-ejb-remote-app final String moduleName = this.moduleName; // AS7 allows each deployment to have an (optional) distinct name. We haven't specified a distinct name for // our EJB deployment, so this is an empty string final String distinctName = ""; // We don't have this // jndiName must contain the EJB Name and the viewClassName, e.g. GreeterBean!com.acme.Greeter String absoluteJndiName = String.format("ejb:%s/%s/%s/%s" , appName , moduleName , distinctName , jndiName); return absoluteJndiName; } @Override public T lookup(Class clazz) { String lookupString = String.format("%sBean!%s" , clazz.getSimpleName() , clazz.getName()); return this.lookup(lookupString); } } private static class LocalServiceLocatorImpl extends AbstractJndiServiceLocator implements ServiceLocator { private static final String JNDI_NAME_BEAN_MANAGER = "java:comp/BeanManager"; private final String moduleName; private final BeanManager bm; private LocalServiceLocatorImpl(BeanManager bm) { super(createInitialContext()); this.moduleName = ""; this.bm = bm; } private LocalServiceLocatorImpl(String moduleName) { super(createInitialContext()); this.moduleName = moduleName == null ? "" : moduleName; this.bm = this.lookup(JNDI_NAME_BEAN_MANAGER); } private static Context createInitialContext() { try { return new InitialContext(); } catch (Exception ex) { throw new JuRuntimeException("Couldn't create InitialContext", ex); } } @Override public T lookup(Class clazz) { // java:global/ee-ear-ear/ee-ear-ejb/TestLocalBean!ch.inftec.ju.ee.test.TestLocal // java:app/ee-ear-ejb/TestLocalBean!ch.inftec.ju.ee.test.TestLocal // java:module/TestLocalBean!ch.inftec.ju.ee.test.TestLocal // java:global/ee-ear-ear/ee-ear-ejb/TestLocalBean // java:app/ee-ear-ejb/TestLocalBean // java:module/TestLocalBean String jndiName = String.format("java:app/%s/%s!%s" , this.moduleName , clazz.getSimpleName() + "Bean" , clazz.getName()); return this.lookup(jndiName); } @Override public T cdi(Class clazz) { return cdiAnno(clazz); } @Override public T cdiAnno(Class clazz, Annotation... annotations) { Set> beans = this.bm.getBeans(clazz, annotations); // We'll use resolve to get a single instance (e.g. we might have @Alternative beans and getBeans will include them Bean bean = this.bm.resolve(beans); return ServiceLocatorUtils.toInstance(this.bm, bean, clazz); } @Override public List cdiAll(Class clazz) { return cdiAllAnno(clazz); } @Override public List cdiAllAnno(Class clazz, Annotation... annotations) { Set> beans = this.bm.getBeans(clazz, annotations); return ServiceLocatorUtils.toInstances(this.bm, beans, clazz, null); } @Override public T cdiNamed(Class clazz, final String name) { Set> beans = this.bm.getBeans(clazz, ServiceLocatorUtils.createNamedAnnotation(name)); return ServiceLocatorUtils.toInstances(this.bm, beans, clazz, 1).get(0); } @Override public CdiComplexLookupBuilder cdiComplex(Class clazz) { return new CdiComplexLookupBuilder(clazz, this.bm); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy