Update Registry file content in WSO2 EI 6.1.1 dynamically - wso2

I am storing config file in Config registry like below.
My use case here is, need to update accessToken tag content from wso2 ei service,because it expires within an hour. how can i pass regenerated accesstoken to this file?
<!-- Reading config registry file content -->
<property name="ZohoAppConfig" expression="get-property('registry','conf:/ZohoConfig/ZohoAppConfigFile.xml')" scope="default" type="OM" />
<property description="accessToken" expression="$ctx:ZohoAppConfig//*[local-name()='accessToken']" name="accessToken" scope="default" type="STRING"/>
<property description="refreshToken" expression="$ctx:ZohoAppConfig//*[local-name()='refreshToken']" name="refreshToken" scope="default" type="STRING"/>
<property description="AllPortalsEP" expression="$ctx:ZohoAppConfig//*[local-name()='AllPortals']" name="uri.var.AllPortalsEP" scope="default" type="STRING"/>
<log level="custom">
<property name="===ZohoAppConfig===" expression="get-property('ZohoAppConfig')"/>
<property expression="get-property('accessToken')" name="===accessToken===="/>
<property expression="get-property('uri.var.AllPortalsEP')" name="===uri.var.AllPortalsEP===="/>
</log>
<!-- Need to update registry content here -->
Awaiting for your response.

You can modify your ZohoAppConfig, for example using enrich mediator:
<enrich>
<source clone="true" property="someNewAccesToken" type="property"/>
<target action="replace" xpath="$ctx:ZohoAppConfig//accessToken" type="custom" xmlns:ns="http://org.apache.synapse/xsd"/>
</enrich>
This will update in your property ZohoAppConfig the token. Next to store back to registry you need use property:
<property expression="$ctx:ZohoAppConfig" name="conf:/ZohoConfig/ZohoAppConfigFile.xml"
scope="registry" type="STRING" xmlns:ns="http://org.apache.synapse/xsd"/>
That should works in 6.1.1, I tested it on 6.3.0. but that way is caching the read in memory for 15sec, what could be in some cases problematic.
Another way is to store using script mediator, and set the cacheDuration to 0:
<script language="js"><![CDATA[
mc.getConfiguration().getRegistry().updateResource('conf:/ZohoConfig/ZohoAppConfigFile.xml',mc.getProperty('sample'));
var regEntry = mc.getConfiguration().getRegistry().getRegistryEntry('conf:/ZohoConfig/ZohoAppConfigFile.xml');
regEntry.setCachableDuration(0);
mc.getConfiguration().getRegistry().updateRegistryEntry(regEntry);
]]></script>
I have described it much more with an example, along with some encountered problem here

Related

Cannot send request in mediation synapse in wso2 apim

We have two ways to send requests in wso2 APIM:
1- send mediator
2- call mediator
Unfortunately, I cannot use any of these mediators!
for example this request: http://jsonplaceholder.typicode.com/posts/
I need this approach for get token from a server and then use it in payload of main request for authentication.
could anyone help me please?! :)
I didn't get any error or special log!
<log level="custom">
<property name="text" value="###############################33"/>
</log>
<call blocking="false">
<endpoint>
<http method="GET" uri-template="http://jsonplaceholder.typicode.com/posts/"/>
</endpoint>
</call>
<log level="custom">
<property name="text" value="###############################"/>
</log>
You could find related blogs "WSO2 API Manager & OAuth2 Protected Endpoint" and answer to this question
The idea is to
call the token endpoint with the appropriate grant type(usually client secret grant is used for system to system calls).
Then extract the token using the script mediator
Then use the that token to call the API attaching the token to "Authorisation Bearer:" header.
Please give this a try.
Let's use the below properties before the call mediator. If your response is not a json payload, you need to set the expected payload content type to the ContentType and messageType properties.
<property action="remove" name="NO_ENTITY_BODY" scope="axis2"/>
<property name="ContentType" scope="axis2" value="application/json"/>
<property name="messageType" scope="axis2" value="application/json"/>
After adding the above properties into the sequence, it should look like the below.
<sequence>
<property action="remove" name="NO_ENTITY_BODY" scope="axis2"/>
<property name="ContentType" scope="axis2" value="application/json"/>
<property name="messageType" scope="axis2" value="application/json"/>
<call blocking="true">
<endpoint>
<http method="GET"
uri-template="http://www.mocky.io/v2/5c9ddf51330000b12c3f253a"/>
</endpoint>
</call>
</sequence>

