wso2 xpath selection on property value - xpath

in wso2 I've an xml as a local property containing a list of status with code and description (status_list).
I would like to select the correct status for one given code. This code is stored in a property.
I've tried something like
<property name="codes" expression="get-property('status_list')" scope="default" type="OM"/>
<log level="custom">
<property expression="$ctx:codes/status[#code='$ctx:code']" name="Test"/>
</log>
$ctx:codes/status is ok and display the list of all status but as soon as I want to "filter" them it's not working.
Of courise if I hardcode a code the xpath is working.
<property expression="$ctx:codes/status[#code='code1']" name="Test"/>
Do you have an idea how to achieve this?

Ok finally I was not so far away from the response.
The following code is working
<property name="codes" expression="get-property('status_list')" scope="default" type="OM"/>
<log level="custom">
<property expression="$ctx:codes/status[#code=$ctx:code]" name="Test"/>
</log>
I simply had to remove the quotes...

Related

WSo2 Esb filtering messages to an output file

I am working with a filter mediator attempting to send messages to an output xml file. I have my sequence using a filter mediator based on a attribute value, if it is true I want to write the message to a new xml file in a certain directory. If it is false I will drop the record.
Here is my sequence:
<sequence xmlns="http://ws.apache.org/ns/synapse" name="RenaissanceIqtFilterSequence">
<log level="custom">
<property name="sequence" value="FilterSequence"></property>
</log>
<filter xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:ns="http://org.apache.synapse/xsd" xmlns:z="RowsetSchema" xpath="//z:row/#name='RP'">
<then>
<log level="custom">
<property name="sequence" value="Condition Write"></property>
</log>
<call-template target="FileWriteTemplate">
<with-param name="targetFileName" value="NEW_MESSAGE_FILE"></with-param>
<with-param name="addressUri" value="vfs:file:///var/process/rrout"></with-param>
</call-template>
</then>
<else>
<log level="custom">
<property name="sequence" value="Condition Drop"></property>
</log>
<drop></drop>
</else>
</filter>
</sequence>
*I am using a template as you can see to write out to my new output file setting parameters for the file name and uri.
The result is the whole file is being written out to the directory not just the messages I want. I have been running google searches trying to see where I am going wrong. I assume at this point I may be using the Filter mediator incorrectly? Maybe there is a better way or mediator to use to accomplish this task? I would appreciate any thoughts or recommendations folks may have. Thanks for your time!

SFTP Spring Integrations rm command

I am wondering if someone can assist, I know I am doing this wrong and I'm tearing my hair out. My goal is to delete any files with a .txt extension in a remote directory using Spring Integrations SFTP in a Spring Batch job. It is my understanding that I do not have to ls remote files to remove them and can just issue an rm command on *.txt for a given directory however I may be incorrect?
I have the following SFTP configuration
<bean id="sftpSessionFactory"
class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
<property name="host" value="${host}" />
<property name="port" value="${port}" />
<property name="user" value="${user}" />
<property name="privateKey" value="file:${privateKey}" />
<property name="password" value="${password}" />
</bean>
<int:channel id="rmChannel"/>
<int-sftp:outbound-gateway
session-factory="sftpSessionFactory"
request-channel="rmChannel"
remote-file-separator="/"
command="rm"
expression="headers['file_remoteDirectory'] + headers['file_remoteFile']" />
<bean id="cleanRemoteDirectoryTasklet" class="com.example.batch.job.integration.SFTPRmTasklet" scope="step">
<property name="channel" ref="rmChannel" />
<property name="filePatternToDelete" value="*.txt" />
<property name="targetDirectory" value="${remoteDirectory}"/> // edit removed 'file:' notation
</bean>
I believe I am OK to this point an my problem is executing this flow in the Java implementation in SFTPRmTasklet, I'm not sure how to construct the message to initiate the sftp remove. Currently I have something like this simply to kick it off I know that my payload is wrong.
Message<String> rmRequest = MessageBuilder.withPayload("/my/target/dir")
.setHeader("file_remoteDirectory", targetDirectory)
.setHeader("file_remoteFile", filePatternToDelete)
.build();
channel.send(rmRequest)
ultimately this yields an exception
org.springframework.integration.MessagingException: org.springframework.core.NestedIOException: Failed to remove file: 2: No such file
UPDATE 1
So I decided to target just one remote file and changed filePatternToDelete to test.txt. After a bit of debugging I realised that AbstractRemoteFileOutBoundGateway was evaluating my remoteFilePath to /my/target/dirtest.txt and remote filename to dirtest.txt, which is obviously not what I wanted so I added a trailing to / to the target directory in my properties file and this sorted out this error great!
I can now delete the file from the remote server as I wished to do however I received an error around no reply-channel so I have added the following channel
<int:channel id="end"/>
and modified my outbound gateway
<int-sftp:outbound-gateway
session-factory="sftpSessionFactory"
request-channel="rmChannel"
reply-channel="end"
remote-file-separator="/"
command="rm"
expression="headers['file_remoteDirectory'] + headers['file_remoteFile']" />
and now get an error around no subscribers for this channel. Progress at least and in case you hadn't guessed I'm pretty new to Spring!
If you are not interested in the result of the rm, set the reply-channel to nullChannel.
It's like /dev/null on unix.

