Migrating from service-mix file poller to apache camel file poller - java

I am new to apache camel. I want to migrate from service mix file poller to camel file poller. I am trying to do it, but currently I have nothing to test as I have to code this and give someone for testing. So can someone help me and check whether I am going in right way?
Service-mix File Poller code:
<sm:activationSpec componentName="abcFilePoller"
destinationService="b:destinationA"
service="b:abcFilePoller">
<sm:component>
<bean class="org.apache.servicemix.components.file.FilePoller">
<property name="file" value="file://D:/input" />
<property name="period" value="20000"/>
<property name="archive" value="file://D:/archive" />
<property name="filter" ref="abcFileFilter" />
<property name="marshaler">
<bean class="org.apache.servicemix.components.util.BinaryFileMarshaler" />
</property>
</bean>
</sm:component>
</sm:activationSpec>
<sm:activationSpec componentName="destinationA"
service="b:destinationA">
<sm:component>
<bean
class="com.abc.file.ABCReceiverComponent">
</bean>
</sm:component>
</sm:activationSpec>
<bean id="abcFileFilter" class="org.apache.commons.io.filefilter.WildcardFileFilter">
<constructor-arg value="A*.ID" />
Apache Camel File Poller
<camel:route id="abcFilePoller">
<camel:from
uri="timer://time?period=20000"/>
<camel:pollEnrich uri="file://D:/input"/>
<camel:filter ref="abcFileFilter"></camel:filter>
<camel:to uri="file://D:/archive" />
<camel:to uri="" />
</camel:route>
<bean id="abcFileFilter" class="org.apache.commons.io.filefilter.WildcardFileFilter">
<constructor-arg value="A*.ID" />
</bean>
I have not completed the camel coding. I have left with destination part. And I have no idea about the marshaler that is used in the service-mix part. How to implement that BinaryFileMarshaler using camel.

You can do this even easier in Apache Camel where you can configure the filtering in the file endpoint, so it just becomes
<route>
<from uri="file:D:/input?delay=20000&include=A.*ID"/>
<to uri="file:D:/archive"/>
</route>
Just mind that the include option uses a regular expression, so if you are not familiar with that it can take a bit tries to get the expression to work as expected. But its standard java regular expressions.
See more at: https://camel.apache.org/components/latest/file-component.html
And for new users to Apache Camel then see: http://java.dzone.com/articles/open-source-integration-apache

Related

Put operation does not work for IBM MQ from camel when using JMSPoolXAConnectionFactory

We are implementing XA transaction between MQ and database and trying to create a connection factory as a service in karaf as per the below link.
https://access.redhat.com/documentation/fr-fr/red_hat_fuse/7.2/html/apache_karaf_transaction_guide/using-jms-connection-factories#manual-deployment-connection-factories
The MQ we are using is IBM and we are connecting to it through camel.
The karaf service is exposed from the same bundle that is going to use it. This is done through blueprint xml file present in the src/main/resources/OSGI-INF/blueprint folder.
When we use (through JNDI) the connection factory exposed as a service for setting the connection factory to be used by the JmsComponent of camel, we are able to get message from the queue but not able to put message into the queue. There is no error when the put operation fails and hence, the database gets updated with success. This happens specifically when using JmsPoolXAConnectionFactory as the pool connection factory. If we change it to JmsPoolConnectionFactory, the put operation works and the message is added to the queue.
Below are the sample routes for get and put to queue.
GET:
from("mq:queue:{{queueName}}")
.process(new CustomProcessor1())
.to("direct:call-sp")
.end();
from("direct:call-sp")
.to("sql-stored:call-sp")
.end();
PUT:
from("vm:send")
.process(new CustomProcessor2())
.to("mq:queue:{{queueName}}")
.to("sql-stored:update-sp")
.to("vm:nextroute")
.end();
Camel JmsComponent Configuration in camel-context.xml:
<reference id="ptm" interface="org.springframework.transaction.PlatformTransactionManager" />
<reference id="connectionFactory" interface="javax.jms.ConnectionFactory" filter="(osgi.jndi.service.name=jms/mq)" availability="optional" />
<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
<property name="transacted" value="false" />
<property name="connectionFactory" ref="connectionFactory" />
<property name="transactionManager" ref="ptm" />
</bean>
<bean id="mq" class="org.apache.camel.component.jms.JmsComponent">
<property name="configuration" ref="jmsConfig" />
<property name="destinationResolver" ref="customDestinationResolver" />
</bean>
<bean id="customDestinationResolver" class="com.example.CustomDestinationResolver">
</bean>
Is there any put related specific configuration that we are missing?
To coordinate XA transactions, you need a transaction manager which implements the Java Transaction API (JTA).
Therefore, I think you need to use a JtaTransactionManager rather than a org.springframework.transaction.PlatformTransactionManager.
Check this out:
https://tomd.xyz/camel-xa-transactions-checklist/

