Forum Home » Enterprise Products » Fuse IDE

Thread: How to return multiple values from cxf webservice?

 
This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 19 - Last Post: Sep 13, 2009 1:04 PM Last Post By: njiang
khaliqgaffar

Posts: 38
Registered: 08/04/09
How to return multiple values from cxf webservice?
Posted: Aug 13, 2009 12:56 PM
 
  Click to reply to this thread Reply
Hello,

I have scneario where input function is exposed as webservice.This webservice is designed using eip .The function which is exposed is List<Employee>getEmployee(String age,String status).

The List of employee would be database query which would return list of employee object back to webservice.

I have thought i would do this way eip diagram

CXF->Bean(webservice Implemtation)->sql(queries database on the above 2 parameter)

Please let me know how this can be accomplished within FID using palletes.Is there any samples which depicts similar scenario ?

Any help in this regard would be highly apperciated.

Please bare with my question as i am trying to move from tibco background to fuse opensource.

Regards,
Khaliq
mahesh

Posts: 11
Registered: 10/07/08
Re: How to return multiple values from cxf webservice?
Posted: Aug 14, 2009 5:56 AM   in response to: khaliqgaffar in response to: khaliqgaffar
 
  Click to reply to this thread Reply
Palette of EIP editor in FID 1.2.1 doesn't have sql component.
If any other component (missing in palette) is to be used, then use he "Generic Endpoint".

Generic endpoint takes the whole URI string as the endpoint property. Add the required jars to class-path for Run/Debug.

If any new component requires bean additions, then define the bean in the Spring Definition xml and add that xml to bean imports section in the EIP.

regards,
mahesh
khaliqgaffar

Posts: 38
Registered: 08/04/09
Re: How to return multiple values from cxf webservice?
Posted: Aug 14, 2009 12:23 PM   in response to: mahesh in response to: mahesh
 
  Click to reply to this thread Reply
Hi Mahesh,

I have already done a sample where i queried the database using sql in FID . My question was how to pass list of records back to webservice call ? Lets say i want to pass list of employee object back to webservice call.

Is there anything which we can do out of the box or please let me know how we can go about doing this.

Regards,
Khaliq
mahesh

Posts: 11
Registered: 10/07/08
Re: How to return multiple values from cxf webservice?
Posted: Aug 14, 2009 12:50 PM   in response to: khaliqgaffar in response to: khaliqgaffar
 
  Click to reply to this thread Reply
A CXF component replies the content of OUT. If your SQL component can copy the list of records to the exchange's OUT then it will do (if Exchange's IN or FAULT is set then copy to the exchange's OUT for response).
khaliqgaffar

Posts: 38
Registered: 08/04/09
Re: How to return multiple values from cxf webservice?
Posted: Aug 16, 2009 9:32 AM   in response to: mahesh in response to: mahesh
 
  Click to reply to this thread Reply
Hi Mahesh,

Can you assist me as to how i go about doing this ?

Regards,
Khaliq
davsclaus

Posts: 1,893
Registered: 10/14/08
Re: How to return multiple values from cxf webservice?
Posted: Aug 17, 2009 7:40 AM   in response to: khaliqgaffar in response to: khaliqgaffar
 
  Click to reply to this thread Reply
cxf -> bean -> sql -> bean2

Where bean2 transforms that result from the SQL to the type the CXF expects which was a List<Employee> as I believe.

So just create a bean with a signature like

public List<Employee> myTransformSqlData(Exchange exchange) {
List data = exchange.getIn().getBody(List.class);
// SQL returns data in a list of map I believe
// so loop the list and extract colums from the map and put it on a employee object
List<Employee> answer = new ArrayList...
// loop data
// create employee and set values
return answer;
}

Instead of Exchange as parameter to your method you can use List data to avoid being dependent on any Camel API

public List<Employee> myTransformSqlData(List data) {
...
}
khaliqgaffar

Posts: 38
Registered: 08/04/09
Re: How to return multiple values from cxf webservice?
Posted: Aug 17, 2009 10:14 AM   in response to: davsclaus in response to: davsclaus
 
  Click to reply to this thread Reply
Hi,

I have replicated as suggested by you .Whenever i call the webservice the sql gives the below mentioned exception.

I tried making same sql call via spring jdbc template . I had not issues or exception .