Set system property with spEL arithmetic

The following property is configured in a properties file:
readTimeout=10. I want to use it to set the system property oracle.jdbc.ReadTimeout, but first multiply it by 1000 (to convert to ms.)
I tried the following, which does not work:
<bean id="systemPrereqs"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" value="#{#systemProperties}" />
<property name="targetMethod" value="putAll" />
<property name="arguments">
<util:map>
<entry key="oracle.jdbc.ReadTimeout"
value="#{T(java.lang.Integer).valueOf('${readTimeout}')*1000}" />
</util:map>
</property>
</bean>
No oracle.jdbc.ReadTimeout system property gets created.
However, if I use the following expression:#{'${readTimeout}'*1000} then it is evaluated, and oracle.jdbc.ReadTimeout system property is created, but with 101010.... (a thousand repetitions).
Seems that Spring has a problem with type conversion using T(java.lang.Integer).valueOf. Maybe because the spEL expression is not supported in util:properties/map definitions.
Don't use '${readTimeout}', readTimeout will work fine:
<entry key="oracle.jdbc.ReadTimeout" value="#{new Integer(readTimeout) * 1000}" />

Filter Mediator on XPATH Functions

I am facing a problem with my code using Filter mediator and XPATH functions. What I am trying to do in my code is to check if a particular block is empty, do not call/enrich that block and move to another one checks for if it is empty, if not process it and moves to next one and in the end do a commit. Currently I am getting the error as:
FilterMediator Error evaluating XPath expression : fn:exists($body/product/simpleProduct/standardAttributes)
My code is as follows:
<inSequence>
<log level="custom">
<property name="STATUS" value="************ REQUEST ***************"/>
</log>
<transaction action="new"/>
<filter xpath="fn:exists($body/product/simpleProduct/standardAttributes)">
</filter>
<enrich>
<source type="body" clone="true"/>
<target type="property" property="MSG_PAYLOAD"/>
</enrich>
<log level="full"/>
<xslt key="simpleAttributes"/>
<log level="custom">
<property name="STATUS"
value="*********INSERTING Simple Product Attributes *************"/>
</log>
</inSequence>
It fails at fn:exists(). Can you help me with your inputs where am I going wrong?
Apparently the function you use is xpath 2 function. OOTB xpath 2 functions won't work in ESB. If this is xpath2, you have to enable it. To enable xpath 2, for that uncomment synapse.xpath.dom.failover.enabled=true in synapse.properties file.

Passing encrypted properties to spring context

I never seen this but I wondering if somebody has come across. Having a web server which access a database. I want to pass the database password encrypted and have spring context decrypting it before setting the datasource. I know the spring security can do some of this like using a salt file in the web server, etc.
The challenge here is that I don't want to give a clear user,password,url to the web server team. Just an encrypted password and have spring decrypted before using it.
Is there something like this already? I know I could code something but is it already done?
Thanks
By using an org.jasypt.properties.EncryptableProperties object, an application would be able to correctly read and use a .properties file like this:
datasource.driver=com.mysql.jdbc.Driver
datasource.url=jdbc:mysql://localhost/reportsdb
datasource.username=reportsUser
datasource.password=ENC(G6N718UuyPE5bHyWKyuLQSm02auQPUtm)
Note that the database password is encrypted (in fact, any other property could also be encrypted, be it related with database configuration or not).
More information :
http://www.jasypt.org/encrypting-configuration.html
I actually found exactly what I was looking for in this thread:
How to use encrypted password in apache BasicDataSource?
Here are the details from jasyp http://www.jasypt.org/spring3.html
This problem and solution to it is explained here..(link)
db.Properties.
#driverClassName=oracle.jdbc.driver.OracleDriver
#url=jdbc:oracle:thin:#localhost:1521:XE
#username=ITEM_INVENTORY
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/ITEM_INVENTORY?zeroDateTimeBehavior=convertToNull
username=root
Encrypt db.Properties
##password=cGFzc3dvcmQ=
password=cm9vdA==
The spring beans configuration for the datasource would look like this
(here you may use only password part)
spring-beans.xml
<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="db#[driverClassName]" />
<property name="url" value="db#[url]" />
<property name="username" value="db#[username]" />
<property name="password" value="encryptedDb#[password]" />
</bean>
<bean id="dbPropertyPlaceholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:db.properties</value>
</list>
</property>
<property name="placeholderPrefix" value="db#[" />
<property name="placeholderSuffix" value="]" />
</bean>
<bean id="encryptedDbPropertyPlaceholder" class="com.inventory.api.util.DecryptPropertyConfigurer">
<property name="locations">
<list>
<value>classpath:encryped_db.properties</value>
</list>
</property>
<property name="placeholderPrefix" value="encryptedDb#[" />
<property name="placeholderSuffix" value="]" />
</bean>
And so on.. please refer given link for more information..

Resources