One Star

[resolved] How to retrieve datasource with it's JNDI name in Talend Route?

Hi Team,
I am trying to retrieve all available data sources and their JNDI names in Talend Runtime. However, I only can get either all data sources or all JNDIs, but cannot map JNDIs to relavent data source instances. 
For example, I managed to get all JNDIs and then try to get data sources with below code:
Registry reg = camelContext.getRegistry();
Set<org.apache.karaf.jndi.JndiService> s = reg.findByType(org.apache.karaf.jndi.JndiService.class);
if(s == null)
System.out.println("JndiService is null");
else{
for(org.apache.karaf.jndi.JndiService js : s)
{
try{
Map<String, String> jndis = js.names();
for(Map.Entry<String, String> row_jndi : jndis.entrySet() )
{
String key = row_jndi.getKey();
String value = row_jndi.getValue();
System.out.println("Key = " + key + "; Value = " + value);
Object obj = reg.lookupByName(key);
if(obj != null)
System.out.println("Obj is " + obj.toString());
else
System.out.println("Obj is null" );
}

}catch(Exception e)
{
....................
}
}
}

However, the reg.lookupByName(key) failed to get objects and log shows:
Key = osgi:service/WeChatDS; Value = org.apache.commons.dbcp2.managed.ManagedDataSource
Obj is null
Key = osgi:service/jndi; Value = org.apache.karaf.jndi.internal.JndiServiceImpl
Obj is null
Key = osgi:service/MobileCRMDS; Value = org.apache.commons.dbcp2.managed.ManagedDataSource
Obj is null
Key = osgi:service/jdbc/WeChat2; Value = org.postgresql.ds.PGPoolingDataSource
Obj is null

When I try to use code of: "Set<javax.sql.DataSource> o = reg.findByType(javax.sql.DataSource.class);", it only gives me instances of data sources, but I cannot use data source instance to fetch JNDI name.
Anyone could advice me how to get JNDI and relevant data source instance? BTW, I am working on TOS 6.0
1 ACCEPTED SOLUTION

Accepted Solutions
One Star

Re: [resolved] How to retrieve datasource with it's JNDI name in Talend Route?

4 REPLIES
Employee

Re: [resolved] How to retrieve datasource with it's JNDI name in Talend Route?

You could try to use plain jndi like:
Context context = new InitialContext();
and then use the context to look up and retrieve the DataSources.
Another option is to get hold of the OSGi BundleContext and lookup the DataSources as OSGi services.
One Star

Re: [resolved] How to retrieve datasource with it's JNDI name in Talend Route?

Hi Schneider,
Thank you for your reply. However, it throws exceptions as such:
javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
at javax.naming.InitialContext.getURLOrDefaultInitCtx(Unknown Source)
at javax.naming.InitialContext.lookup(Unknown Source)
at test_datasource.mysqljob_0_1.mysqljob.tJava_1Process(mysqljob.java:737)
at test_datasource.mysqljob_0_1.mysqljob.tPostgresqlConnection_1Process(mysqljob.java:663)
at test_datasource.mysqljob_0_1.mysqljob.tPrejob_1Process(mysqljob.java:528)
at test_datasource.mysqljob_0_1.mysqljob.runJobInTOS(mysqljob.java:2152)
at org.talend.camel.TalendProducer.invokeTalendJob(TalendProducer.java:109)
at org.talend.camel.TalendProducer.process(TalendProducer.java:65)
at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:129)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:448)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:118)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.component.jetty.CamelContinuationServlet.service(CamelContinuationServlet.java:162)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:808)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669)
at org.eclipse.jetty.servlets.MultiPartFilter.doFilter(MultiPartFilter.java:146)
at org.apache.camel.component.jetty.CamelFilterWrapper.doFilter(CamelFilterWrapper.java:43)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.eclipse.jetty.server.Server.handle(Server.java:497)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
at java.lang.Thread.run(Unknown Source)

The codes are:
javax.naming.Context ctx = new javax.naming.InitialContext();
Object o = ctx.lookup("somename");

Am I using a wrong Context class? Context is unknown class in Talend....
One Star

Re: [resolved] How to retrieve datasource with it's JNDI name in Talend Route?

Finally, I managed to achieve my requirements using bundleContext...here are my codes in cConfig in Talend Route:
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;

Bundle[] bundles = bundleContext.getBundles();
for (Bundle bundle : bundles) {

ServiceReference[] services = bundle.getRegisteredServices();
if (services != null) {
for (ServiceReference serviceReference : services) {
String[] objectClasses = (String[])serviceReference.getProperty(Constants.OBJECTCLASS);
boolean t = false;
for(String s : objectClasses){
if(s.equals("javax.sql.DataSource"))
{
t = true;
break;
}
}
if(t){
Object actualService = bundleContext.getService(serviceReference);
System.out.println("actualService is " + actualService);
String jndiProperty = (String)serviceReference.getProperty("osgi.jndi.service.name");
System.out.println("actualService JNDI is " + jndiProperty);
}

}
}
}

So actualService here refers to real data source and jndiProperty is its JNDI name.
One Star

Re: [resolved] How to retrieve datasource with it's JNDI name in Talend Route?