what would be the reason why sql componet is giving this exception . As i read in documentation it also uses spring jdbctemplate.

Regards,
Khaliq

17-Aug-2009 14:06:48 org.apache.cxf.phase.PhaseInterceptorChain doIntercept
WARNING: Interceptor has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: PreparedStatementCallback; uncategorized SQLException for SQL select * from messages; SQL state null; error code 17004; Invalid column type; nested exception is java.sql.SQLException: Invalid column type
at org.apache.camel.component.cxf.CamelInvoker.invoke(CamelInvoker.java:200)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:417)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:269)
at java.util.concurrent.FutureTask.run(FutureTask.java:123)
at org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:98)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:236)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:104)
at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.serviceRequest(JettyHTTPDestination.java:302)
at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:266)
at org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandler.java:70)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:534)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:879)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:747)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:520)
Caused by: org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL select * from messages; SQL state null; error code 17004; Invalid column type; nested exception is java.sql.SQLException: Invalid column type
at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.translate(SQLStateSQLExceptionTranslator.java:124)
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.translate(SQLErrorCodeSQLExceptionTranslator.java:322)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:604)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:616)
at org.apache.camel.component.sql.SqlProducer.process(SqlProducer.java:45)
at org.apache.camel.impl.converter.AsyncProcessorTypeConverter$ProcessorToAsyncProcessorBridge.process(AsyncProcessorTypeConverter.java:43)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:84)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:68)
at org.apache.camel.processor.interceptor.StreamCachingInterceptor.proceed(StreamCachingInterceptor.java:87)
at org.apache.camel.processor.interceptor.StreamCachingInterceptor.process(StreamCachingInterceptor.java:82)
at org.apache.camel.processor.DeadLetterChannel.process(DeadLetterChannel.java:189)
at org.apache.camel.processor.DeadLetterChannel.process(DeadLetterChannel.java:133)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:115)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:89)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:68)
at org.apache.camel.processor.interceptor.StreamCachingInterceptor.proceed(StreamCachingInterceptor.java:87)
at org.apache.camel.processor.interceptor.StreamCachingInterceptor.process(StreamCachingInterceptor.java:82)
at org.apache.camel.processor.UnitOfWorkProcessor.process(UnitOfWorkProcessor.java:52)
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:41)
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:66)
at org.apache.camel.component.cxf.CamelInvoker.invoke(CamelInvoker.java:185)
... 22 more
Caused by: java.sql.SQLException: Invalid column type
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208)
at oracle.jdbc.driver.OraclePreparedStatement.setObjectCritical(OraclePreparedStatement.java:9262)
at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:8843)
at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:9565)
at oracle.jdbc.driver.OraclePreparedStatement.setObject(OraclePreparedStatement.java:9548)
at org.apache.camel.component.sql.SqlProducer$1.doInPreparedStatement(SqlProducer.java:52)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:588)
... 40 more
davsclaus

Posts: 1,893
Registered: 10/14/08
Re: How to return multiple values from cxf webservice?
Posted: Aug 17, 2009 10:47 AM   in response to: khaliqgaffar in response to: khaliqgaffar
 
  Click to reply to this thread Reply
Its Oracle that returns error 17004.

Try google for ORA-17004.

And instead of select * try a SQL that selects the columns you need, such as

select first_name, last_name from employees

Or what the SQL you need to use. You can run it in a SQL tool to ensure that it works and returns what you need. (eg toad, sql+, dbvisualizer etc.)
khaliqgaffar

Posts: 38
Registered: 08/04/09
Re: How to return multiple values from cxf webservice?
Posted: Aug 17, 2009 11:23 AM   in response to: davsclaus in response to: davsclaus
 
  Click to reply to this thread Reply
Currently i am calling this via webservice which is leading this error .If i change to timer component then i have no issues with sql component.

I am attaching webservice flow with sql along with this post.

Regards,
Khaliq
khaliqgaffar

Posts: 38
Registered: 08/04/09
Re: How to return multiple values from cxf webservice?
Posted: Aug 18, 2009 5:22 AM   in response to: davsclaus in response to: davsclaus
 
  Click to reply to this thread Reply
I tried everything checked the sql statement in toad . Wrote a sample spring application which uses spring jdbctemplate to check the sql . Infact i tried the same with timer being start event .

