I did what you are suggesting before posting my request.
Please find my code and see if you could identify what is wrong with my code
(it is a simple example)
public class DeterminedRouter extends AbstractRouter implements Serializable
{
private static final long serialVersionUID = -4973022035526665822L;
final Logger log = LoggerFactory.getLogger(this.getClass());
private String dataSourceNames;
private String defaultDataSourceName;
private Map<String, DataSource> dataSources = null;
private ThreadLocal<DataSource> currentDataSource = new
ThreadLocal<DataSource>();
/**
*
*/
public DeterminedRouter() {
}
/**
* @param datasourceList datasource resource name, separator is a space
*/
public void setDataSourceNames(String datasourceList) {
dataSourceNames = datasourceList;
}
/**
* lookup datasource in openejb resources
*/
private void init() {
dataSources = new ConcurrentHashMap<String, DataSource>();
for (String ds : dataSourceNames.split(" ")) {
try {
Object o = getOpenEJBResource(ds);
if (o instanceof DataSource) {
dataSources.put(ds, DataSource.class.cast(o));
}
}catch (NamingException e) {
e.printStackTrace();
}
}
}
/**
* @return the user selected data source if it is set
* or the default one
* @throws IllegalArgumentException if the data source is not found
*/
@Override
public DataSource getDataSource() {
// lazy init of routed datasources
if (dataSources == null) {
init();
}
// if no datasource is selected use the default one
if (currentDataSource.get() == null) {
if (dataSources.containsKey(defaultDataSourceName)) {
return dataSources.get(defaultDataSourceName);
} else {
throw new IllegalArgumentException("you have to specify at
least one datasource");
}
}
// the developper set the datasource to use
return currentDataSource.get();
}
/**
*
* @param datasourceName data source name
*/
public void setDataSource(String datasourceName) {
if (dataSources == null) {
init();
}
if (!dataSources.containsKey(datasourceName)) {
throw new IllegalArgumentException("data source called " +
datasourceName + " can't be found.");
}
DataSource ds = dataSources.get(datasourceName);
currentDataSource.set(ds);
}
/**
* reset the data source
*/
public void clear() {
currentDataSource.remove();
}
public void setDefaultDataSourceName(String name) {
this.defaultDataSourceName = name;
}
}
////////////////////////////////////////////////////////////////
@Stateless
public class RoutedPersister implements Serializable {
private static final long serialVersionUID = -4630430944530409705L;
final Logger log = LoggerFactory.getLogger(this.getClass());
@Resource(name="TsRouter", type = DeterminedRouter.class)
private DeterminedRouter router;
@PersistenceContext(unitName = "router")
private EntityManager em;
private RoutedPersister routedPersister;
private String[] databases;
private Properties properties;
/**
*
*/
public RoutedPersister() {
}
@PostConstruct
public void init(){
try{
databases = new String[]{"db1", "db2", "db3"};
properties = new Properties();
properties.setProperty(Context.INITIAL_CONTEXT_FACTORY,
LocalInitialContextFactory.class.getName());
// resources
// datasources
for (int i = 1; i <= databases.length; i++) {
String dbName = databases[i - 1];
properties.setProperty(dbName,
"new://Resource?type=DataSource");
dbName += ".";
properties.setProperty(dbName + "JdbcDriver",
"com.mysql.jdbc.Driver");
properties.setProperty(dbName + "JdbcUrl",
"jdbc:mysql://domain.com:3306/" + i);
properties.setProperty(dbName + "UserName", "username");
properties.setProperty(dbName + "Password", "password");
properties.setProperty(dbName + "JtaManaged", "true");
}
// router
properties.setProperty("TsRouter",
"new://Resource?provider=org.router:DeterminedRouter&type=" +
DeterminedRouter.class.getName());
properties.setProperty("TsRouter.DatasourceNames", "db1 db2
db3");
properties.setProperty("TsRouter.DefaultDataSourceName",
"db1");
// routed datasource
properties.setProperty("Routed Datasource",
"new://Resource?provider=RoutedDataSource&type=" + Router.class.getName());
properties.setProperty("Routed Datasource.Router",
"TsRouter");
Context ctx =
EJBContainer.createEJBContainer(properties).getContext();
routedPersister = (RoutedPersister)
ctx.lookup("java:global/dynamic-datasource-routing/RoutedPersister");
}catch(Exception e){
e.printStackTrace();
}
}
public RoutedPersister getRoutedPersister() {
return routedPersister;
}
public void setRoutedPersister(RoutedPersister routedPersister) {
this.routedPersister = routedPersister;
}
public void persist(int id, String name, String ds) {
router.setDataSource(ds);
// em.persist(new Person(id, name));
}
}
////////////////////////////////////////////////////////////////////////////
<?xml version="1.0" encoding="UTF-8"?>
<ServiceJar>
<ServiceProvider id="TsRouter"
service="Resource"
type="org.apache.openejb.resource.jdbc.Router"
class-name="test.datasources.DeterminedRouter"
>
# the parameters
DataSourceNames
DefaultDataSourceName
</ServiceProvider>
</ServiceJar>
I placed this file in WEB-INF/classes/META-INF/org.router/service-jar.xml
When I run it I get the following error message:
Mar 16, 2014 4:07:23 PM org.apache.tomee.catalina.TomcatWebAppBuilder
startInternal
SEVERE: Unable to deploy collapsed ear in war
StandardEngine[Catalina].StandardHost[l
ocalhost].StandardContext[/rls]
org.apache.openejb.OpenEJBException: Can't find resource for class
test.datas
ources.RoutedPersister#router. (No provider available for resource-ref
'null' of type
'test.datasources.DeterminedRouter' for 'rls.Comp1509825954'.)
at
org.apache.openejb.config.AutoConfig.processResourceRef(AutoConfig.java:11
74)
at org.apache.openejb.config.AutoConfig.deploy(AutoConfig.java:858)
at org.apache.openejb.config.AutoConfig.deploy(AutoConfig.java:193)
at
org.apache.openejb.config.ConfigurationFactory$Chain.deploy(ConfigurationF
actory.java:396)
at
org.apache.openejb.config.ConfigurationFactory.configureApplication(Config
urationFactory.java:938)
at
org.apache.tomee.catalina.TomcatWebAppBuilder.startInternal(TomcatWebAppBu
ilder.java:1171)
at
org.apache.tomee.catalina.TomcatWebAppBuilder.configureStart(TomcatWebAppB
uilder.java:1051)
at
org.apache.tomee.catalina.GlobalListenerSupport.lifecycleEvent(GlobalListe
nerSupport.java:127)
at
org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupp
ort.java:119)
at
org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.ja
--
View this message in context:
http://openejb.979440.n4.nabble.com/Dynamic-DataSource-Exception-tp4657657p4668232.html
Sent from the OpenEJB User mailing list archive at Nabble.com.