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)
Related
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>
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 need to know how is it possible to publish statistics via event publisher from Enteprise Integrator to Stream Processor.
I have following implementation of event publisher on my EI
<?xml version="1.0" encoding="UTF-8"?>
<eventPublisher name="MessageFlowStatisticsPublisher"
statistics="enable" trace="enable" xmlns="http://wso2.org/carbon/eventpublisher">
<from streamName="org.wso2.esb.analytics.stream.FlowEntry" version="1.0.0"/>
<mapping customMapping="disable" type="wso2event"/>
<to eventAdapterType="wso2event">
<property name="username">admin</property>
<property name="protocol">thrift</property>
<property name="publishingMode">non-blocking</property>
<property name="publishTimeout">0</property>
<property name="receiverURL">tcp://xxx:7611</property>
<property encrypted="true" name="password">xxx</property>
</to>
</eventPublisher>
On Stream Processor I have simple siddhi app for receive data and print them into log as is shown below
#App:name("FlowEntryApp")
#App:description("Plan of flow entry")
#source(type='wso2event', #map(type = 'wso2event'))
define stream FlowEntry(compressed bool, tenantId int, messageId string, flowData string);
#sink(type='log', prefix='My flowEntry:')
define stream TestOutputFlowEntry(messageId string, flowData string);
#info(name='FlowEntryOutput')
from FlowEntry
select messageId, flowData
group by messageId
insert into TestOutputFlowEntry;
Also I have setted all configuration for publishing statstics as "enable statistic" and "enable trace" for my proxy service. When I invoke my service, eventPublisher send wso2event to SP, this is working correctly. But on the SP side, SP handle error "No StreamDefinition for streamId org.wso2.esb.analytics.stream.FlowEntry:1.0.0 present in cache"
I know, that problem is in siddhi app, that I define stream "FlowEntry" instead of "org.wso2.esb.analytics.stream.FlowEntry" but siddhi language doesn't support characters like '.' in stream name.
So I tried to change stream name on EI site, change streamName in eventPublisher to 'FlowEntry' only, also I changed streamName in json file inside eventstream folder but now when I invoke my service, EI will not send any events to SP.
Have anybody idea how to publish org.wso2.esb.analytics.stream.FlowEntry stream to SP and then processed it by siddhi?
The stream name can be overridden by using wso2.stream.id element in the source annotation.
#source(type='wso2event', wso2.stream.id='org.wso2.esb.analytics.stream.FlowEntry', #map(type = 'wso2event'))<br>
define stream FlowEntry(compressed bool, tenantId int, messageId string, flowData string);
By using the above source definition, 'FlowEntry' can still be used inside the Siddhi App, while in the thrift server stream id will be defined as 'org.wso2.esb.analytics.stream.FlowEntry:1.0.0'.
Best Regards.
i am getting messages from Proxy client how could i know client url means i want to do a filter condition based on url so in that case i could know that which url hitting me
i have tried with some sample code nut its notworking my code like this
<property name="client_url" expression="get-property('From')"/>
and also i logged it but its not returning null log is like this
LogMediator To: /services/RoleDetails, MessageID: urn:uuid:695faeb5-b26e-405d-ab7b-ce27213f5cbe, Direction: request, client_url = null
same thing working for
<property name="client_url" expression="get-property('To')"/>
Log for his
LogMediator To: /services/RoleDetails, MessageID: urn:uuid:a550ba76-201d-48c8-b069-3afdbb2b2db1, Direction: request, client_url = /services/RoleDetails
how could i know the client uri
I think You need to set 'From' property from your client.
But you can do something like this.
<property name="from property------->" expression="get-property('axis2','REMOTE_ADDR')"/>
and
<property name="from property------->" expression="get-property('axis2','REMOTE_HOST')"/>
you have to get that from axis2 context. refer this post