This is to get some clarity on the JSON mapping of the generated JSON events in WSO2 CEP.
I configured two buckets for this. I have a string (Suresh 7 LeadSE) and I'm converting that into a JSON object. First bucket is getting the input string and I have written a siddhi extension to convert this into JSON.
The FirstBucket will get the input as String and converts it into a JSON and put it in a topic called parsedPacketTopic. Now I would like to get the individual elements from this JSON. I am trying to get this through the SecondBuket configuration. However, I don't know how to map the generated JSON value in the SecondBucket.
I am getting null values for the fields expInYears, empName, position and I don't know how exactly to map the generated JSON to these fields.
Can anyone help on this?
Code
FirstBucket configuration
<cep:input brokerName="localAgentBroker" topic="rawPacketTopic/1.0.0">
<cep:tupleMapping queryEventType="Tuple" stream="rawPacketStream">
<cep:property inputDataType="payloadData" inputName="rawPacket"
name="rawPacket" type="java.lang.String"/>
</cep:tupleMapping>
</cep:input>
<cep:query name="Queryfirst">
<cep:expression><![CDATA[from rawPacketStream[rawPacket!="null"]
insert into parsePacketStream customExtn:testFun(rawPacket) as pac]]>
</cep:expression>
<cep:output brokerName="activemqJmsBroker" topic="parsedPacketTopic">
<cep:mapMapping>
<cep:property name="parsedPac" valueOf="pac"/>
</cep:mapMapping>
</cep:output>
</cep:query>
Stream Definition of rawPacketTopic
{"streamId":"rawPacketTopic:1.0.0","name":"rawPacketTopic","version":"1.0.0","nickName":"PVT_Data","description":"PVT_Data","metaData":[{"name":"clientType","type":"STRING"}],"payloadData":[{"name":"rawPacket","type":"STRING"}]}
Stream Definition of parsedPacketTopic
{"streamId":"parsedPacketTopic:1.0.0","name":"parsedPacketTopic","version":"1.0.0","description":"PVTsinJson","metaData":[{"name":"ClientType","type":"STRING"}],"payloadData":[{"name":"parsedPac","type":"STRING"},
{"name":"expInYears","type":"INT"},{"name":"empName","type":"STRING"},{"name":"position","type":"STRING"}]}
i am getting the parsedPac json value as {"expInYears":7,"empName":"Suresh","position":"LeadSE"}
SecondBucket Configuration
<cep:input brokerName="activemqJmsBroker" topic="parsedPacketTopic">
<cep:mapMapping queryEventType="Tuple" stream="parsedPacketStream">
<cep:property inputDataType="payloadData" inputName="parsedPac" name="parsedPac" type="java.lang.String"/>
<cep:property inputDataType="payloadData" inputName="expInYears" name="expInYears" type="java.lang.Integer"/>
<!--<cep:property inputDataType="payloadData" inputName="empName" name="empName" type="java.lang.String"/>
<cep:property inputDataType="payloadData" inputName="position" name="position" type="java.lang.String"/>-->
</cep:mapMapping>
</cep:input>
<cep:query name="SecondQuery">
<cep:expression><![CDATA[from parsedPacketStream[parsedPac !="null"]
insert into displayPacketStream * ]]></cep:expression>
<cep:output brokerName="activemqJmsBroker" topic="displayTopic">
<!--<cep:mapMapping>
<cep:property name="expInYears" valueOf="expInYears"/>
<cep:property name="empName" valueOf="empName"/>
<cep:property name="position" valueOf="position"/>
</cep:mapMapping> -->
<cep:textMapping>Experience is - {expInYears}</cep:textMapping>
</cep:output>
</cep:query>
Stream Definition of displayTopic
{"streamId":"displayTopic:1.0.0","name":"displayTopic","version":"1.0.0","description":"PVTsinJson","metaData":[{"name":"ClientType","type":"STRING"}],
"payloadData":[{"name":"expInYears","type":"INT"},{"name":"empName","type":"STRING"},{"name":"position","type":"STRING"}]}
I think you are attempting JSON mapping which is not directly supported in WSO2 CEP 2.1.0.
If I understood your question correctly, I think you are converting the raw input into JSON from the extension in first cep bucket and then writing the second query based on that. However, since JSON input mapping is not directly supported, the second query will only see the whole string and not a JSON object.
Is there a specific requirement to convert the raw input to JSON in your scenario?
If not, using your custom extension, you can convert it to a CEP 2.1.0 supported format other than JSON (such as Map, Tuple, XML) which you should be able to process without any issues.
Another approach might be to send JSON converted events via the REST API as in documentation sample provided in [1]. This API will convert the JSON events to Tuple Events by default.
Anyway, JSON Input mapping will be supported from the next CEP 3.0.0 release.
[1] http://docs.wso2.org/wiki/display/CEP210/Build+Analyzer
HTH,
Related
In WSO2 Integration Studio Data Service project, I am extracting data from mongo database using find query. While showing an integer field in json format, I get the following error.
I have a field called 'RoomCount' and an integer type that returns a Mongo query result. I am getting error while converting this field to Json Format as below. When I am pulling string type data its work but integer,double.. doesnt work !
<query id="MunicipalBuildingDetails" useConfig="MongoDb">
<expression>collectionName.find()</expression>
<result outputType="json" escapeNonPrintableChar="true">{
Result:
{
Data:
[{
"Col1":"$document.RoomCount"
}
]
}
}</result>
</query>
Error is;
DS Fault Message: Error occurred when retrieving data. :JSONObject["RoomCount"] not a string.
How can I solve this?
This is another issue with the Mongo JSON conversion implementation. The values are always read as Strings. If you have any Integers rather than reading the element return the complete response and let the client handle it or handle it in the integration layer.
<query id="MunicipalBuildingDetails" useConfig="MongoDb">
<expression>collectionName.find()</expression>
<result outputType="json" escapeNonPrintableChar="true">{
Result:
{
Data:
[{
"Col1":"$document"
}
]
}
}</result>
</query>
Another alternative is to use the MongoDB connector. Also I'm not sure whether there is any option in MongoDB to always return values as Strings, may be worth checking that option as well.
I want to use BPMN Service Task and invoke a REST API.
I need to receive requests from the service ESB in format XML.
Example of request:
<?xml version="1.0" encoding="utf-8"?>
<reqSendEvent extrSystem="rout" typeEvent="newRout" xmlns="http://magnit.ru/tanderCoreMassageData.xsd">
<originTime>2017.08.25 15:12:00</originTime>
<content>
<rout>
<name>xxxxx</name>
</rout>
</content>
</reqSendEvent>
servicetask:
<serviceTask id="servicetask1" name="Service Task" activiti:class="org.wso2.developerstudio.bpmn.extensions.restTask.RESTTask">
<extensionElements>
<activiti:field name="serviceURL">
<activiti:expression><![CDATA[http://localhost:9773/tanderBPMN/services/servicetask1]]></activiti:expression>
</activiti:field>
<activiti:field name="method">
<activiti:string><![CDATA[POST]]></activiti:string>
</activiti:field>
<activiti:field name="headers">
<activiti:expression><![CDATA[Content-Type:text/xml]]></activiti:expression>
</activiti:field>
<activiti:field name="outputMappings">
<activiti:string><![CDATA[xxxxxx]]></activiti:string>
</activiti:field>
</extensionElements>
</serviceTask>
In all the examples, using JSON payloads. What do i write expression in to the outputMappings to get value from tag *//rout/name?
You should be able to use a simple String to hold the POST payload and map the parameter to the String.
Have you tried this?
Greg
I am a newbie to SOAP UI, I need to fetch a tag value from Test step response file (REST request's response) and set it as testsuite property.
My Request file looks like;
<xdata created_by="XXXX" created_at="Wed Mar 16 08:45:39 EDT 2016" app="" profile="" app_version="" env="DEV" tran="" service="1234">
<rows start_index="0">
<row basketId="1234566" basketVersionId="11" basketName="ORDERS_1505" basketDescription="ORDERS" createdUserName="XXXX" updatedUserName="XXX" __errorMsg="{"errors":[],"success":true}" totalApprovedOrderCount="0"/>
</rows>
</xdata>
I need to fetch basketVersionId attribute, please help.
Note: All the examples I read are dealing with Soap Response, property transfer using namespace and xpath. but that is not woking here I guess.
SOAPUI converts practically all to Xml, so despite the fact that you've a REST service you can use anyway and XPath in the property transfer testStep.
The only difference is that in property transfer you've to select:
ResponseAsXml as a property for the REST service with a Json response.
Response as a property for a SOAP service with Xml response.
So you can use: //*:row/#basketVersionId as XPath to get your attribute value.
Hope it helps,
I'm facing wso2 data service problem with simple query.
Expected query:
I want to use IN clause with multiple value. This is my sample query:
SELECT ORGANIZATION_ID, ORGANIZATION_NAME FROM ORGANIZATION WHERE ORGANIZATION_ID IN (?)
ORDER BY ORGANIZATION_NAME ASC
Getting error:
When i try web service using "1,2,3" value, i get javax.xml.stream.XMLStreamException error.
How can i write above query in WSO2 DSS?
Please advice me on that.
Thanks,
Eba
Refer the following data service query configuration which contains a sample input parameter of type "ARRAY" which you can effectively use to get your requirement fulfilled.
<query id="setSalaryForEmployeesQuery" useConfig="default">
<sql>update Employees set salary=:salary where employeeNumber in (:employeeNumbers)</sql>
<param name="salary" ordinal="1" paramType="SCALAR" sqlType="DOUBLE" type="IN"/>
<param name="employeeNumbers" ordinal="2" paramType="ARRAY" sqlType="INTEGER" type="IN"/>
</query>
There, if you refer the input mapping configuration named "employeeNumbers", it basically addresses the same requirement mentioned in your query.
To try this functionality, you can use the "tryIt" functionality provided with each data service(similar to other service types) and the data service request format corresponding to the aforementioned configuration would look like what's depicted below.
<p:setSalaryForEmployees xmlns:p="http://ws.wso2.org/dataservice/samples/rdbms_sample">
<!--Exactly 1 occurrence-->
<xs:salary xmlns:xs="http://ws.wso2.org/dataservice/samples/rdbms_sample">1000</xs:salary>
<!--1 or more occurrences-->
<xs:employeeNumbers xmlns:xs="http://ws.wso2.org/dataservice/samples/rdbms_sample">1011</xs:employeeNumbers>
<xs:employeeNumbers xmlns:xs="http://ws.wso2.org/dataservice/samples/rdbms_sample">1022</xs:employeeNumbers>
</p:setSalaryForEmployees>
The complete data service configuration which contains the above configuration snippet can be located in the "DSS_HOME/sample/dbs/rdbms/RDBMSSample.dbs" which resides in DSS product archive.
I need to create a mule service that will POST data to a web service that expects name/value pairs (not xml), then process the XML response from that service. I cannot find a good example on how to prep the payload for an http POST.
Can someone provide some insight or examples?
What I have so far is (I don't know if 'PathToTransformerClass' is needed):
<service name="myService">
<inbound>
<vm:inbound-endpoint path="myService.request" synchronous="true">
<custom-transformer class="PathToTransformerClass" />
</vm:inbound-endpoint>
</inbound>
<outbound>
<pass-through-router>
<http:outbound-endpoint address="URIofWebServiceToPostTo" method="POST" synchronous="true">
<response-transformers>
<custom-transformer class="PathToClassToProcessTheResponse" />
</response-transformers>
</http:outbound-endpoint>
</pass-through-router>
</outbound>
</service>
The following might be helpful: http://comments.gmane.org/gmane.comp.java.mule.user/29342
I can't find any examples either, but it looks like the built-in HTTP transformers are
http-response-to-object-transformer A
transformer that converts an HTTP
response to a Mule Message. The
payload may be a String, stream, or
byte array.
http-response-to-string-transformer
Converts an HTTP response payload
into a string. The headers of the
response will be preserved on the
message.
object-to-http-request-transformer
This transformer will create a valid
HTTP request using the current message
and any HTTP headers set on the
current message.
message-to-http-response-transformer
This transformer will create a valid
HTTP response using the current
message and any HTTP headers set on
the current message.
object-to-http-request-transformer might be your best bet; perhaps you can create a map of key-value pairs and then convert that into URL encoded form? Not sure but hopefully this gives you some things to Google.
Are you asking about how to take XML and create key value pairs to send out via HTTP? For that you can use an XLST transformer where in the XSL you set the method output to be text.
1) Let variables=<map><entry><string>idEvent_Type</string><string>1</string></entry></map>&options=user:admin
be the Map body to post as HTTP request.
2) URL encode it (eg. using http://meyerweb.com/eric/tools/dencoder/)
which produce :
variables%3D%3Cmap%3E%3Centry%3E%3Cstring%3EidEvent_Type%3C%2Fstring%3E%3Cstring%3E1%3C%2Fstring%3E%3C%2Fentry%3E%3C%2Fmap%3E%26options%3Duser%3Aadmin
3) then create a Mule set-payload transformer :
<set-payload value="variables%3D%3Cmap%3E%3Centry%3E%3Cstring%3EidEvent_Type%3C%2Fstring%3E%3Cstring%3E1%3C%2Fstring%3E%3C%2Fentry%3E%3C%2Fmap%3E%26options%3Duser%3Aadmin
" doc:name="Set playload"/>
4) then create a Mule HTTP endpoint :
<http:outbound-endpoint exchange-pattern="request-response" host="..." port="..." path="..." user="..." password="..." contentType="application/x-www-form-urlencoded" doc:name="POSTHTTPRequest"/>
and it works
Maybe U can give a try using Object-to-http-request-transformer as this transformer will create a valid HTTP request using the message currently received and any HTTP headers set on the current message.
Have never tried it, but that is the only transformer I can get in my mind after reading ur query...hope it works.. :D