TomEE 2 got two new interesting features (in particular in enterprises) to configure resources: default placeholder values and properties-provider.
Placeholder
TomEE supports placeholding in resources, for instance:
<Resource id="..."> JdbcUrl = ${my.url} JdbcDriver = ${my.driver} </Resource>
This is great but what happen if my.url or my.driver is not specified? You get the url my.url. You can of course set the real/test url:
<Resource id="..."> JdbcUrl = ${jdbc:h2:mem:xx} JdbcDriver = ${my.driver} </Resource>
but then you need to set -Djdbc:h2:mem:xx=jdbc:mysql://localhost:3306/xx which is a bit weird (in particular if you didn’t develop the application).
To avoid it we activated default values in placeholders with the separator (configurable) “:-“:
<Resource id="..."> JdbcUrl = ${my.url:-jdbc:h2:mem:xx} JdbcDriver = ${my.driver} MinIdle = ${my.minIdle:-3} </Resource>
This makes the configuration more readable :).
PS: if you want to use a simple “:” instead of “:-” which was choosen to be aligned with commons-lang3 default, just set as system property openejb.placeholder.delimiter to ‘:’
Properties provider
Resource properties values are set from resource properties. Main issue is in enterprises you often have a system to read/store them (Database, NoSQL, …..).
To allow to integrate with it you can now set properties-provider attribute on resources:
<Resource id="..." properties-provider="com.foo.MyPropertiesReader" />
For known types (DataSource for instance) default values will still be provided but all properties are overwritten by MyPropertiesReader.
MyPropertiesReader can either implements org.apache.openejb.api.resource.PropertiesResourceProvider or just defines a provides method returning Properties.
Another interesting thing is this provider can be configured with properties of the resource or get injected all properties if it has a setProperties(Properties) method.
Here is a sample:
public class MyPropertiesReader { private Properties properties; private String resourceCompanyId; public void setProperties(final Properties p) { this.p = p; } public Properties provides() { // change properties reading what you need using resourceCompanyId properties.remove("resourceCompanyId"); // not a resource config, remove it return properties; } }
and the configuration could be:
<Resource id="myResource" properties-provider="com.foo.MyPropertiesReader"> resourceCompanyId = 141186 resourceAttribute = value </Resource>