How to get the file from service-activator Message object in listener class

I need to pass the file to service layer which i am receiving in SFTP path.
below is configuration and i am seeing the message receiving in my service-activator like
GenericMessage [payload=com.jcraft.jsch.ChannelSftp$2#322906a2,
headers={closableResource=org.springframework.integration.sftp.session.SftpSession#379662a7,
id=704c58e7-1d93-3bef-0330-233c0f9af55c, file_remoteDirectory=/tmp/charge/,
file_remoteFile=Charge.txt, timestamp=1594158522576}]
<bean id="sftpSessionFactory"
class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
<property name="host" value="hostname"/>
<property name="port" value="22"/>
<property name="user" value="vkp"/>
<property name="password" value="1234"/>
<property name="allowUnknownKeys" value="true"/>
</bean>
<int-sftp:inbound-streaming-channel-adapter id="sftpAdapterAutoCreate"
session-factory="sftpSessionFactory"
filename-pattern="*.txt"
channel="receiveChannel"
remote-directory="/tmp/charge/">
</int-sftp:inbound-streaming-channel-adapter>
<int:poller fixed-rate="25000" max-messages-per-poll="1" id="shippingChargePoller" default="true"/>
<int:channel id="receiveChannel">
<int:queue/>
</int:channel>
<int:stream-transformer id="withCharset" charset="UTF-8" input-
channel="receiveChannel" />
<int:service-activator id="FeedListener" input-channel="receiveChannel" method="onMessage">
<bean class="com.listener.ChargeFeedListener"/>
</int:service-activator>
public void onMessage(Message<?> message){
System.out.println(message.toString());
System.out.println( " Received File is "+message.getPayload());
}
But i am not receiving the file in my java class . What i need to do to get the file ?
Please, read documentation: https://docs.spring.io/spring-integration/docs/current/reference/html/sftp.html#sftp-streaming. The <int-sftp:inbound-streaming-channel-adapter> is not about files. It does open an InputStream for a remote entry (probably file on SFTP) and let you to do with this stream whatever you want. For example (also according that docs), there is a StreamTransformer which let's you to read that stream into a byte[] or string if you provide a charset. If you really want to deal with files, then you need to consider to switch to the <int-sftp:inbound-channel-adapter>. That one pull the remote entry and store its content into a local file. Then that java.io.File is sent to the channel for your consideration.
I think we had a chat with you on the matter in other your question: Spring SFTP Integration is not polling the file.
Please, let us know what is wrong with our docs that confuses you so you have to raise questions like this over here.

How to configure route tracing in Apache Camel >= 3?

I'm trying to migrate from Camel 2.X to 3.X and have run in to a question about logging the routing trace.
Previously I have configured it like this in my application context xml-file:
<bean id="camelTracer" class="org.apache.camel.processor.interceptor.Tracer">
<property name="traceExceptions" value="false" />
<property name="traceInterceptors" value="true" />
<property name="logLevel" value="DEBUG" />
<property name="logName" value="com.mycompany.routing.trace" />
</bean>
<bean id="traceFormatter" class="org.apache.camel.processor.interceptor.DefaultTraceFormatter">
<property name="showBody" value="true" />
<property name="maxChars" value="0" />
</bean>
But that obviously does not work anymore.
From the migration guide on the Camel website:
"A new tracer has been implemented and the old tracer has been removed. The new tracer logs messages at the org.apache.camel.Tracing logger name which is hardcoded. The format of the output is also updated to make it better. The tracer can be customized."
If I set .tracing() at the start of my routes it does log the trace. The name is hardcoded which is fine, but I would like to change the level from INFO to DEBUG among other things.
Does anyone know where to find information on how to configure this "new" tracer (preferrably in an applicationContext.xml file)? Or anywhere else, maybe in the Java DSL route? Or if it is even possible?
Thanks!
Logging level of DefaultTracer cannot be changed by configuration. You need to implement customized Tracer and bind this implementation to registry.
Tracer:
public class TracerCustom extends DefaultTracer {
private static final Logger LOG = LoggerFactory.getLogger("com.stackoverflow.camel.TracerCustom");
#Override
protected void dumpTrace(String out) {
LOG.debug(out);
}
// Customize other methods if needed
}
Spring context:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<bean class="com.stackoverflow.camel.TracerCustom" />
<camelContext id="tracerCamelContext" xmlns="http://camel.apache.org/schema/spring">
<route trace="true">
<from uri="timer:test"/>
<to uri="log:test"/>
</route>
</camelContext>
</beans>

How to enable addressing feature in cxf xml?