All the above seem to work perfectly . Looks like this is a issues when cxf component when used along with sql component.

Regards,
Khaliq
davsclaus

Posts: 1,893
Registered: 10/14/08
Re: How to return multiple values from cxf webservice?
Posted: Aug 18, 2009 7:37 AM   in response to: khaliqgaffar in response to: khaliqgaffar
 
  Click to reply to this thread Reply
Hi

Thanks for trying out.

Can you attach or create a sample project that is causing this issue?
And if so attach it to this forum then we can take a look at it.

I have created a ticket about this issue to track it:
MR-241
khaliqgaffar

Posts: 38
Registered: 08/04/09
Re: How to return multiple values from cxf webservice?
Posted: Aug 18, 2009 10:01 AM   in response to: davsclaus in response to: davsclaus
 
  Click to reply to this thread Reply
Attachment FuseJMSProject.zip (28.6 KB)
Hi ,

I am attaching the entire project for you reference.

Regards,
Khaliq
njiang

Posts: 572
Registered: 09/17/07
Re: How to return multiple values from cxf webservice?
Posted: Aug 18, 2009 12:29 PM   in response to: khaliqgaffar in response to: khaliqgaffar
 
  Click to reply to this thread Reply
Can you show me the stack trace for CXF component ?

Here is a thing, you can't put the List<Message> directly to the exchange's outMessage body, you need to use a Object array to wrap the list object, or the CamelInvoker will miss-interpret the List object.

Willem
njiang

Posts: 572
Registered: 09/17/07
Re: How to return multiple values from cxf webservice?
Posted: Aug 24, 2009 3:39 AM   in response to: njiang in response to: njiang
 
  Click to reply to this thread Reply
Hi Khaliq,
Did you give my suggestion a try ?
Please add some comment on the MR-241, when you have time to try it.
indika

Posts: 15
Registered: 08/16/09
Re: How to return multiple values from cxf webservice?
Posted: Aug 24, 2009 7:26 AM   in response to: njiang in response to: njiang
 
  Click to reply to this thread Reply
Nijang,

If you can give better insight as to what you exactlly want me to do .

Regards,
Khaliq
khaliqgaffar

Posts: 38
Registered: 08/04/09
Re: How to return multiple values from cxf webservice?
Posted: Aug 24, 2009 9:18 AM   in response to: indika in response to: indika
 
  Click to reply to this thread Reply
My issue is that sql component is not able to return resultset when CXF component is used as primary endpoint.

Instead of using CXF endpoint if i use Timer endpoint i get result out from sql component .

I feel there is issue with

CXF->SQL

Regards,
Khaliq
khaliqgaffar

Posts: 38
Registered: 08/04/09
Re: How to return multiple values from cxf webservice?
Posted: Aug 31, 2009 1:03 AM   in response to: khaliqgaffar in response to: khaliqgaffar
 
  Click to reply to this thread Reply
Any Insight into above mentioned problem ?

Regards,
Khaliq
njiang

Posts: 572
Registered: 09/17/07
Re: How to return multiple values from cxf webservice?
Posted: Aug 31, 2009 8:51 AM   in response to: khaliqgaffar in response to: khaliqgaffar
 
  Click to reply to this thread Reply
My suggestion is changing the code of DirectSql.java like below

package com.CXF;
 
    public class DirectSql {
	
	public Object[] getSqlData(){
		MessageList msglist = new MessageList();
		return new Object[]{msglist};
	}
 
}
khaliqgaffar

Posts: 38
Registered: 08/04/09
Re: How to return multiple values from cxf webservice?
Posted: Sep 2, 2009 8:58 AM   in response to: njiang in response to: njiang
 
  Click to reply to this thread Reply
Hi Njang,

I have already tried this workaround and which is working . But my objective was to get it via fid pallete with no java coding .

While i can get this via timer as endpoint but not as CXF as endpoint.

Regards,
Khaliq
njiang

Posts: 572
Registered: 09/17/07
Re: How to return multiple values from cxf webservice?
Posted: Sep 13, 2009 1:04 PM   in response to: khaliqgaffar in response to: khaliqgaffar
 
  Click to reply to this thread Reply
If you want to put the list back to CXF endpoint rightly, you just need to wrap the list with object array. Since CXF endpoint will try to extract the list for the return value.