I am trying to transform json to xml using datamapper and i am getting the empty xml structure but not getting any values in wso2. I have created data mapper dependencies and loaded both input and out structures and used AI to map json -> xml and they mapped correctly.
I tried on eclipse oxygen(esb-6.2.0) and integration studio(v8) also and deployed in EI(6.5.0) but still the behavior is same empty response structure. I kept a log in the in-sequence and it is logging the json request but not the xml response. I am not getting why the issue is happening.
Please provide your thoughts and attached the code to this post. Please do needful
The issue is with the API. In the API we need to specify the input and the output data type. In your case since the transformation is from JSON to XML, the input type needs to be JSON while the output type needs to be XML. But you have defined both as xml which resulted in this issue. Modify the input type to JSON and you will get the expected results
<api xmlns="http://ws.apache.org/ns/synapse" name="DataMapper" context="/data">
<resource methods="POST" url-mapping="/mapper">
<inSequence>
<log separator="/">
<property name="payload" expression="json-eval($.body)"/>
</log>
<datamapper config="gov:datamapper/Wso2DataMapper.dmc" inputSchema="gov:datamapper/Wso2DataMapper_inputSchema.json" outputSchema="gov:datamapper/Wso2DataMapper_outputSchema.json" xsltStyleSheet="gov:datamapper/Wso2DataMapper_xsltStyleSheet.xml" inputType="JSON" outputType="XML"/>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
input
{
"studNo":"Sample studNo",
"studName":"Sample studName",
"StudGroup":"Sample StudGroup",
"studAddress":{
"addrLine1":"Sample addrLine1",
"AddrLine2":"Sample AddrLine2",
"Mandal":"Sample Mandal",
"District":"Sample District",
"State":"Sample State",
"Country":"Sample Country",
"Zip":"Sample Zip"
}
}
output
<Student xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<studentNo>Sample studNo</studentNo>
<studentName>Sample studName</studentName>
<studentGroup>Sample StudGroup</studentGroup>
<studentAddress>
<AddressLine1>Sample AddrLine2</AddressLine1>
<AddressLine2>Sample addrLine1</AddressLine2>
<Mandal>Sample Mandal</Mandal>
<District>Sample District</District>
<State>Sample State</State>
<Country>Sample Country</Country>
<ZIP>Sample Zip</ZIP>
</studentAddress>
</Student>
Related
I am using WSO2 APIM version 3.2.0.
I have a POST request with the request payload.
In the response message mediation of WSO2 APIM I have added the policy that contains the class mediator that tries to get the payload sent during the request.
OMElement element = (OMElement) mc.getEnvelope().getBody().getFirstOMChild();
log.info("payload: " + element.toString());
The above code snippet prints the response payload content but I need the request payload content at the response path.
Response message mediation with a policy added
Below is the sequence with class mediator
sequence with class mediator
Code snippet inside class mediator
OMElement element = (OMElement) mc.getEnvelope().getBody().getFirstOMChild();
log.info("payload: " + element.toString());
Pls let me know what changes to be done, to get the request payload content.
First, we have to store the request payload in a custom property in the Message Context. Then, we can use that property to retrieve the Request Payload in the Response path of the execution.
For example: You are invoking an API with JSON Payload. So, we have to first capture the sent payload and store it in a custom property in the Message Context. Given below is a sample sequence to perform the same
<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="admin--MockAPI:v1.0.0--In">
<property name="RequestPayload" expression="json-eval($)" />
<log level="custom">
<property name="RequestPayload" expression="$ctx:RequestPayload" />
</log>
</sequence>
Then, in the Response path, inside your custom class mediator, you have to access the RequestPayload property from the MessageContext to extract the stored payload. You can achieve this by using the following snippet
synapseContext.getProperty("RequestPayload");
I'm writing some power query against the Graph API and when I try to pull OData from the applications resource I get the error:
DataSource.Error: OData: The property 'resourceSpecificApplicationPermissions' does not exist on type 'microsoft.graph.apiApplication'. Make sure to only use property names that are defined by the type.
Details:
DataSourceKind=OData
DataSourcePath=https://graph.microsoft.com/beta/applications
Source = OData.Feed(AppsURL,[#"Content-Type"="application/json", Authorization = AccessTokenHeader])
If I do the same but as a REST API request I get the JSON but then I need to take care of paging and transformation.
Source = Json.Document(Web.Contents(AppsURL,
[
Headers = [#"Content-Type"="application/json",
Authorization = AccessTokenHeader
]
]))
If I do the same against https://graph.microsoft.com/beta/servicePrincipals the OData.Feed method works like a charm.
Any possible work around or do I need to wait for the API to be fixed before consuming that resource?
After doing some tracing I found the schema is verified at: https://graph.microsoft.com/beta/$metadata and it is missing one definition.
To original response:
<ComplexType Name="apiApplication">
<Property Name="acceptMappedClaims" Type="Edm.Boolean"/>
<Property Name="knownClientApplications" Type="Collection(Edm.Guid)"/>
<Property Name="preAuthorizedApplications" Type="Collection(microsoft.graph.preAuthorizedApplication)"/>
<Property Name="requestedAccessTokenVersion" Type="Edm.Int32"/>
<Property Name="oauth2PermissionScopes" Type="Collection(microsoft.graph.permissionScope)" Nullable="false" />
</ComplexType>
Is missing:
<Property Name="resourceSpecificApplicationPermissions" Type="Collection(microsoft.graph.resourceSpecificPermission)" Nullable="false"/>
As a workaround I added a rule to Fidller:
if (oSession.HostnameIs("graph.microsoft.com") && oSession.oResponse.headers.ExistsAndContains("Content-Type","application/xml;charset=utf-8") && oSession.PathAndQuery == '/beta/$metadata' ){
oSession.utilDecodeResponse();
oSession.utilReplaceInResponse('<Property Name="oauth2PermissionScopes" Type="Collection(microsoft.graph.permissionScope)" Nullable="false" />','<Property Name="oauth2PermissionScopes" Type="Collection(microsoft.graph.permissionScope)" Nullable="false" /><Property Name="resourceSpecificApplicationPermissions" Type="Collection(microsoft.graph.resourceSpecificPermission)" Nullable="false"/>');
}
I am writing a proxy service in WSO2 ESB that accepts a JSON payload and performs some transformations (to a SOAP message) that are quite complex, so we are writing the transformation logic in a Custom Mediator.
As you can see, my custom mediator class sets a property in the message context, and the proxy flow extracts this property and sets the payload (using a Javascript API that I could find).
This results in my SOAP message being "double wrapped" in two envelope tags, and I need to use an enricher with a XPath expression to remove the outer envelope/body tags.
Is it possible to set the XML payload within the custom mediator, thus avoiding to read a property and writing the XML payload in the proxy flow?
The proxy code is listed below:
<?xml version="1.0" encoding="UTF-8"?>
<proxy name="stackOverflowProxy" startOnLoad="true" trace="disable"
transports="jms" xmlns="http://ws.apache.org/ns/synapse">
<target>
<inSequence>
<!-- process incoming request in custom class. the payload is a JSON object -->
<class name="stackOverflow.CustomMediator"/>
<!-- set registration xml string as xml payload -->
<script language="js"><![CDATA[mc.setPayloadXML(new XML(mc.getProperty('mediatorPayload')));]]></script>
<enrich>
<source clone="true"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xpath="$body//soapenv:Envelope/soapenv:Body/*"/>
<target type="body"/>
</enrich>
</inSequence>
<outSequence/>
<faultSequence/>
</target>
</proxy>
And this is the Custom Mediator class:
package stackOverflow;
// imports ...
public class CustomMediator extends AbstractMediator {
public boolean mediate(MessageContext messageContext) {
//messageContext has a json object property
//message is processed and transformed to a SOAPEnvelope (namespaces omitted for simplicity)
//soapEnvelopeString = <Envelope><Body><tag>value</tag></Body></Envelope>
messageContext.setProperty("mediatorPayload", soapEnvelope.toString());
return true;
}
}
In your custom mediator you are setting entire soap message in to a property and in script mediator setting it as payload of the soap message. thats why you are getting double soap env.
in your class mediator set only the body payload to property and then insert that value as payload in main flow using script will solve your issue.
package stackOverflow;
// imports ...
public class CustomMediator extends AbstractMediator {
public boolean mediate(MessageContext messageContext) {
//messageContext has a json object property
//message is processed and transformed to a SOAPEnvelope (namespaces omitted for simplicity)
//**soapPayload = <tag>value</tag>**
messageContext.setProperty("mediatorPayload", soapPayload);
return true;
}
}
Does wso2 api manager v1.10.0 permit transforming the HTTP method of the request to the backend through custom in sequence?
I created an api with http GET resource through publisher web console. But since the endpoint support POST method only, i tried changing the HTTP Method by creating custom in sequence with property mediator :
<property name="HTTP_METHOD" value="POST" scope="axis2"/>
but the response showed a fault message :
{
"fault": {
"code": 403,
"type": "Status report",
"message": "Fault Call",
"description": "No matching resource found in the API for the given request"
}
}
The log files only showed these lines :
==> /opt/wso2am-gateway/repository/logs/wso2carbon.log <==
[2016-04-08 10:30:16,868] INFO - STATUS = Executing default 'fault' sequence, ERROR_CODE = 403, ERROR_MESSAGE = No matching resource found in the API for the given request {org.apache.synapse.mediators.builtin.LogMediator}
If i remove the property mediator, the request pass through and reach the backend.
Does anyone know how to solve this problem?
You can use the following custom inFlow mediation sequence to convert the HTTP_METHOD into POST from GET.
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="CustomIn" xmlns="http://ws.apache.org/ns/synapse">
<property action="remove" name="HTTP_METHOD" scope="axis2"/>
<property name="HTTP_METHOD" scope="axis2" type="STRING" value="POST"/>
</sequence>
Here, the request is the GET request from the client-side.
But, the above solution will be possible only when you are defining the GET and the POST resources similarly on your API (Although you don't use one of the both).
Otherwise, you will get the following error messages while you are invoking the API.
No matching resource found for given API Request
Method not allowed for given API resource
No matching resource found in the API for the given request
You need to also define POST resource on your API (although you don't use it)
I am retrieving the single row from DSS like
<Body xmlns="http://ws.wso2.org/dataservice">
<Datalist>
<username>anil</username>
<password>anil123</password>
</Datalist>
</Body>
and i am consuming this row in ESB Payload factory , while running the my ESB service,
i am getting like this :-
{"ResponseJSON":{"Body":{"Datalist":{"username":"anil","password":"anil123"}},"Status":"200","Total":"1.0"}}
But my output look like as JSON array.
{
"ResponseJSON": {
"Body": {
"Datalist": [
{
"username": "anil",
"password": "anil123"
}
]
},
"Status": "200",
"Total": "1.0"
}
}
How can we achieve this
I am also facing same issue in WSO2ESB 4.8.0
But got workaround by using Script-mediator.
Please let me know if you have any other solution for this problem.
Thanks
HI Add the following property in your Proxy Service sequence.
<property name="messageType" value="application/json" scope="axis2"/>
or else if you are working on WSO2 ESB 4.7.0.
<property name="ContentType" value="application/json" scope="axis2"/>
then no need to write above properties.It is automatically converted into json format.
Try to work on latest WS02 E.S.B 4.7.0, it's working fie.
If you need anything let me know.