Could you please advice how to get more than one row?
My API source:
<inSequence xmlns="http://ws.apache.org/ns/synapse">
<property expression="json-eval($.vendorId)" name="vendorId" scope="default" type="STRING"/>
<dblookup>
<connection>
<pool>
<dsName>MyDS</dsName>
</pool>
</connection>
<statement>
<sql><![CDATA[select * from db_view v where v.vendorId = nvl(?, v.vendorId)]]></sql>
<parameter expression="$ctx:vendorId" type="VARCHAR"/>
<result column="vendorId" name="vendorId"/>
<result column="vendorName" name="vendorName"/>
</statement>
</dblookup>
<filter xpath="boolean($ctx:vendorId)">
<then>
<payloadFactory media-type="json">
<format>{"result": { "vendorId" : "$1","vendorName" : "$2"}}</format>
<args>
<arg evaluator="xml" expression="$ctx:vendorId" literal="false"/>
<arg evaluator="xml" expression="$ctx:vendorName" literal="false"/>
</args>
</payloadFactory>
</then>
<else>
<payloadFactory media-type="json">
<format>{"response" : { "code" : "01","message" : "fail"}}</format>
</payloadFactory>
</else>
</filter>
</inSequence>
My db view returns 5 rows, but I get only the first row from the GET request:
{"result": { "vendorId" : "123", "vendorName" : "My Vendor N1" }}
Also if I pass the parameter vendorId = 321, the api should return 0 rows. At the current moment it ALWAYS returns the first row from view. Why and how to make it work?
Thanks in advance
CALLOUT Mediator:
<resource methods="GET" uri-template="/get/supplier/{filterQuery}">
<inSequence>
<property name="operation" value="view" scope="default" type="STRING"/>
<log level="full" separator="|">
<property name="operation" expression="get-property('operation')"/>
<property name="step" value="request"/>
</log>
<property name="filterQuery" expression="get-property('uri.var.filterQuery')" scope="default" type="STRING"/>
<log level="full" separator="|">
<property name="filterQuery" expression="$ctx:filterQuery"/>
</log>
<callout serviceURL="http://...:8280/services/serviceName" action="/vendors/$ctx:filterQuery">
<source type="envelope"/>
<target key="response"/>
</callout>
<log level="custom" separator="|">
<property name="MESSAGE" expression="$ctx:response"/>
</log>
<property name="res" expression="$ctx:response" scope="default" type="OM"/>
<property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
<property name="RESPONSE" value="true" scope="default" type="STRING"/>
<property name="messageType" value="application/json" scope="axis2" type="STRING"/>
<property name="contentType" value="application/json" scope="transport" type="STRING"/>
<payloadFactory media-type="json">
<format>{"vendorId": "$1","vendorName": "$2"}</format>
<args/>
</payloadFactory>
<log level="full" separator="|">
<property name="operation" expression="$ctx:operation"/>
<property name="step" value="response"/>
</log>
<respond/>
</inSequence>
<faultSequence>
<payloadFactory media-type="json">
<format>{"response" : {"code" : "01", "message" : "fail"}}</format>
<args/>
</payloadFactory>
</faultSequence>
</resource>
This is normal behavior. As you can read in DBLookup Mediator documentation :
The DBLookup mediator can set a property from one row in a result set. It cannot return multiple rows. If you need to get multiple records, or if you have a table with multiple parameters (such as URLs), you can use the WSO2 Data Services Server to create a data service and invoke that service from the ESB using the Callout mediator instead.
You can not use dblookup madiator as mentioned but you can use DataSources.
Brief datasource example for Get Method dataservice;
<data name="RDBMSDataService" serviceStatus="active" transports="http https local">
<config enableOData="false" id="Datasource">
<property name="driverClassName">com.mysql.jdbc.Driver</property>
<property name="url">jdbc:mysql://localhost:3306/Employees</property>
<property name="username">root</property>
<property name="password">password</property>
</config>
<resource method="GET" path="Employee/{EmployeeNumber}">
<call-query href="GetEmployeeDetails">
<with-param name="EmployeeNumber" query-param="EmployeeNumber"/>
</call-query>
</resource>
<query id="GetEmployeeDetails" useConfig="Datasource">
<sql>select EmployeeNumber, FirstName, LastName, Email, Salary from Employees where EmployeeNumber=:EmployeeNumber</sql>
<result outputType="json">{
"Employees":{
"Employee":[
{
"EmployeeNumber":"$EmployeeNumber",
"FirstName":"$FirstName",
"LastName":"$LastName",
"Email":"$Email",
"Salary":"$Salary"
}
]
}
}</result>
<param name="EmployeeNumber" sqlType="STRING"/>
</query>
</data>
You can create this .dbs file and deploy it. Then you can call this component like http://localhost:8290/services/RDBMSDataService/Employee/{EmployeeNumber} with specific parametres then it will return json :
{
"Employees": {
"Employee": [
{
"EmployeeNumber": "5012",
"FirstName": "Will",
"LastName": "Smith",
"Email": "will#smith.com",
"Salary": "13500.0"
},
{
"EmployeeNumber": "5013",
"FirstName": "Parker",
"LastName": "Peter",
"Email": "peter#parker.com",
"Salary": "15500.0"
}
]
}
}
You can take the value from context like :
<property expression="json-eval($.Employees)" name="EmployeeList" scope="default" type="STRING"/>
how can I extract RAW HL7message from XML SOAP (taken from DB) and use endpoint to send it to HL7://localhost:20101 server ?
I have this message body:
<soapenv:Body xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<row xmlns="SERVICE_HL7IN">
<DATA1>
MSH|^~\&|||||20210414014542.151+0200||MDM^T04^MDM_T02|401|T|2.5
</DATA1>
</row>
</soapenv:Body>
and I need to send this to endpoint:
MSH|^~\&|||||20210414014542.151+0200||MDM^T04^MDM_T02|401|T|2.5
Here is the sequence:
<sequence>
<log level="custom">
<property expression="$body" name="outbod"/>
</log>
<property expression="//xsi:row/xsi:DATA1" name="sendmsg" scope="default" type="STRING"/>
<log level="custom">
<property expression="get-property('sendmsg')" name="outb"/>
</log>
<property name="HL7_RESULT_MODE" scope="axis2" type="STRING" value="ACK"/>
<property expression="get-property('sendmsg')" name="body" scope="axis2" type="STRING"/>
<payloadFactory media-type="text">
<format>
$1
</format>
<args>
<arg expression="get-property('sendmsg')">
</arg>
</args>
</payloadFactory>
<property name="messageType" scope="axis2" type="STRING" value="application/edi-hl7"/>
<property name="contentType" scope="axis2" type="STRING" value="application/edi-hl7"/>
<log level="full" />
<send>
<endpoint>
<address uri="hl7://localhost:20101"/>
</endpoint>
</send>
</sequence>
Any help or advice is appretiated
I have a proxy service inlclued a sequence.
I process for authentication for proxy service with tag
<policy key="gov:/testPolicy"/>
<enableSec/>
In this sequence contain iterate mediator.
When call proxy service with authentication by soapUI then not reponse for client and have a error Unexpected error sending message back {org.apache.synapse.core.axis2.Axis2Sender} org.apache.axis2.AxisFault: No password supplied by the callback handler for the user : "wso2carbon"
If have not iterate mediator then have not error
This sequence
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="SendReceiveQueue" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<property expression="get-property('Edxml_Organ_Id')" name="senderUnitId" scope="default" type="STRING" xmlns:ns="http://org.apache.synapse/xsd"/>
<property expression="get-property('Edxml_Type')" name="applicationType" scope="default" type="STRING" xmlns:ns="http://org.apache.synapse/xsd"/>
<property expression="get-property('Edxml_Record_Code')" name="recordCode" scope="default" type="STRING" xmlns:ns="http://org.apache.synapse/xsd"/>
<property expression="$ctx:data_original" name="messagePl" scope="default" type="STRING" xmlns:edXML="http://www.mic.gov.vn/TBT/QCVN_102_2016" xmlns:ns="http://org.apache.synapse/xsd"/>
<property expression="$body" name="messagePlBody" scope="default" type="STRING" xmlns:edXML="http://www.mic.gov.vn/TBT/QCVN_102_2016" xmlns:ns="http://org.apache.synapse/xsd"/>
<property name="QUEUE_ACTION_TYPE" scope="default" type="STRING" value="SENDER"/>
<log level="custom">
<property expression="get-property('messagePl')" name="messagePllogging" xmlns:ns="http://org.apache.synapse/xsd"/>
<property expression="get-property('messagePlBody')" name="messagePlloggingBody" xmlns:ns="http://org.apache.synapse/xsd"/>
</log>
<iterate expression="$ctx:abc//edXML:To" id="abc" sequential="true" xmlns:edXML="http://www.mic.gov.vn/TBT/QCVN_102_2016" xmlns:ns="http://org.apache.synapse/xsd" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<target>
<sequence>
<log level="custom">
<property name="goi DSS" value="-------------------------------------------"/>
<property expression="//edXML:To/edXML:OrganId/text()" name="queue name"/>
</log>
<payloadFactory media-type="xml">
<format>
<p:getQueueId xmlns:p="http://ws.wso2.org/dataservice">
<xs:in_unitId xmlns:xs="http://ws.wso2.org/dataservice">$1</xs:in_unitId>
<xs:in_b2bType xmlns:xs="http://ws.wso2.org/dataservice">$2</xs:in_b2bType>
</p:getQueueId>
</format>
<args>
<arg evaluator="xml" expression="//edXML:To/edXML:OrganId/text()"/>
<arg evaluator="xml" expression="syn:get-property('Edxml_Type')"/>
</args>
</payloadFactory>
<call blocking="true">
<endpoint>
<address uri="http://cqdt-app3:8280/services/validateData"/>
</endpoint>
</call>
<property expression="//x:returnCode/x:MessageQueueId/text()" name="queue_name" scope="default" type="STRING" xmlns:x="http://ws.wso2.org/dataservice"/>
<log level="custom">
<property name="lay xong tu dss" value="-------------------------------------------"/>
<property expression="$ctx:queue_name" name="ten queue lay ra"/>
</log>
<class name="com.vsc.ReceiveQueue">
<property name="password" value="admin"/>
<property name="queueName" value="testQueue1"/>
<property name="CF_NAME_PREFIX" value="connectionfactory."/>
<property name="CF_NAME" value="QueueConnectionFactory"/>
<property name="QPID_ICF" value="org.wso2.andes.jndi.PropertiesFileInitialContextFactory"/>
<property name="CARBON_DEFAULT_HOSTNAME" value="cqdt-app3"/>
<property name="QUEUE_NAME_PREFIX" value="queue."/>
<property name="userName" value="admin"/>
<property name="CARBON_CLIENT_ID" value="carbon"/>
<property name="CARBON_DEFAULT_PORT" value="5675"/>
<property name="CARBON_VIRTUAL_HOST_NAME" value="carbon"/>
</class>
<log level="custom">
<property name="put xong vao queue" value="-------------------------------------------"/>
<property expression="$ctx:queue_name" name="ten queue ban xong"/>
</log>
<payloadFactory media-type="xml">
<format>
<response>
<result>SUCCESS</result>
</response>
</format>
<args/>
</payloadFactory>
<property name="RESPONSE" scope="default" type="STRING" value="true"/>
<property name="messageType" scope="axis2" type="STRING" value="application/xml"/>
<property action="remove" name="NO_ENTITY_BODY" scope="axis2"/>
<header action="remove" name="To" scope="default"/>
<send/>
</sequence>
</target>
</iterate>
<property name="RESPONSE" scope="default" type="STRING" value="true"/>
<header action="remove" name="To" scope="default"/>
<log level="custom">
<property expression="get-property('messagePl')" name="1111555555555555555555555555551111111111111111111111111111111-------------------------------" xmlns:ns="http://org.apache.synapse/xsd"/>
</log>
</sequence>
Please help me!
Have you tried applying the policy on the endpoint directly?
<endpoint xmlns="http://ws.apache.org/ns/synapse" name="TQBsEndpoint">
<address uri="http://cqdt-app3:8280/services/validateData" format="soap11">
<enableSec policy="gov:testPolicy"/>
</address>
</endpoint>
I written custom mediator and its working fine I am passing the values to my class mediator using insequence like this
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="tReadingMobile_5"
transports="https http"
startOnLoad="true"
trace="disable">
<description/>
<target>
<inSequence onError="fault">
<property name="FORCE_ERROR_ON_SOAP_FAULT" value="true"/>
<property name="Reading"
expression="//Readings"
scope="default"
type="STRING"/>
<property name="actiondetailid"
expression="//actiondetailid/text()"
scope="default"
type="STRING"/>
<property name="actionid"
expression="//actionid/text()"
scope="default"
type="STRING"/>
<property name="userid"
expression="//userid/text()"
scope="default"
type="STRING"/>
<property name="assetid"
expression="//assetid/text()"
scope="default"
type="STRING"/>
<property name="partybranchid"
expression="//partybranchid/text()"
scope="default"
type="STRING"/>
<property name="activityid"
expression="//activityid/text()"
scope="default"
type="STRING"/>
<property name="clientid"
expression="//clientid/text()"
scope="default"
type="STRING"/>
<property name="ouid"
expression="//ouid/text()"
scope="default"
type="STRING"/>
<log level="custom">
<property name="fff" expression="get-property('Reading')"/>
<property name="ggggg" expression="get-property('actiondetailid')"/>
<property name="hhhh" expression="get-property('actionid')"/>
<property name="partybranchid" expression="get-property('partybranchid')"/>
</log>
<iterate continueParent="true"
id="Readings"
expression="//ReadingsLiteTaildto">
<target>
<sequence>
<property name="actiondetailid" expression="get-property('actiondetailid')"/>
<property name="parameterid" expression="//ParameterId/text()"/>
<property name="slno" expression="//SlNo/text()"/>
<property name="inputvalue" expression="//InputValue/text()"/>
<property name="inputtext" expression="//InputText/text()"/>
<property name="finalvalue" expression="//FinalValue/text()"/>
<payloadFactory>
<format>
<p:insert_treadings_operation xmlns:p="http://ws.wso2.org/dataservice">
<xs:actiondetailid xmlns:xs="http://ws.wso2.org/dataservice">$1</xs:actiondetailid>
<xs:slno xmlns:xs="http://ws.wso2.org/dataservice">$2</xs:slno>
<xs:parameterid xmlns:xs="http://ws.wso2.org/dataservice">$3</xs:parameterid>
<xs:inputvalue xmlns:xs="http://ws.wso2.org/dataservice">$4</xs:inputvalue>
<xs:inputtext xmlns:xs="http://ws.wso2.org/dataservice">$5</xs:inputtext>
<xs:finalvalue xmlns:xs="http://ws.wso2.org/dataservice">$6</xs:finalvalue>
</p:insert_treadings_operation>
</format>
<args>
<arg expression="get-property('actiondetailid')"/>
<arg expression="get-property('slno')"/>
<arg expression="get-property('parameterid')"/>
<arg expression="get-property('inputvalue')"/>
<arg expression="get-property('inputtext')"/>
<arg expression="get-property('finalvalue')"/>
</args>
</payloadFactory>
<send receive="tReadingsid_Seq">
<endpoint>
<address uri="http://localhost:9764/services/treadings_DataService/"
format="soap11"/>
</endpoint>
</send>
</sequence>
</target>
</iterate>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
<property xmlns:ns="http://org.apache.synapse/xsd"
name="Time"
expression="get-property('SYSTEM_TIME')"
scope="default"
type="STRING"/>
<property name="actiondetailid"
expression="get-property('actiondetailid')"
scope="default"
type="STRING"/>
<property name="OUT_ONLY" value="true"/>
<property name="dbconnectionurl"
value="jdbc:postgresql://$$$$$$$$$$/*****"/>
<property name="dbuser" value="##########"/>
<property name="dbpassword" value="*******"/>
<class name="in.youtility.esb.custommediators.ReadingAlertMediator"/>
<property name="Message"
expression="get-property('Message')"
scope="default"
type="STRING"/>
</inSequence>
<outSequence onError="fault"/>
</target>
</proxy>
The Message property is define inside the class
So i wish retrieve it from out side class means insequence
Is it possible in wso2esb or not if i get this property out of class then i will get scenario
Yes. It is possible. It will work as a normal property which you can refer at any place after you get the return value from class mediator.
You can get the property 'Message' as you have mentioned but before that you need to assign the result to the property 'Message'.
See the following sample of assign the result,
<class name="in.youtility.esb.custommediators.ReadingAlertMediator">
<property name="target" value="Message"/>
</class>
Here is my proxy code:
<proxy xmlns="http://ws.apache.org/ns/synapse" name="ProviderPublication" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
<target>
<inSequence>
<filter xmlns:p="http://www.openoandm.org/xml/ISBM/" xpath="//p:OpenPublicationSession">
<then>
<property xmlns:xs="http://www.openoandm.org/xml/ISBM/" name="ChannelURI" expression="//xs:ChannelURI" scope="default" type="STRING"/>
<class name="wso2.org.Communicator.OpenPublication">
<property name="channelURI" value="myChannelURI"/>
</class>
**<property name="sessionIDFromClassMediator" expression="get-property('SessionID')" scope="default" type="STRING"/>**
<header name="To" action="remove"/>
<property name="RESPONSE" value="true" scope="default" type="STRING"/>
<property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
<payloadFactory>
<format>
<ns1:OpenPublicationSessionResponse xmlns:ns1="http://www.openoandm.org/xml/ISBM/">
<ns1:SessionID>$1</ns1:SessionID>
</ns1:OpenPublicationSessionResponse>
</format>
<args>
<arg expression="get-property('sessionIDFromClassMediator')"/>
</args>
</payloadFactory>
<send/>
</then>
<else>
<filter xpath="//p:PostPublication">
<then>
<property xmlns:xs="http://www.openoandm.org/xml/ISBM/" name="SessionID" expression="//xs:SessionID" scope="default" type="STRING"/>
<property xmlns:xs="http://www.openoandm.org/xml/ISBM/" name="Topic" expression="//xs:Topic" scope="default" type="STRING"/>
<property xmlns:xs="http://www.openoandm.org/xml/ISBM/" name="Expiry" expression="//xs:Expiry" scope="default" type="STRING"/>
<property xmlns:ns="http://www.openoandm.org/xml/ISBM/" name="MessageContent" expression="//MessageContent" scope="default" type="STRING"/>
<class name="wso2.org.postPublication.PostPublication">
<property name="topic" value="Sports"/>
<property name="sessionID" value="session_001"/>
<property name="messagecontent" value="Cricket on air"/>
<property name="expiry" value="Monday"/>
</class>
<property name="getMessageIDFromClassMed" expression="get-property('MessageID')" scope="default" type="STRING"/>
<log level="full">
**<property name="SessionIDFromFstFltr" expression="get-property('sessionIDFromClassMediator')"/>**
</log>
I AM NOT ABLE TO GET THE PROPERTY VALUE OF sessionIDFromClassMediator SO MY FILTER NEVER GETS TRUE AND CAN'T GET INSIDE THE FILTER
**<filter xpath="get-property('sessionIDFromClassMediator') = get-property('SessionID')">
<then>
<log level="custom">
<property name="STATE" value="message is sent to queue"/>
</log>
<property name="OUT_ONLY" value="true"/>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
<header name="To" action="remove"/>
<property name="RESPONSE" value="true" scope="default" type="STRING"/>
<property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
<payloadFactory>
<format>
<ns1:PostPublicationResponse xmlns:ns1="http://www.openoandm.org/xml/ISBM/">
<ns1:MessageID>$1</ns1:MessageID>
</ns1:PostPublicationResponse>
</format>
<args>
<arg expression="get-property('getMessageIDFromClassMed')"/>
</args>
</payloadFactory>
<send/>
</then>
<else>
<log level="full">
<property name="FilterNotRunning" value="----------FilterNotRunning------------------"/>
</log>
<drop/>
</else>
</filter>**
</then>
<else>
<drop/>
</else>
</filter>
</else>
</filter>
</inSequence>
<endpoint>
<address uri="jms:/myQueue?&transport.jms.DestinationType=queue"/>
</endpoint>
So i want to get the value of <property name="sessionIDFromClassMediator" expression="get-property('SessionID')" scope="default" type="STRING"/> so that i can use this property value to match with Other Property after
<class name="wso2.org.postPublication.PostPublication">
<property name="topic" value="Sports"/>
<property name="sessionID" value="session_001"/>
<property name="messagecontent" value="Cricket on air"/>
<property name="expiry" value="Monday"/>
</class>
and after that i am sending message to Message broker but before that i want to associate a payload which should be send to the queue of message broker. I want to implement payload inside
I AM NOT ABLE TO GET THE PROPERTY VALUE OF sessionIDFromClassMediator SO MY FILTER NEVER GETS TRUE AND CAN'T GET INSIDE THE FILTER
**<filter xpath="get-property('sessionIDFromClassMediator') = get-property('SessionID')">
<then>
<log level="custom">
<property name="STATE" value="message is sent to queue"/>
</log>
<property name="OUT_ONLY" value="true"/>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
<header name="To" action="remove"/>
<property name="RESPONSE" value="true" scope="default" type="STRING"/>
<property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
<payloadFactory>
<format>
<ns1:PostPublicationResponse xmlns:ns1="http://www.openoandm.org/xml/ISBM/">
<ns1:MessageID>$1</ns1:MessageID>
</ns1:PostPublicationResponse>
</format>
<args>
<arg expression="get-property('getMessageIDFromClassMed')"/>
</args>
</payloadFactory>
<send/>
</then>
<else>
<log level="full">
<property name="FilterNotRunning" value="----------FilterNotRunning------------------"/>
</log>
<drop/>
</else>
</filter>**
part.THE MAIN PROBLEM IS THAT THE FIRST FILTER IS EXECUTED WHEN I ENVOKE OPERATION OPENPUBLICATION, AND WHEN I ENVOKE THE SECOND OPERATION ALL THE PROPERTY VALUE GET RESET. SO HOW CAN I MAKE PROPERTY VALUE PERSISTENT SO THAT IT IS NEVER LOST? Hope you understand my question and looking forward to your solutions. Thanks in advance
Try to add some logs of your property to see if it is there or not:
<log level="custom">
<property name="your property" expression="get-property('sessionIDFromClassMediator'))"/>
</log>
Keep in mind the different levels of the properties (transport, axis2, axis2-client).
I also had quite some problems with the filter mediator using the xpath attribute. I don't use it anymore and always use the combination of "source" and "regex".
Example:
<filter source="$body/anElementInTheBody" regex="true">
So for your case you can create an additional property (just before the filter) that will contain the boolean value if it should be filtered or not. Then with the regex=true you will enter the filter.
This is just a pseudo code of your example - maybe need some corrections:
<property name="filterCondition" expression="get-property('sessionIDFromClassMediator') = get-property('SessionID')"/>
<filter source="get-property('filterCondition')" regex="true">