WSO2 exclude property from log

I am new to wso2 and I want to log all the properties in the incoming request except one property
here's my code:
<log level="full"/>
<propertyGroup>
<property expression="json-eval($.username)" name="Username" scope="default" type="STRING"/>
<property expression="json-eval($.password)" name="Password" scope="default" type="STRING"/>
<property expression="json-eval($.objectStore)" name="ObjectStore" scope="default" type="STRING"/>
<property expression="json-eval($.documentClass)" name="DocumentClass" scope="default" type="STRING"/>
<property expression="json-eval($.fileName)" name="FileName" scope="default" type="STRING"/>
<property expression="json-eval($.fileData)" name="FileData" scope="default" type="STRING"/>
<property expression="json-eval($.contentType)" name="ContentType" scope="default" type="STRING"/>
</propertyGroup>
I want to exclude the fileData property from log because it's base64
is there's any solution other than a custom log that has only the properties that I want to log ?
Its not posible by default i think. You can write your custom mediator for logging necessary attributes and properties
By default, the <log level="full"/> won't log your property - it is logging standard headers (i.e. To, From, WSAction, SOAPAction, ReplyTo, and MessageID) and the full payload of the message. And as i see in your example - json-eval($.fileData) is part of the JSON payload.
So, there is no other option than using a custom logger.

WSO2 Integrator: REST API GET Request missing response body

I am using WSO2 Integrator 6.6.0 to make a blocking HTTP GET to a REST API that returns a JSON response (HTTP 200 OK).
But I never see the response body inside my sequences. I am not sure what I am doing wrong, having exhausted all available documentation and other threads.
Sequence doing the call (simplified to anonymize), which logs the response afterwards:
<!-- Remove XML body as not needed for GET request -->
<payloadFactory media-type="json">
<format></format>
<args></args>
</payloadFactory>
<header name="Accept" value="application/json" scope="transport"/>
<property name="NO_ENTITY_BODY" value="true" scope="axis2" type="BOOLEAN" />
<call blocking="true">
<endpoint>
<http method="GET" uri-template="http://my-api/order-status">
</endpoint>
</call>
<property name="RESPONSE" scope="default" type="STRING" value="true"/>
<log level="full">
<property name="response-log" value="Received response"/>
<property expression="$body" name="response-body"/>
<property expression="json-eval($)" name="json-eval-body"/>
</log>
This results simply into a log line - with no response body at all!
INFO {org.apache.synapse.mediators.builtin.LogMediator} - To:
http://my-api/order-status, WSAction: urn:mediate, SOAPAction:
urn:mediate, MessageID:
ID:414d51204343494153303131202020209ca4175f28ac422e, Direction:
response, response-log = Received response, response-body =
<soapenv:Body
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"></soapenv:Body>,
json-eval-body = {}, Payload: {}
I can see the request in my API application and I can also see what it correctly returns a response body in its logs. Also, using Postman to do the same request I receive the following JSON response with 200 OK and Content-Type appication/json:
{
"order_status": "NOT_FOUND"
}
Inside WSO2 I do not see anything! I want to be able to convert the response into XML format.
What could be wrong?
Before making a REST call, it is necessary to remove the headers from the main call.
Put this snippet before the call mediator:
<property name = "FORCE_HTTP_CONTENT_LENGTH" scope = "axis2" type = "STRING" value = "true" />
<property action = "remove" name = "REST_URL_POSTFIX" scope = "axis2" />
<property action = "remove" name = "TRANSPORT_HEADERS" scope = "axis2" />
As I understand it should solve.
Can you modify the NO_ENTITY_BODY property as follows and try this mediation again.
<property name="NO_ENTITY_BODY" action="remove" scope="axis2"/>
Having simplified this configuration for this question, I had missed that having the following property set in my proxy service:
<property name="OUT_ONLY" scope="default" type="STRING" value="true"/>
Means that WSO2 is ignoring the response from the API. Removing this property resolved the issue for the following config:
<header name="Accept" value="application/json" scope="transport" />
<property action="remove" name="NO_ENTITY_BODY" scope="axis2"/>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<call blocking="true">
<endpoint key="conf:/endpoints/FX_TRADING_API_ORDERSTATUS.xml"/>
</call>

