我想从各种数据库中获取数据行,并将它们插入另一个聚合数据库中。这个使用Camel Java代码进行的简单测试可以正常运行:
from("timer://Timer?period=60000")
.setBody(constant("select * from cosdata"))
.to("jdbc:vedasDataSource")
.split(body())
.setBody(simple("insert into acogsdata values('${body[id]}','${body[code]}','${body[value]}')"))
.to("jdbc:quantumDataSource");
我对此感兴趣的是在属性文件中维护SQL代码的潜力,这样就可以将特定的数据模式知识与传输(骆驼)代码分开(我在本示例中未显示此代码,但现在我希望这是可以实现的)。我想连接到不同的数据源,这些数据源的字段和表将具有不同的名称。
我想扩展上面的示例,以便通过Web服务将数据路由到目标数据库,该服务也不需要先验与数据源相关的特定架构,即我想避免POJO数据表示。因此,经过大量的研究和试验,我现在想知道这个概念(从传输层分离数据结构)是否可能?
以下代码显示了总体思路,但给出了一个例外。该异常表示缺少数据定义。它与通过Web服务进行封送/拆组有关。从概念上讲,如果Camel路由能够保留第一个示例的行为而不会增加Web服务端点,那将是很好的。
我的路由构建器configure中的以下代码显示了我想要实现的目标:
final String quantumURI = "jdbc:postgresql://localhost:5432/quantum";
DataSource quantumdataSource1 = setupQuantumDataSource(quantumURI);
SimpleRegistry reg = new SimpleRegistry() ;
reg.put("quantumDataSource",quantumdataSource1);
CamelContext context = getContext();
((org.apache.camel.impl.DefaultCamelContext) context).setRegistry(reg);
from(uri)
.to("log:input")
// send the request to the route to handle the operation
.recipientList(simple("direct:${header.operationName}"));
// upload
from("direct:upload")
.split().body()
.setBody(simple("insert into acogsdata values('${body[id]}','${body[code]}','${body[value]}')"))
.to("jdbc:quantumDataSource")
.to("log:output");
我想将每个“行”插入数据库。 作为ArrayList的主体如下所示:
[{id=1, code=Meds, value=12.34}, {id=2, code=Meds, value=12376.39}, {id=3, code=Samples, value=8002.54}, {id=4, code=Misc, value=124.34}, {id=5, code=Fees, value=125.34}]
此数据来自数据源选择语句,然后将其从客户端发送到Web服务:
我收到以下异常:
org.apache.cxf.binding.soap.SoapFault: Failed to invoke method: [id] on java.lang.String due to: java.lang.IndexOutOfBoundsException: Key: id not found in bean: [{id=1, code=Meds, value=12.34}, {id=2, code=Meds, value=12376.39}, {id=3, code=Samples, value=8002.54}, {id=4, code=Misc, value=124.34}, {id=5, code=Fees, value=125.34}] of type: java.lang.String using OGNL path [[id]]
完整堆栈跟踪:
org.apache.cxf.binding.soap.SoapFault: Failed to invoke method: [id] on java.lang.String due to: java.lang.IndexOutOfBoundsException: Key: id not found in bean: [{id=1, code=Meds, value=12.34}, {id=2, code=Meds, value=12376.39}, {id=3, code=Samples, value=8002.54}, {id=4, code=Misc, value=124.34}, {id=5, code=Fees, value=125.34}] of type: java.lang.String using OGNL path [[id]]
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarshalFault(Soap11FaultInInterceptor.java:87)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:53)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:42)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:112)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:70)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:35)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:833)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1695)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1572)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1373)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:673)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:63)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:537)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:446)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:361)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:319)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.frontend.ClientProxy.invoke(ClientProxy.java:81)
at com.sun.proxy.$Proxy34.upload(Unknown Source)
at test1.VisionToWSRouteBuilder$1.process(VisionToWSRouteBuilder.java:31)
at org.apache.camel.processor.DelegateSyncProcessor.process(DelegateSyncProcessor.java:63)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:548)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:138)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:101)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
at org.apache.camel.component.timer.TimerConsumer.sendTimerExchange(TimerConsumer.java:197)
at org.apache.camel.component.timer.TimerConsumer$1.run(TimerConsumer.java:79)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
[Camel (camel-1) thread #1 - timer://Timer] WARN org.apache.camel.component.timer.TimerConsumer - Error processing exchange. Exchange[ID-Nelson-1539460289761-0-1]. Caused by: [org.apache.cxf.binding.soap.SoapFault - Failed to invoke method: [id] on java.lang.String due to: java.lang.IndexOutOfBoundsException: Key: id not found in bean: [{id=1, code=Meds, value=12.34}, {id=2, code=Meds, value=12376.39}, {id=3, code=Samples, value=8002.54}, {id=4, code=Misc, value=124.34}, {id=5, code=Fees, value=125.34}] of type: java.lang.String using OGNL path [[id]]]
org.apache.cxf.binding.soap.SoapFault: Failed to invoke method: [id] on java.lang.String due to: java.lang.IndexOutOfBoundsException: Key: id not found in bean: [{id=1, code=Meds, value=12.34}, {id=2, code=Meds, value=12376.39}, {id=3, code=Samples, value=8002.54}, {id=4, code=Misc, value=124.34}, {id=5, code=Fees, value=125.34}] of type: java.lang.String using OGNL path [[id]]
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarshalFault(Soap11FaultInInterceptor.java:87)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:53)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:42)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:112)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:70)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:35)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:833)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1695)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1572)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1373)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:673)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:63)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:537)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:446)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:361)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:319)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.frontend.ClientProxy.invoke(ClientProxy.java:81)
at com.sun.proxy.$Proxy34.upload(Unknown Source)
at test1.VisionToWSRouteBuilder$1.process(VisionToWSRouteBuilder.java:31)
at org.apache.camel.processor.DelegateSyncProcessor.process(DelegateSyncProcessor.java:63)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:548)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:138)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:101)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
at org.apache.camel.component.timer.TimerConsumer.sendTimerExchange(TimerConsumer.java:197)
at org.apache.camel.component.timer.TimerConsumer$1.run(TimerConsumer.java:79)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
我希望拆分会为setBody(insert statement)提供每一行-好的,还有很多东西要学习。
通过Java接口调用WS:
public interface Ingester {
String verify(String input);
String upload(Object data);//tried various permutations
}
客户端配置:
from("timer://Timer?period=60000")
.setBody(constant("select * from cosdata"))
.to("jdbc:vedasDataSource")
在处理器内部这样调用:
ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
factory.setServiceClass(Ingester.class);
factory.setAddress(URL);
Ingester client = factory.create();
String out = client.upload(exchange.getIn().getBody(String.class));
我希望该拆分将为setBody(insert statement)提供每一行-好的,还有很多东西要学习。我把书给了某人...
有人可以帮忙吗?也许有关如何实现数据结构和传输之间分离的一些建议。
谢谢。