How can I add default WS-addressing to the xml?
<cxf:cxfEndpoint id="endpoint" xmlns:s="http://tempuri.org/"
address="https://uslugaterytws1test.stat.gov.pl/TerytWs1.svc"
endpointName="s:custom"
serviceName="s:TerytWs1"
wsdlURL="classpath:/wsdl/terytws1.wsdl">
<cxf:properties>
<entry key="schema-validation-enabled" value="false" />
</cxf:properties>
<cxf:inInterceptors>
</cxf:inInterceptors>
<cxf:inFaultInterceptors>
</cxf:inFaultInterceptors>
<cxf:outInterceptors>
</cxf:outInterceptors>
<cxf:outFaultInterceptors>
</cxf:outFaultInterceptors>
</cxf:cxfEndpoint>
<cxf:cxfEndpoint id="poxyEndpoint" xmlns:s="http://tempuri.org/"
address="http:localhost:5678/myproxy"
endpointName="s:customProxy"
serviceName="s:TerytWs1Proxy"
wsdlURL="classpath:/wsdl/terytws1Proxy.wsdl">
<cxf:properties>
<entry key="schema-validation-enabled" value="false" />
</cxf:properties>
<cxf:inInterceptors>
</cxf:inInterceptors>
<cxf:inFaultInterceptors>
</cxf:inFaultInterceptors>
<cxf:outInterceptors>
<ref component-id="wssOutInterceptor" />
</cxf:outInterceptors>
<cxf:outFaultInterceptors>
<ref component-id="wssOutInterceptor" />
</cxf:outFaultInterceptors>
</cxf:cxfEndpoint>
<camelContext id="proxyTerytContext" xmlns="http://camel.apache.org/schema/blueprint">
<route id="route-TerytWs1">
<from id="inbound" uri="cxf:bean:proxyEndpoint?dataFormat=CXF_MESSAGE" />
<to id="outbound" uri="cxf:bean:endpoint?dataFormat=CXF_MESSAGE" />
</route>
</camelContext>
When I send request to http:localhost:5678/myproxy then I get:
<faultcode xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">a:InvalidSecurity</faultcode>
<faultstring xml:lang="en-US">An error occurred when verifying security for the message.</faultstring>
I have read many similar questions and examples but haven't found the solution for pure cxf xml. I have been trying to solve this for 2 days. Now I'm crying.
EDIT:
This is an original wsdl: https://uslugaterytws1test.stat.gov.pl/terytws1.svc?wsdl
and this is my proxy to it: https://github.com/woblak/training/blob/master/teryt_testProxy.wsdl
user: TestPubliczny
pass: 1234abcd
There are some examples in the Camel unit tests which test CXF endpoints with WS-Addressing enabled; WSAddressingTest-context.xml seems like it might be relevant to your question?
Here, WS-Addressing has been enabled on a CXF endpoint by adding the wsa:addressing element in features:
<cxf:cxfEndpoint...>
<cxf:features>
<wsa:addressing xmlns:wsa="http://cxf.apache.org/ws/addressing" />
</cxf:features>
</cxf:cxfEndpoint>
The error seems to be related to security. You have an interceptor configured (wssOutInterceptor) but there's no source code. Perhaps you should look there to see if you're setting the auth details.
I would also add message logging so you can see the content of the payload sent to the target and verify that it contains your credentials.
Or, if you're using the Camel CXF namespace ( xmlns:cxf="http://camel.apache.org/schema/cxf") you can use:
<cxf:cxfEndpoint ... loggingFeatureEnabled="true">
...
</cxf:cxfEndpoint>

ServiceMix 4.4.2 proxing FTP via Rest, can't read file from ftp

I'm dealing with a problem how to read a file with Camel in SMX 4.4.2 but only in case when
the read operation cannot be performed in Camel route from.
I need to read data from the file transform it into XML and then return it to the requestor (the requestor hits SMX via REST Service).
I'm having serious problems with reading the file after the REST invokation.
Routes are like these:
<jaxrs:server id="restService" address="http://localhost:9000/REST/"
staticSubresourceResolution="true">
<jaxrs:serviceBeans>
<ref bean="restFtpBean" />
</jaxrs:serviceBeans>
</jaxrs:server>
<bean id="restFtpBean" class="poc.rest.RESTFtpProxyService" />
<cxf:rsServer id="rsServer" address="http://localhost:9000/REST/"
serviceClass="poc.rest.RESTFtpProxyService" />
<camel:camelContext xmlns="http://camel.apache.org/schema/spring">
<endpoint id="ftpProvider" uri="ftp://localhost:21/?fileName=test.xml" />
<route>
<from uri="cxfrs://bean://rsServer" />
<to ref="ftpProvider" />
</route>
</camel:camelContext>
In this scenario Camel tries to write to file !
What am I doing wrong ?
Its always advised to learn and get familiar with the EIPs
http://camel.apache.org/content-enricher.html
Your use-case you need to consume a file from within a route, and there is an EIP pattern for that: http://camel.apache.org/content-enricher.html. See the section about using pollEnrich to consume/poll the file.

Categories

Resources