Using WSO2 DSS 3.5.1 I'd like to find a JSON format for inserting multiple records
having resource
<resource method="POST" path="/insert/count">
<call-query href="insert_rawdata">
<with-param name="timeslot" query-param="timeslot" />
<with-param name="cell_id" query-param="cell_id" />
</call-query>
</resource>
and query
<query id="insert_rawdata" useConfig="PG_DB">
<sql>INSERT INTO mobile_data ( date_time , timeslot , cell_id )
VALUES (
NOW()::timestamp, :timeslot::timestamp with time zone, :cell_id )
ON CONFLICT (timeslot, cell_id) DO NOTHING </sql>
<param name="timeslot" sqlType="STRING" type="IN"/>
<param name="cell_id" sqlType="INTEGER" type="IN"/>
</query>
it's pretty straightfoward to POST multiple records with XML
<test_list>
<data>
<timeslot>2017-11-13 14:00</timeslot>
<cell_id>1234</cell_id>
</data>
<data>
<timeslot>2017-11-13 14:00</timeslot>
<cell_id>1235</cell_id>
</data>
</test_list>
Reading the documentation https://docs.wso2.com/display/DSS351/Using+JSON+Messages+with+RESTful+Services looks useful, however seems the documentation is not right
according to the documentation the JSON object should be _post$RESOURCE, but it's _post_$RESOURCE
working POST request:
{
"_post_insert_count" : {
"timeslot": "2017-11-13 14:00",
"cell_id": 1234
}
}
however I am unable to find correct JSON syntax/format to POST (insert) multiple records with single request, according to the documentation should be
{ "_post_insert_count_batch_req": {
"_post_insert_count": [
{
"timeslot": "2017-11-13 14:00",
"cell_id": 1234
} ,
{
"timeslot": "2017-11-13 14:00",
"cell_id": 1235
}]
}
then I got an exception
java.lang.NullPointerException
at org.apache.axis2.json.gson.GsonXMLStreamReader.validateArgumentTypes(GsonXMLStreamReader.java:783)
at org.apache.axis2.json.gson.GsonXMLStreamReader.nextValue(GsonXMLStreamReader.java:734)
at org.apache.axis2.json.gson.GsonXMLStreamReader.readValue(GsonXMLStreamReader.java:626)
so - someone could help to build a valid JSON request for inserting multiple records?
Thanks for any hint
working example:
{
"_post_insert_items_batch_req": {
"_post_insert_items": [{
"timestamp": "2017-11-13 14:00:00",
"school": "Regina Pace",
"eventid": 1234
},
{
"timestamp": "2017-11-13 14:00:00",
"school": "Regina Pace",
"evenid": 1235
}
]
}
}
which is strange as last time I had NPE from similar request, so I don't really understand where's the problem
Related
i need little help about how the request field when no value or optional with condition can print at response. i have request json message and want convert to xml with wso2.
sample request
"AppHdr" : {
"Fr" : {
"FIId" : {
"FinInstnId" : {
"Othr" : {
"Id" : "FASTIDJA"
}
}
}
},
"To" : {
"FIId" : {
"FinInstnId" : {
"Othr" : {
"Id" : "INDOIDJA"
}
}
}
},
"BizMsgIdr" : "20210301FASTIDJA010HRB12345678",
"MsgDefIdr" : "pacs.002.001.10",
"BizSvc" : "",
"CreDt" : "2021-03-01T12:00:00",
"CpyDplct" : "",
"PssblDplct" : "",
"Sgntr" : ""
},
the result response need to fix was like this
<ns:AppHdr>
<ns1:Fr>
<ns1:FIId>
<ns1:FinInstnId>
<ns1:Othr>
<ns1:Id>FASTIDJA</ns1:Id>
</ns1:Othr>
</ns1:FinInstnId>
</ns1:FIId>
</ns1:Fr>
<ns1:To>
<ns1:FIId>
<ns1:FinInstnId>
<ns1:Othr>
<ns1:Id>INDOIDJA</ns1:Id>
</ns1:Othr>
</ns1:FinInstnId>
</ns1:FIId>
</ns1:To>
<ns1:BizMsgIdr>20210301FASTIDJA010HRB12345678</ns1:BizMsgIdr>
<ns1:MsgDefIdr>pacs.002.001.10</ns1:MsgDefIdr>
<ns1:CreDt>2021-03-01T12:00:00Z</ns1:CreDt>
</ns:AppHdr>
need hint for my case like this. thanks
You could use XSLT to convert from JSON to XML. [1][2]
Normally people want to eliminate empty tags and you know they are possible from the Schema. But in instances where you want an empty tag you can use the attribute xls:nil=true feature. [3]
[1] https://docs.wso2.com/display/EI660/Sample+440%3A+Converting+JSON+to+XML+Using+XSLT
[2] https://docs.wso2.com/display/EI660/XSLT+Mediator+
[3] https://www.ibm.com/support/pages/how-set-empty-element-attribute-xslniltrue-using-xslt
The easiest way to convert a JSON to XML is by setting the messageType property. For example, check the below.
<property name="messageType" scope="axis2" type="STRING" value="application/xml"/>
Setting the above property alone will Convert your Json to the following XML.
<AppHdr>
<Fr>
<FIId>
<FinInstnId>
<Othr>
<Id>FASTIDJA</Id>
</Othr>
</FinInstnId>
</FIId>
</Fr>
<To>
<FIId>
<FinInstnId>
<Othr>
<Id>INDOIDJA</Id>
</Othr>
</FinInstnId>
</FIId>
</To>
<BizMsgIdr>20210301FASTIDJA010HRB12345678</BizMsgIdr>
<MsgDefIdr>pacs.002.001.10</MsgDefIdr>
<BizSvc></BizSvc>
<CreDt>2021-03-01T12:00:00</CreDt>
<CpyDplct></CpyDplct>
<PssblDplct></PssblDplct>
<Sgntr></Sgntr>
</AppHdr>
Other than that you can use JSON Transform Mediator. Here you can control how the transformation handles Null values by setting different synapse properties. If you want fine control over the transformation. You can use the Datamapper Mediator, XSLT transformation or manually construct the Payload using the PayloadFactory mediator.
I want to format the Date field from a WSo2 EI REST API
currently i am getting the response in the below format.
{
"Members": {
"member": [
{
"First_Name": "FLORENCE ",
"Effective_Date": "2019-05-01-07:00"
}]}}
But I want the response to be like
"Effective_Date": "2019-05-01"
I tried with "Effective_Date":"$effective_date(type:dateTime, 'YYYY-MM-DD')"
<config id="DataSource">
<property name="jndi_resource_name">jdbc/datasourcename</property>
</config>
<query id="get_new_touchMembers" useConfig="DataSource">
<sql>EXECUTE databasename..SP_NAME</sql>
<result outputType="json"> {
"Members":{ "member":[ { "S.NO":"$s.NO", "ID":"$id", "DOB":"$dob", "Effective_Date":"$effective_date", "Term_Date":"$term_date", "Plan_Description":"$plan_description" } ] } } </result>
</query>
Try this property as it works for me!
<property expression="get-property('SYSTEM_DATE', 'yyyy-MM-dd')" name="effective_date" scope="default"/>
I have defined a restful service with nested queries. Output mapping is defined in XML. I get proper response as XML. But if I request a JSON response using Accept:Application/json I get
{
"Fault": {
"faultcode": "soapenv:Server",
"faultstring": "Error while writing to the output stream using JsonWriter",
"detail": ""
}
}
I was getting below exception in 3.5.0 and I found a jira saying it is fixed in 3.5.1. So I tried in 3.5.1 now I am not getting below exception but the same output.
javax.xml.stream.XMLStreamException: Invalid Staring element
Please note I have also tried the escapeNonPrintableChar="true" option in my queries but no use. Strange thing is it working for different data sets. Just one particular data set is throwing this output.
I have changed the JSON formatters as below and got it to work but there is a problem in that.
<messageFormatter contentType="application/json" class="org.apache.axis2.json.JSONMessageFormatter"/>
<!--messageFormatter contentType="application/json" class="org.apache.axis2.json.gson.JsonFormatter" / -->
<messageBuilder contentType="application/json" class="org.apache.axis2.json.JSONOMBuilder"/>
<!--messageBuilder contentType="application/json" class="org.apache.axis2.json.gson.JsonBuilder" /-->
If I use above formatter the null values are not represented properly. Like I get
"Person": {
"Name": {
"#nil": "true"
}
but I want it as (like the other JSON formatter used to give)
"Person": {
"Name": null
}
Any help please. Is there a bug still left in this area?
When you are creating the query in your output response, you define the format you want to receive the response you can select xml or json, in the case you mention you can select the json option, then select generate response this creates this json structure.
{
"entries": {
"entry": [
{
"field1": "$column1",
"field2": "$column2"
}
]
}
}
Then you can modify the answer you need with your fields. Here is an example of how I use it in my query
{
"Pharmacies": {
"Pharmacy": [
{
"ID": "$Id",
"Descripcion": "$Desc",
"Latitude": "$Latitude",
"Longitude": "$Longitude",
"Image": "$Image"
}
]
}
}
The values with "$" are correspond to the name of the column of the query
Regards
I am getting a string value (xml to string) from lambda backend which should be returned to end user in application/xml format. How can I achieve this?
You can specify an Integration Response that returns XML, along with a mapping template to format XML using the object returned from Lambda.
I do not believe there is a default format conversion to XML. A simple mapping template might be like this:
#set($root = $input.path('$'))
<stuff>
<message>$root.message</message>
<sourceIp>$context.identity.sourceIp</sourceIp>
<outputs>
#foreach($key in $root.keySet())
<output>
<key>$key</key>
<value>$root.get($key)</value>
</output>
#end
</outputs>
</stuff>
With reference to this document, section "Accessing the $util Variable", solved the challenge in a simple JSON to XML transform. I did try the mapping template given earlier here, but it did not work for me.
In my case, my JSON response payload is of the form:
[
{
"key1": "val1",
"key2": "val2",
"key3": "val3"
},
{
"key1": "val1",
"key2": "val2",
"key3": "val3",
"key4": "val4"
}
]
Here is the mapping template that deals with it:
#set ($arr = $util.parseJson($input.path('$')))
<responses>
#foreach($c in $arr)
<response>
#foreach ($k in $c.keySet())
<$k>$c.get($k)</$k>#end
</response>
#end
</responses>
The key was the parseJson to get a true JSON/Java object. After thi it was smooth sailing.
And the output is of the form:
<responses>
<response>
<key1>val1</key1>
...
</response>
...
</responses>
I hope this helps.
It may be that I am reading the API docs completely wrong, but here we go.
I send a GET request to https://www.googleapis.com/youtube/v3/playlistItems. In that request, I have the AUTHORIZATION header, and two parameters:
"PART" : "contentDetails",
"PLAYLISTID" : "UUy8_GJ_ZQ2SHm909UJ1AK-Q"
I know my authorization is correct, because I'm using the same auth header to get and receive Analytics requests with no problem.
According to Google's docs, either ID or playlistID MUST be included. But I get a "No filter selected" error 400 back when I send this request.
{ "error" : { "code" : 400,
"errors" : [ { "domain" : "youtube.parameter",
"location" : "",
"locationType" : "parameter",
"message" : "No filter selected.",
"reason" : "missingRequiredParameter"
} ],
"message" : "No filter selected."
}
}
If I change the PlaylistID parameter to ID, the request successfully completes and returns an empty array (empty because that video ID obviously doesn't exist.)
Is this an API bug? Is the API case sensitive? (From what I can see, CFHTTP uppercases the param names even though I wrap them with LCase)
Update:
Code here: https://gist.github.com/mborn319/13d7b9b03db10d97cd16
Apologies, I'm not sure how best to share 200 lines of CFML.
As you pointed out, the problem is the uppercased PLAYLIST ID param.
As you can see, this request works pretty fine:
https://www.googleapis.com/youtube/v3/playlistItems?part=contentDetails&playlistId=UUy8_GJ_ZQ2SHm909UJ1AK-Q&access_token=[putValidAccessTokenHere]
{
"kind": "youtube#playlistItemListResponse",
"etag": "\"F9iA7pnxqNgrkOutjQAa9F2k8HY/1T4SJss5RstUWWw6S4NPUKDWL-c\"",
"pageInfo": {
"totalResults": 1,
"resultsPerPage": 5
},
"items": [
{
"kind": "youtube#playlistItem",
"etag": "\"F9iA7pnxqNgrkOutjQAa9F2k8HY/s2P7FNuP_oK0sax4SB_fU9BVaLo\"",
"id": "UUeEJED-0K6VNZf3zbi8n5FA7Qu41XY55_",
"contentDetails": {
"videoId": "Y-Ft354b_vI"
}
}
]
}
If you make the same query with PLAYLISTID you will get your error output:
https://www.googleapis.com/youtube/v3/playlistItems?part=contentDetails&PLAYLISTID=UUy8_GJ_ZQ2SHm909UJ1AK-Q&access_token=[putValidAccessTokenHere]
{
"error": {
"errors": [
{
"domain": "youtube.parameter",
"reason": "missingRequiredParameter",
"message": "No filter selected.",
"locationType": "parameter",
"location": ""
}
],
"code": 400,
"message": "No filter selected."
}
}
But i am sorry, i can't tell you how to post params with CF in lowercases (is it even possible?) but here is a reference to some CF code. They use the old data api but they fetch data via get-request. Maybe the treatment of params differs in this case: http://davidosomething.com/blog/quick-access-to-the-youtube-api-with-coldfusion/
Given that the API is case-sensitive, you have to ensure ColdFusion maintains casing, which can be a little frustrating since ColdFusion isn't strict.
If you use dot notation to specify the key name in the structure, CF almost always uppercases it.
But if you specify the key name using bracket notation, the casing is maintained.
<cfset args.foo = "..."> key will be stored/transmitted as uppercase FOO
vs.
<cfset args["foo"] = "..."> key will be stored/transmitted as lowercase foo
<cfset args["UPPERCASE"]="UPPERCASE">
<cfset args["lowercase"]="lowercase">
<cfset args["CamelCase"]="CamelCase">
So you should be able to create a structure with your arguments, using brackets
<cfset data["part"] = "contentDetails">
<cfset data["playlistId"] = "UUy8_GJ_ZQ2SHm909UJ1AK-Q">
And then loop over your args as before
<cfhttp url="#arguments.url#" method="#arguments.type#" result="httpResult">
<cfloop item="curArg" collection="#data#">
<cfhttpparam name="#curArg#" value="#data[curArg]#" type="url" />
</cfloop>
</cfhttp>
The API should then receive the params in the proper case.
<cfdump var="#DeserializeJson(httpResult.filecontent.tostring())#">