Multipart in wso2 EI

I have a requirement where i am supposed to upload a gzip file to wso2 EI server.
I have a file(gzip) in a system(running java). I need to send this file to a API hosted in wso2ei, which will store this. Since file can be HUGE, I need the API to support multi part file upload. I want to write an API in wso2 EI which will support multipart and will take this file and store on some location on EI server itself.
I do not want to use VFS.
Below is the code that i tried but not working. Its creating a corrupted zip file. If i am giving a huge file , then i am getting out of memory error too. Though while using multipart, i was not expecting out of memory error(irrespective the size of file).
Note: I tried without decoding the body. With application/zip content type as well.
<?xml version="1.0" encoding="UTF-8"?>
<api context="/upload" name="MultiPartAPI" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST" >
<inSequence>
<property expression="json-eval($)" name="inputPayLoad" scope="default" type="STRING"/>
<property name="messageType" scope="axis2" type="STRING" value="multipart/form-data"/>
<property name="ContentType" scope="axis2" type="STRING" value="multipart/form-data"/>
<property expression="//mediate/data/text()" name="payload" scope="default" type="STRING"/>
<property expression="//mediate/data/#filename" name="fileName" scope="default" type="STRING"/>
<log level="custom">
<property name="===========" value="================="/>
<property expression="$ctx:fileName" name="fileName"/>
</log>
<property expression="base64Decode(get-property('payload'))" name="DecodeBody" scope="default" type="STRING"/>
<property description="File full path" expression="fn:concat('\home\files\gzip\',$ctx:fileName)" name="fileFullPath" scope="default" type="STRING"/>
<property name="messageType" scope="axis2" type="STRING" value="application/octet-stream"/>
<property name="ContentType" scope="axis2" type="STRING" value="application/octet-stream"/>
<fileconnector.create>
<source>{$ctx:fileFullPath}</source>
<inputContent>{$ctx:DecodeBody}</inputContent>
</fileconnector.create>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
BR//
Vipin Nirwal
This give the details of above requirement.

User Friendly Log

We have developed a Project in Developer Studio everything is working fine and our Custom log is creating Custom messages in Carbon log. Our requirement is that our custom log should write in a separate file like 'Interfacing Exceptions Report' so that user can easily track the error instead of reviewing the whole Carbon log because it has too much contents as well.
Currently we have source as follows for custom log:
<property xmlns:ns11="http://xmlns.oracle.com/apps/scm/doo/decomposition/receiveTransform/receiveSalesOrder/model/"
name="OrderNumber"
expression="//ns11:OrderNumber"
scope="default"
type="STRING"/>
<property xmlns:ns11="http://xmlns.oracle.com/apps/scm/doo/decomposition/receiveTransform/receiveSalesOrder/model/"
name="OrderStatus"
expression="//ns11:OrderStatus"
scope="default"
type="STRING"/>
<property xmlns:ns11="http://xmlns.oracle.com/apps/scm/doo/decomposition/receiveTransform/receiveSalesOrder/model/"
name="ReturnStatus"
expression="//ns11:ReturnStatus"
scope="default"
type="STRING"/>
<log level="custom">
<property name="prop1" expression="get-property('OrderNumber')"/>
<property name="prop2" expression="get-property('OrderStatus')"/>
</log>
<filter source="get-property('ReturnStatus')" regex="SUCCESS">
<then>
<log level="custom">
<property name="message" value="Your order has been created successfully "/>
</log>
</then>
<else>
<log level="custom">
<property name="errormessage" value="Sorry,there was an issue in order creation"/>
</log>
</else>
</filter>
What you're looking for sounds like per service logging or per api logging.