use of org.apache.openejb.util.SuperProperties in project tomee by apache.
the class ConfigurationFactory method configureService.
/**
* This is the major piece of code that configures services.
* It merges the data from the <ServiceProvider> declaration
* with the data from the openejb.xml file (say <Resource>)
* <p/>
* The end result is a canonical (i.e. flattened) ServiceInfo
* The ServiceInfo will be of a specific type (ContainerInfo, ResourceInfo, etc)
*
* @param service Service
* @param infoType Class
* @param <T> infoType
* @return ServiceInfo
* @throws OpenEJBException On error
*/
public <T extends ServiceInfo> T configureService(org.apache.openejb.config.Service service, final Class<? extends T> infoType) throws OpenEJBException {
try {
if (infoType == null) {
throw new NullPointerException("type");
}
if (service == null) {
service = getDefaultService(infoType);
if (service == null) {
throw new OpenEJBException(messages.format("configureService.noDefaultService", infoType.getName()));
}
}
{
String template = service.getTemplate();
if (template == null) {
template = SystemInstance.get().getProperty(Template.class.getName());
}
if (template != null) {
template = unaliasPropertiesProvider(template);
// don't trim them, user wants to handle it himself, let him do it
final ObjectRecipe recipe = newObjectRecipe(template);
recipe.setProperty("serviceId", service.getId());
// note: we can also use reflection if needed to limit the dependency
Template.class.cast(recipe.create()).configure(service);
}
}
final ServiceProvider provider = getServiceProvider(service, infoType);
if (service.getId() == null) {
service.setId(provider.getId());
}
final Properties overrides = trim(getSystemProperties(overrideKey(service), provider.getService()));
final Properties serviceProperties = service.getProperties();
trim(serviceProperties);
trim(provider.getProperties());
logger.info("configureService.configuring", service.getId(), provider.getService(), provider.getId());
if (logger.isDebugEnabled()) {
for (final Map.Entry<Object, Object> entry : serviceProperties.entrySet()) {
final Object key = entry.getKey();
Object value = entry.getValue();
if (key instanceof String && "password".equalsIgnoreCase((String) key)) {
value = "<hidden>";
}
logger.debug("[" + key + "=" + value + "]");
}
for (final Map.Entry<Object, Object> entry : overrides.entrySet()) {
final Object key = entry.getKey();
Object value = entry.getValue();
if (key instanceof String && "password".equalsIgnoreCase((String) key)) {
value = "<hidden>";
}
logger.debug("Override [" + key + "=" + value + "]");
}
}
final Properties props = new SuperProperties().caseInsensitive(true);
// weird hack but sometimes we don't want default values when we want null for instance
if (serviceProperties == null || "false".equals(serviceProperties.getProperty(IGNORE_DEFAULT_VALUES_PROP, "false"))) {
props.putAll(provider.getProperties());
}
if (serviceProperties != null) {
props.putAll(serviceProperties);
}
props.putAll(overrides);
{
// force user properties last
String propertiesProvider = service.getPropertiesProvider();
if (propertiesProvider == null) {
propertiesProvider = SystemInstance.get().getProperty(PropertiesResourceProvider.class.getName());
}
if (propertiesProvider != null) {
propertiesProvider = unaliasPropertiesProvider(propertiesProvider);
// don't trim them, user wants to handle it himself, let him do it
final ObjectRecipe recipe = newObjectRecipe(propertiesProvider);
recipe.setFactoryMethod("provides");
recipe.setProperty("serviceId", service.getId());
recipe.setProperties(props);
// let user get all config
recipe.setProperty("properties", props);
final Properties p = Properties.class.cast(recipe.create());
props.putAll(p);
}
}
props.remove(IGNORE_DEFAULT_VALUES_PROP);
final T info;
try {
info = infoType.newInstance();
} catch (final Exception e) {
throw new OpenEJBException(messages.format("configureService.cannotInstantiateClass", infoType.getName()), e);
}
// some jndi adjustment
if (service.getId().startsWith("java:/")) {
service.setId(service.getId().substring("java:/".length()));
}
info.service = provider.getService();
info.types.addAll(provider.getTypes());
info.description = provider.getDescription();
info.displayName = provider.getDisplayName();
info.className = provider.getClassName();
info.factoryMethod = provider.getFactoryName();
info.id = service.getId();
info.properties = props;
info.constructorArgs.addAll(parseConstructorArgs(provider));
if (info instanceof ResourceInfo && service instanceof Resource) {
final ResourceInfo ri = ResourceInfo.class.cast(info);
final Resource resource = Resource.class.cast(service);
ri.jndiName = resource.getJndi();
ri.postConstruct = resource.getPostConstruct();
ri.preDestroy = resource.getPreDestroy();
ri.aliases.addAll(resource.getAliases());
ri.dependsOn.addAll(resource.getDependsOn());
}
if (service.getClasspath() != null && service.getClasspath().length() > 0) {
info.classpath = resolveClasspath(service.getClasspath());
}
info.classpathAPI = service.getClasspathAPI();
specialProcessing(info);
return info;
} catch (final NoSuchProviderException e) {
final String message = logger.fatal("configureService.failed", e, (null != service ? service.getId() : ""));
throw new OpenEJBException(message + ": " + e.getMessage());
} catch (final Throwable e) {
final String message = logger.fatal("configureService.failed", e, (null != service ? service.getId() : ""));
throw new OpenEJBException(message, e);
}
}
use of org.apache.openejb.util.SuperProperties in project tomee by apache.
the class BeanProperties method deploy.
@Override
public AppModule deploy(final AppModule appModule) throws OpenEJBException {
final Properties base = new Properties();
base.putAll(SystemInstance.get().getProperties());
base.putAll(appModule.getProperties());
for (final EjbModule module : appModule.getEjbModules()) {
final Properties overrides = new SuperProperties().caseInsensitive(true);
overrides.putAll(base);
overrides.putAll(module.getProperties());
if (module.getOpenejbJar() == null) {
module.setOpenejbJar(new OpenejbJar());
}
final OpenejbJar openejbJar = module.getOpenejbJar();
final Map<String, EjbDeployment> deploymentMap = openejbJar.getDeploymentsByEjbName();
for (final EnterpriseBean bean : module.getEjbJar().getEnterpriseBeans()) {
final SuperProperties properties = new SuperProperties().caseInsensitive(true);
properties.putAll(globalProperties);
final String additionalKey = bean.getEjbName();
if (additionalProperties.containsKey(additionalKey)) {
for (final Map.Entry<Object, Object> entry : additionalProperties.get(additionalKey).entrySet()) {
properties.put(entry.getKey().toString(), entry.getValue().toString());
}
}
final EjbDeployment deployment = deploymentMap.get(bean.getEjbName());
if (deployment != null) {
properties.putAll(deployment.getProperties());
deployment.getProperties().clear();
}
final String id = bean.getEjbName() + ".";
for (final Map.Entry<Object, Object> entry : overrides.entrySet()) {
final String key = entry.getKey().toString();
if (key.startsWith(id)) {
final String property = key.substring(id.length());
if (properties.containsKey(property)) {
log.debug("Overriding ejb " + bean.getEjbName() + " property " + property + "=" + entry.getValue());
} else {
log.debug("Adding ejb " + bean.getEjbName() + " property " + property + "=" + entry.getValue());
}
properties.put(property, entry.getValue());
}
}
if (properties.size() > 0) {
if (deployment == null) {
final EjbDeployment ejbDeployment = openejbJar.addEjbDeployment(bean);
ejbDeployment.getProperties().putAll(properties);
} else {
deployment.getProperties().putAll(properties);
}
}
}
}
// cleanup
additionalProperties.clear();
globalProperties.clear();
return appModule;
}
use of org.apache.openejb.util.SuperProperties in project tomee by apache.
the class DataSourceFactory method asProperties.
private static Properties asProperties(final String definition) throws IOException {
final SuperProperties properties = new SuperProperties();
properties.caseInsensitive(true);
properties.putAll(IO.readProperties(IO.read(definition), new Properties()));
return properties;
}
use of org.apache.openejb.util.SuperProperties in project tomee by apache.
the class ServiceProvider method getProperties.
/**
* Gets the value of the properties property.
* <p/>
* <p/>
* This accessor method returns a reference to the live Properties Object,
* not a snapshot. Therefore any modification you make to the
* returned Properties will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the properties property.
* <p/>
* <p/>
* For example, to add a new value, do as follows:
* <pre>
* getProperties().setProperty(key, value);
* </pre>
* <p/>
* <p/>
* <p/>
*/
public Properties getProperties() {
if (properties == null) {
final SuperProperties sp = new SuperProperties();
sp.setCaseInsensitive(true);
properties = sp;
}
return properties;
}
use of org.apache.openejb.util.SuperProperties in project tomee by apache.
the class Assembler method doCreateResource.
private Object doCreateResource(final Collection<ServiceInfo> infos, final ResourceInfo serviceInfo) throws OpenEJBException {
// do it early otherwise we can loose it
final String skipPropertiesFallback = (String) serviceInfo.properties.remove("SkipPropertiesFallback");
final ObjectRecipe serviceRecipe = createRecipe(infos, serviceInfo);
final boolean properties = PropertiesFactory.class.getName().equals(serviceInfo.className);
if ("false".equalsIgnoreCase(serviceInfo.properties.getProperty("SkipImplicitAttributes", "false")) && !properties) {
serviceRecipe.setProperty("transactionManager", transactionManager);
serviceRecipe.setProperty("ServiceId", serviceInfo.id);
}
serviceInfo.properties.remove("SkipImplicitAttributes");
// if custom instance allow to skip properties fallback to avoid to set unexpectedly it - connectionProps of DBs
final AtomicReference<Properties> injectedProperties = new AtomicReference<>();
if (!"true".equalsIgnoreCase(skipPropertiesFallback)) {
serviceRecipe.setProperty("properties", new UnsetPropertiesRecipe() {
@Override
protected Object internalCreate(final Type expectedType, final boolean lazyRefAllowed) throws ConstructionException {
final Map<String, Object> original = serviceRecipe.getUnsetProperties();
final Properties properties = new SuperProperties() {
@Override
public Object remove(final Object key) {
// avoid to log them then
original.remove(key);
return super.remove(key);
}
}.caseInsensitive(// keep our nice case insensitive feature
true);
for (final Map.Entry<String, Object> entry : original.entrySet()) {
properties.put(entry.getKey(), entry.getValue());
}
injectedProperties.set(properties);
return properties;
}
});
} else {
// this is not the best fallback we have but since it is super limited it is acceptable
final Map<String, Object> unsetProperties = serviceRecipe.getUnsetProperties();
injectedProperties.set(new Properties() {
@Override
public String getProperty(final String key) {
final Object obj = unsetProperties.get(key);
return String.class.isInstance(obj) ? String.valueOf(obj) : null;
}
@Override
public Set<String> stringPropertyNames() {
return unsetProperties.keySet();
}
@Override
public Set<Object> keySet() {
//noinspection unchecked
return Set.class.cast(unsetProperties.keySet());
}
@Override
public synchronized boolean containsKey(final Object key) {
return getProperty(String.valueOf(key)) != null;
}
});
}
if (serviceInfo.types.contains("DataSource") || serviceInfo.types.contains(DataSource.class.getName())) {
final Properties props = PropertyPlaceHolderHelper.simpleHolds(serviceInfo.properties);
if (serviceInfo.properties.containsKey("Definition")) {
final Object encoding = serviceInfo.properties.remove("DefinitionEncoding");
try {
// we catch classcast etc..., if it fails it is not important
final InputStream is = new ByteArrayInputStream(serviceInfo.properties.getProperty("Definition").getBytes(encoding != null ? encoding.toString() : "ISO-8859-1"));
final Properties p = new SuperProperties();
IO.readProperties(is, p);
for (final Entry<Object, Object> entry : p.entrySet()) {
final String key = entry.getKey().toString();
if (!props.containsKey(key) && !(key.equalsIgnoreCase("url") && props.containsKey("JdbcUrl"))) {
// with @DataSource we can get both, see org.apache.openejb.config.ConvertDataSourceDefinitions.rawDefinition()
props.put(key, entry.getValue());
}
}
} catch (final Exception e) {
// ignored
}
}
serviceRecipe.setProperty("Definition", PropertiesHelper.propertiesToString(props));
}
// else: any other kind of resource relying on it? shouldnt be
replaceResourceAdapterProperty(serviceRecipe);
ClassLoader loader = Thread.currentThread().getContextClassLoader();
boolean customLoader = false;
try {
if (serviceInfo.classpath != null && serviceInfo.classpath.length > 0) {
final URL[] urls = new URL[serviceInfo.classpath.length];
for (int i = 0; i < serviceInfo.classpath.length; i++) {
urls[i] = serviceInfo.classpath[i].toURL();
}
loader = new URLClassLoaderFirst(urls, loader);
customLoader = true;
serviceRecipe.setProperty("OpenEJBResourceClasspath", "true");
}
} catch (final MalformedURLException e) {
throw new OpenEJBException("Unable to create a classloader for " + serviceInfo.id, e);
}
if (!customLoader && serviceInfo.classpathAPI != null) {
throw new IllegalArgumentException("custom-api provided but not classpath used for " + serviceInfo.id);
}
Object service = serviceRecipe.create(loader);
if (customLoader) {
final Collection<Class<?>> apis;
if (serviceInfo.classpathAPI == null) {
apis = new ArrayList<Class<?>>(Arrays.asList(service.getClass().getInterfaces()));
} else {
final String[] split = serviceInfo.classpathAPI.split(" *, *");
apis = new ArrayList<>(split.length);
final ClassLoader apiLoader = Thread.currentThread().getContextClassLoader();
for (final String fqn : split) {
try {
apis.add(apiLoader.loadClass(fqn));
} catch (final ClassNotFoundException e) {
throw new IllegalArgumentException(fqn + " not usable as API for " + serviceInfo.id, e);
}
}
}
if (apis.size() - (apis.contains(Serializable.class) ? 1 : 0) - (apis.contains(Externalizable.class) ? 1 : 0) > 0) {
service = Proxy.newProxyInstance(loader, apis.toArray(new Class<?>[apis.size()]), new ClassLoaderAwareHandler(null, service, loader));
}
// else proxy would be useless
}
serviceInfo.unsetProperties = injectedProperties.get();
// Java Connector spec ResourceAdapters and ManagedConnectionFactories need special activation
if (service instanceof ResourceAdapter) {
final ResourceAdapter resourceAdapter = (ResourceAdapter) service;
// Create a thead pool for work manager
final int threadPoolSize = getIntProperty(serviceInfo.properties, "threadPoolSize", 30);
final Executor threadPool;
if (threadPoolSize <= 0) {
logger.warning("Thread pool for '" + serviceInfo.id + "' is (unbounded), consider setting a size using: " + serviceInfo.id + ".QueueSize=[size]");
threadPool = Executors.newCachedThreadPool(new DaemonThreadFactory(serviceInfo.id + "-worker-"));
} else {
threadPool = new ExecutorBuilder().size(threadPoolSize).prefix(serviceInfo.id).threadFactory(new DaemonThreadFactory(serviceInfo.id + "-worker-")).build(new Options(serviceInfo.properties, SystemInstance.get().getOptions()));
logger.info("Thread pool size for '" + serviceInfo.id + "' is (" + threadPoolSize + ")");
}
// WorkManager: the resource adapter can use this to dispatch messages or perform tasks
final WorkManager workManager;
if (GeronimoTransactionManager.class.isInstance(transactionManager)) {
final GeronimoTransactionManager geronimoTransactionManager = (GeronimoTransactionManager) transactionManager;
final TransactionContextHandler txWorkContextHandler = new TransactionContextHandler(geronimoTransactionManager);
// use id as default realm name if realm is not specified in service properties
final String securityRealmName = getStringProperty(serviceInfo.properties, "realm", serviceInfo.id);
final SecurityContextHandler securityContextHandler = new SecurityContextHandler(securityRealmName);
final HintsContextHandler hintsContextHandler = new HintsContextHandler();
final Collection<WorkContextHandler> workContextHandlers = new ArrayList<WorkContextHandler>();
workContextHandlers.add(txWorkContextHandler);
workContextHandlers.add(securityContextHandler);
workContextHandlers.add(hintsContextHandler);
workManager = new GeronimoWorkManager(threadPool, threadPool, threadPool, workContextHandlers);
} else {
workManager = new SimpleWorkManager(threadPool);
}
// BootstrapContext: wraps the WorkMananger and XATerminator
final BootstrapContext bootstrapContext;
if (transactionManager instanceof GeronimoTransactionManager) {
bootstrapContext = new GeronimoBootstrapContext(GeronimoWorkManager.class.cast(workManager), (GeronimoTransactionManager) transactionManager, (GeronimoTransactionManager) transactionManager);
} else if (transactionManager instanceof XATerminator) {
bootstrapContext = new SimpleBootstrapContext(workManager, (XATerminator) transactionManager);
} else {
bootstrapContext = new SimpleBootstrapContext(workManager);
}
// start the resource adapter
try {
logger.debug("createResource.startingResourceAdapter", serviceInfo.id, service.getClass().getName());
resourceAdapter.start(bootstrapContext);
} catch (final ResourceAdapterInternalException e) {
throw new OpenEJBException(e);
}
final Map<String, Object> unset = serviceRecipe.getUnsetProperties();
unset.remove("threadPoolSize");
logUnusedProperties(unset, serviceInfo);
service = new ResourceAdapterReference(resourceAdapter, threadPool, OPENEJB_RESOURCE_JNDI_PREFIX + serviceInfo.id);
} else if (service instanceof ManagedConnectionFactory) {
final ManagedConnectionFactory managedConnectionFactory = (ManagedConnectionFactory) service;
// connection manager is constructed via a recipe so we automatically expose all cmf properties
final ObjectRecipe connectionManagerRecipe = new ObjectRecipe(GeronimoConnectionManagerFactory.class, "create");
connectionManagerRecipe.allow(Option.CASE_INSENSITIVE_PROPERTIES);
connectionManagerRecipe.allow(Option.IGNORE_MISSING_PROPERTIES);
connectionManagerRecipe.setAllProperties(serviceInfo.properties);
connectionManagerRecipe.setProperty("name", serviceInfo.id);
connectionManagerRecipe.setProperty("mcf", managedConnectionFactory);
// standard properties
connectionManagerRecipe.setProperty("transactionManager", transactionManager);
ClassLoader classLoader = loader;
if (classLoader == null) {
classLoader = getClass().getClassLoader();
}
if (classLoader == null) {
classLoader = ClassLoader.getSystemClassLoader();
}
connectionManagerRecipe.setProperty("classLoader", classLoader);
logger.getChildLogger("service").info("createResource.createConnectionManager", serviceInfo.id, service.getClass().getName());
// create the connection manager
final ConnectionManager connectionManager = (ConnectionManager) connectionManagerRecipe.create();
if (connectionManager == null) {
throw new OpenEJBRuntimeException(messages.format("assembler.invalidConnectionManager", serviceInfo.id));
}
final Map<String, Object> unsetA = serviceRecipe.getUnsetProperties();
final Map<String, Object> unsetB = connectionManagerRecipe.getUnsetProperties();
final Map<String, Object> unset = new HashMap<String, Object>();
for (final Entry<String, Object> entry : unsetA.entrySet()) {
if (unsetB.containsKey(entry.getKey())) {
unset.put(entry.getKey(), entry.getValue());
}
}
// service becomes a ConnectorReference which merges connection manager and mcf
service = new ConnectorReference(connectionManager, managedConnectionFactory);
// init cm if needed
final Object eagerInit = unset.remove("eagerInit");
if (eagerInit != null && eagerInit instanceof String && "true".equalsIgnoreCase((String) eagerInit) && connectionManager instanceof AbstractConnectionManager) {
try {
((AbstractConnectionManager) connectionManager).doStart();
try {
final Object cf = managedConnectionFactory.createConnectionFactory(connectionManager);
if (cf instanceof ConnectionFactory) {
final Connection connection = ((ConnectionFactory) cf).getConnection();
connection.getMetaData();
connection.close();
}
} catch (final Exception e) {
// no-op: just to force eager init of pool
}
} catch (final Exception e) {
logger.warning("Can't start connection manager", e);
}
}
logUnusedProperties(unset, serviceInfo);
} else if (service instanceof DataSource) {
ClassLoader classLoader = loader;
if (classLoader == null) {
classLoader = getClass().getClassLoader();
}
final ImportSql importer = new ImportSql(classLoader, serviceInfo.id, (DataSource) service);
if (importer.hasSomethingToImport()) {
importer.doImport();
}
final ObjectRecipe recipe = DataSourceFactory.forgetRecipe(service, serviceRecipe);
if (recipe != serviceRecipe || !serviceInfo.properties.containsKey("XaDataSource")) {
logUnusedProperties(recipe, serviceInfo);
}
// else logged on xadatasource itself
final Properties prop = serviceInfo.properties;
String url = prop.getProperty("JdbcUrl", prop.getProperty("url"));
if (url == null) {
url = prop.getProperty("jdbcUrl");
}
if (url == null) {
logger.debug("Unable to find url for " + serviceInfo.id + " will not monitor it");
} else {
final String host = extractHost(url);
if (host != null) {
remoteResourceMonitor.addHost(host);
remoteResourceMonitor.registerIfNot();
}
}
} else if (!Properties.class.isInstance(service)) {
if (serviceInfo.unsetProperties == null || isTemplatizedResource(serviceInfo)) {
logUnusedProperties(serviceRecipe, serviceInfo);
}
// else wait post construct
}
final ResourceCreated event = new ResourceCreated(service, serviceInfo.id);
SystemInstance.get().fireEvent(event);
return event.getReplacement() == null ? service : event.getReplacement();
}
Aggregations