I am stuck on below,
I have set content type as XML in my proxy.
As below:
<parameter name="transport.jms.ContentType">
<rules xmlns="">
<jmsProperty>contentType</jmsProperty>
<default>application/xml</default>
</rules>
</parameter>
Sending below message into the queue which is correct one
<Data>
<name>abc</name>
<account>1212</account>
</Data>
But if any tag is missing in it as below. I dont want lose that message instead I want it to store in one special queue
<Data>
<name>abc
<account>1212</account>
Any guidance will be appreciated.Thanks
Related
I am trying to get data from a webservice to put in a SSRS report.
Here is a dataset that works with a simple string parameter (The parameter is set in dataset properties):
<Query xmlns="http://tempuri.org/">
<Method Name="ValidateUserWSToken" Namespace="http://tempuri.org/" />
<SoapAction>http://tempuri.org/WSTokenService/ValidateUserWSToken</SoapAction>
</Query>
Here is a similar method that expects a complextype for it's parameter
<Query>
<Method Name="GetUserWSToken" Namespace="http://tempuri.org/"/>
<SoapAction>http://tempuri.org/WSTokenService/GetUserWSToken</SoapAction>
</Query>
Putting the parameter in the dataset properties as
<UserName>username</UserName><Password>password</Password>
gives the error "There was an error trying to deserialize parameter http://tempuri.org/:request. The InnerException message was 'Error in line 5 position 20. Expected state 'Element'.. Encountered "text" with name '', namespace ''.'.". I don't think setting this in dataset properties will work.
I have tried variations on the following to try to put the parameter in the query text
<Query>
<Method Name="GetUserWSToken" Namespace="http://tempuri.org/" />
<SoapAction>http://tempuri.org/WSTokenService/GetUserWSToken</SoapAction>
<Parameters>
<Parameter Name="request" type="xml">
<DefaultValue xmlns:a="some namespace">
<a:Password>password</a:Password>
<a:UserName>username</a:UserName>
</DefaultValue>
</Parameter>
</Parameters>
</Query>
but these all fail with a 500 error - "Object reference not set to an instance of an object.", presumably because the webservice is not finding the parameter or finding it is null.
Here is the XML that SoapUI produces (and works)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:civ="some namespace">
<soapenv:Header/>
<soapenv:Body>
<tem:GetUserWSToken>
<!--Optional:-->
<tem:request>
<civ:Password>password</civ:Password>
<civ:UserName>username</civ:UserName>
</tem:request>
</tem:GetUserWSToken>
</soapenv:Body>
</soapenv:Envelope>
Can this be converted into something I can use in SSRS query text?
This works:
<Query>
<Method Name="GetUserWSToken" Namespace="http://tempuri.org/">
<Parameters>
<Parameter Name="request" Type="XML" xmlns="some namespace">
<DefaultValue>
<Password>password</Password>
<UserName>username</UserName>
</DefaultValue>
</Parameter>
</Parameters>
</Method>
<SoapAction>http://tempuri.org/WSTokenService/GetUserWSToken</SoapAction>
<ElementPath IgnoreNamespaces="true">*</ElementPath>
</Query>
and this is what it is converted to:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetUserWSToken xmlns="http://tempuri.org/">
<request><Password xmlns="some namespace">Password123</Password><UserName xmlns="some namespace">FifeIntegrationUser</UserName></request>
</GetUserWSToken>
</soap:Body>
</soap:Envelope>
Please someone could help. I have a set of data as csv(from excel multiple sheets i have formed csv)just i want to insert those data into multiple table depends the sheets of an excel.
please help me to sort out my issues.
I expected those csv in each iteration to form xml.
First, we can build the XML from CSV data and iterate through the XML. Please find a sample config below. In this sample, it will pick the CSV files from the source directory and process.
Smooks Config:
<?xml version="1.0"?>
<smooks-resource-list
xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd"
xmlns:csv="http://www.milyn.org/xsd/smooks/csv-1.2.xsd">
<resource-config selector="org.xml.sax.driver">
<resource>org.milyn.csv.CSVReader</resource>
<param name="fields">firstname,lastname,gender,age,country</param>
<param name="rootElementName">people</param>
<param name="recordElementName">person</param>
</resource-config>
</smooks-resource-list>
Proxy:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="CSVToXML"
transports="https,http,vfs"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<smooks config-key="conf:/repository/smooks-config.xml">
<input type="text"/>
<output type="xml"/>
</smooks>
<!-- Here iterate through the XML -->
</inSequence>
<outSequence/>
</target>
<parameter name="transport.PollInterval">1000</parameter>
<parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter>
<parameter name="Operation">urn:placeOrder</parameter>
<parameter name="transport.vfs.FileURI">file://<SOURCE_DIR></parameter>
<parameter name="transport.vfs.MoveAfterProcess">file://<PROCESSED_FILES_DIR></parameter>
<parameter name="transport.vfs.MoveAfterFailure">file://<FAILED_FILES_DIR></parameter>
<parameter name="transport.vfs.FileNamePattern">.*\.csv</parameter>
<parameter name="transport.vfs.ContentType">text/plain</parameter>
<parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
<description/>
</proxy>
References:
1. https://docs.wso2.com/display/EI640/VFS+Transport
2. https://docs.wso2.com/display/EI640/Smooks+Mediator
3. https://docs.wso2.com/display/EI640/Iterate+Mediator
Currently working for a company on wso2 integrator, I need to retrieve files periodically created into a directory so that they can be processed, modified and sent to a remote API.
The problem is that we need to use wso2 exclusively and absolutely can't code side programs to adapt to the situation. We can use script though only if they are embedded within wso2.
Does someone have a clue?
This is a simple synapse configuration that:
Wait for incoming CSV files on a given directory
Convert its contents to XML
Do some transformation on its elements
Sends the result to a another endpoint (an output directory in this case)
I hope it helps to get you going (comments inline):
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://ws.apache.org/ns/synapse">
<!-- ======================================== -->
<!-- Smooks configuration to parse sample CSV -->
<!-- ======================================== -->
<localEntry key="smooks-orders-csv">
<smooks-resource-list
xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd" xmlns:csv="http://www.milyn.org/xsd/smooks/csv-1.2.xsd">
<resource-config selector="org.xml.sax.driver">
<resource>org.milyn.csv.CSVReader</resource>
<param name="fields">OrderId,SKU,Quantity,UnitPrice,TotalPrice</param>
<param name="skip-line-count">1</param> <!-- Skip Header line -->
<param name="rootElementName">orders</param>
<param name="recordElementName">order</param>
</resource-config>
</smooks-resource-list>
</localEntry>
<!-- ====================================================== -->
<!-- XML processing logic: Replaces SKU number 0002 to 0003 -->
<!-- ====================================================== -->
<localEntry key="change-sku">
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="SKU/text()[.='0002']">0003</xsl:template>
</xsl:stylesheet>
<description/>
</localEntry>
<!-- *********************** -->
<!-- Process Orders sequence -->
<!-- *********************** -->
<sequence name="process_orders" onError="fault" statistics="enable" trace="enable">
<!-- Convert incoming file into a stream of orders -->
<smooks config-key="smooks-orders-csv">
<input type="text"/>
<output type="xml"/>
</smooks>
<!-- General Synapse properties that must be set for a One-Way exchange pattern -->
<property name="FORCE_SC_ACCEPTED" scope="axis2" value="true"/>
<property name="OUT_ONLY" value="true"/>
<!-- VFS send will fail unless you remove this property -->
<property action="remove" name="ClientApiNonBlocking" scope="axis2"/>
<!-- The "magic" property 'transport.vfs.ReplyFileName' is used by the VFS transport to define output file name
when the specified URI is a directory
-->
<property
expression="fn:concat(fn:substring-after(get-property('MessageID'), 'urn:uuid:'), '.xml')"
name="transport.vfs.ReplyFileName" scope="transport" xmlns:ns="http://org.apache.synapse/xsd"/>
<!-- Create output file -->
<send>
<endpoint>
<address format="pox" uri="vfs:file:///mnt/c/transfer/out"/>
</endpoint>
</send>
</sequence>
<!-- Inbound polling endpoint -->
<inboundEndpoint name="received_orders" onError="fault"
protocol="file" sequence="process_orders" suspend="false">
<parameters>
<parameter name="interval">1000</parameter>
<parameter name="sequential">true</parameter>
<parameter name="coordination">true</parameter>
<!-- Input directory -->
<parameter name="transport.vfs.FileURI">file:///mnt/c/transfer/in</parameter>
<!-- CSV files are plain text messages -->
<parameter name="transport.vfs.ContentType">text/plain</parameter>
<!-- RegExp used to filter files in input directory -->
<parameter name="transport.vfs.FileNamePattern">.*\.txt</parameter>
<parameter name="transport.vfs.Locking">disable</parameter>
<!-- Move processed files to the 'processed' subdirectory -->
<parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter>
<parameter name="transport.vfs.MoveAfterProcess">file:///mnt/c/transfer/in/processed</parameter>
<!-- Move failed files to the 'rejected subdirectory -->
<parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
<parameter name="transport.vfs.MoveAfterFailure">file:///mnt/c/transfer/in/rejected</parameter>
<parameter name="transport.vfs.AutoLockRelease">true</parameter>
<parameter name="transport.vfs.LockReleaseSameNode">false</parameter>
<parameter name="transport.vfs.DistributedLock">false</parameter>
<parameter name="transport.vfs.FileSortAttribute">NONE</parameter>
<parameter name="transport.vfs.FileSortAscending">true</parameter>
<parameter name="transport.vfs.CreateFolder">true</parameter>
<parameter name="transport.vfs.Streaming">false</parameter>
<parameter name="transport.vfs.Build">false</parameter>
</parameters>
</inboundEndpoint>
</definitions>
I'm send ISO8583 message from testclient to my inbound,
i have the log console :
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Body>
<ISOMessage xmlns="http://ws.apache.org/ns/synapse">
<data>
<field id="0">0200</field>
<field id="3">568893</field>
<field id="4">000000020000</field>
<field id="7">0110563280</field>
<field id="11">456893</field>
<field id="44">DFGHT</field>
<field id="105">ABCDEFGHIJ 1234567890</field>
</data>
</ISOMessage>
</soapenv:Body>
</soapenv:Envelope>
Response From Server :ISOMessage from pool-28-thread-1 is consumed :
0210B220000002100000000000000080000056892300000010050001105632804568930005KAMAL021ABCDEFGHIJ 1234567890
how to change response from server, for example i want to change field id 105 from <field id="105">ABCDEFGHIJ 1234567890</field> to <field id="105">xxxxxxxxxx 000000000</field>
I don't know how to alter data and send it back to client.
I search on wso2 documentation, how to respond message in inbound, but I can't find anything.
how to handle incoming ISOMessage, alter it, and send it back to client?
Do we need create connector or just simply modify data in sequence?
thanks
You can simply modify the XML within the sequence. Once you received the message you can modify it using the Enrich Mediator as follows (You need to specify the proper XPath to identity the element to change).
Once the response is modified, you can use Send mediator to send it to a
<!-- todo: receive the message -->
<property name="newValue" value="xxxxxxxxxx 000000000"/>
<enrich>
<source type="property" clone="true" property="newValue"/>
<target xpath="$body/*[1]/*[1]/*[7]"/>
</enrich>
<log>
<property name="message" expression="$body"/>
</log>
<!-- todo: send the message -->
The following is the sample XML structure I'm working on:
<command name="test">
<parameter index="2">4000</parameter>
<tag>4000</tag>
<parameter index="3">tag</parameter>
<parameter index="4">4000</parameter>
</command>
<command name="test">
<parameter index="2">4000</parameter>
<add>
<parameter index="1">ports</parameter>
<parameter index="2">1:1,</parameter>
<parameter index="3">3:1,</parameter>
<parameter index="4">3:9-12,</parameter>
<parameter index="5">4:12</parameter>
</add>
<parameter index="3">add</parameter>
<parameter index="4">ports</parameter>
<parameter index="5">1:1,</parameter>
<parameter index="6">3:1,</parameter>
<parameter index="7">3:9-12,</parameter>
<parameter index="8">4:12</parameter>
<tagged />
<parameter index="9">tagged</parameter>
</command>
And the code snippet on the XSL file is:
<xsl:key name="key" match="command[#name='test'][count(tag) > 0]" use="parameter[#index='2']"/>
<xsl:key name="port" match="command[#name='test'][count(add) > 0]" use="add/parameter"/>
<xsl:template match="xyz">
<xsl:variable name="portid" select="concat($slot-no,concat(':',$port-no))"/>
<xsl:apply-templates select="key('port',$portid)"/>
</xsl:template>
<xsl:template match="command[#name='test']">
<xsl:variable name="name" select="parameter[#index=2]"/>
<object>
<name><xsl:value-of select="$name"/></name>
<class>XYZ</class>
<attributes>
<attribute>
<name>XYZ1</name>
<value><xsl:value-of select="key('key',$name)/tag"/></value>
</attribute>
</attributes>
</object>
</xsl:template>
The variable 'portid' is in the form 'x:x', where x is a number. For each of the portid, I need to associate with the <parameter index="2"> value. Previously we had only one portid value under the <add> node and the solution was working fine.
Now, I need to change the 'use' expression in the XSL key 'port' so that the values are changed from '1:1,' to '1:1' and similarly '3:1,' to '3:1' and expand '3:9-12,' to '3:9' , '3:10' , '3:11' , '3:12' and store them with the value in <parameter index="2">. For example, each time the 'portid' is any one of this '1:1', '3:1', '3:9' , '3:10' , '3:11', '3:12' and '4:12', the value to associate is '4000'.
Is this possible? I'm working on this for a week and still not able to find a solution. Any help would be really appreciated. Thanks a lot guys.
I think you can only do that cleanly with XSLT 2.0 e.g.
<xsl:key name="port" match="command[#name='test'][add]" use="add/parameter/replace(., ',', '')"/>
will do for the simply replacement, for the more complex one you will probably have to write a function with xsl:function that takes e.g. '3:9-12,' and returns the sequence you want, that shouldn't be to difficult with XPath 2.0's string functions.
I was able to find the solution for this problem by not using the XSL key. Instead I used a call-template method to strip the commas and expand the series and find the match. Thanks to all who cared to help me on this