Powered By Blogger

Dec 4, 2016


How to use JAVA Flight Recorder (JFR) with WSO2 Products

This blog post is about using JFR with WSO2 Products.  JFR collects events from a Java application from the OS layer, the JVM, and all the way up to the Java application. The collected events include thread latency events such as sleep, wait, lock contention, I/O, GC, and method profiling. We can use this JFR to do long run testing in effective way.

  • Enable JFR by adding below parameters in the wso2server.sh file  ( under $JAVACMD) located at <PRODUCT_HOME>/bin
          -XX:+UnlockCommercialFeatures \
          -XX:+FlightRecorder \
  • Then start the server
  • Then start JMC (Java mission control)  by executing the executable file located at JAVA_HOME/bin/jmc
  • Then you can see  org.wso2.carbon.bootstrap.Bootstrapin the UI, right click on that and click on start Flight Recording. Do relevant changes and click on finish.
  • Then run the load test
  • After the specified time you will get a .jfr file and you can see the memory growth, cpu usage, etc


Aug 29, 2016

Using a Class Mediator to process JSON payload

 

This blog post describes about using a class mediator to process  JSON payload

sample JSON:

{
   "query": "InformationSystem[@id\u003d\"22174\"]",

   "result": [
    {
      "id": [
        "22174"
      ],
      "description": [
        "test 123"
      ],
      "Application Type": [
        "Sample Application"
      ],
      "{Sample} ID": [
        "ID1"
      ]
    }
  ]
}



You can use WSO2 Developer Studio to create a mediator project and since I have used jackson as the library I have added below dependencies to the pom.xml of the mediator project

         <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.7.2</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.7.2</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.7.2</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-core-asl</artifactId>
            <version>1.9.3</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.synapse</groupId>
            <artifactId>synapse-commons</artifactId>
            <version>2.1.2-wso2v4</version>
        </dependency>



The code is as follows:

package org.wso2.sample;

import java.util.Iterator;
import java.util.Map;

import org.apache.synapse.MessageContext;
import org.apache.synapse.commons.json.JsonUtil;
import org.apache.synapse.core.axis2.Axis2MessageContext;
import org.apache.synapse.mediators.AbstractMediator;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;

public class JSONClassMediator extends AbstractMediator {

    public static final String RESULT_NODE = "result";
    public static final String QUERY_NODE = "query";

    @SuppressWarnings("deprecation")
    public boolean mediate(MessageContext context) {
        try {
            // Getting the json payload to a string
            String jsonPayloadToString = JsonUtil.jsonPayloadToString(((Axis2MessageContext) context)
                    .getAxis2MessageContext());

            JsonFactory factory = new JsonFactory();
            ObjectMapper mapper = new ObjectMapper(factory);

            JsonNode rootNode = mapper.readTree(jsonPayloadToString);
            //create a new root object
            ObjectNode rootObject = mapper.createObjectNode();
           
            //process query node
            TextNode queryNodeValue = (TextNode) rootNode.get(QUERY_NODE);
            rootObject.put(QUERY_NODE, queryNodeValue.asText());
           
            //process result node
            ArrayNode resultNode = (ArrayNode) rootNode.get(RESULT_NODE);
            JsonNode resultChildNode = ((ArrayNode) resultNode).get(0);
            Iterator<Map.Entry<String, JsonNode>> fieldsIterator = resultChildNode.fields();
            ObjectNode newNode = mapper.createObjectNode();
            ArrayNode resultArray = mapper.createArrayNode();
            while (fieldsIterator.hasNext()) {
                Map.Entry<String, JsonNode> field = fieldsIterator.next();
                String newKey = field.getKey().replace(" ", "-").replace("{", "").replace("}", "").replace("%", "");
                newNode.put(newKey, field.getValue());
            }          
            resultArray.add(newNode);
            rootObject.put(RESULT_NODE, (JsonNode) resultArray);
       
            // Setting the new json payload.
            String transformedJson = rootObject.toString();
            JsonUtil.newJsonPayload(((Axis2MessageContext) context).getAxis2MessageContext(), transformedJson, true,
                    true);

        } catch (Exception e) {
            handleException("error in processing the json payload", e,context);
            return false;
        }

        return true;
    }
}


Proxy configuration is as follows:

<?xml version="1.0" encoding="UTF-8"?>
       name="sampleProxy"
       transports="https,http"
       statistics="disable"
       trace="disable"
       startOnLoad="true">
   <target>
      <inSequence>
         <call>
            <endpoint key="conf:/repository/sampleEP"/>
         </call>
         <class name="org.wso2.sample.JSONClassMediator"/>
         <log level="full">
            <property name="************RESULT************" expression="$body"/>
         </log>
      </inSequence>
   </target>
   <description/>
</proxy>
 
 
Result:
 
<jsonObject>
      <query>InformationSystem[@id="22174"]</query>
      <result>
         <id>22174</id>
         <description>test 123</description>
         <Application-Type>Sample Application</Application-Type>
         <Sample-ID>ID1</Sample-ID>
      </result>
  </jsonObject>

Using a Script Mediator to process JSON payload


This blog post describes about using a script mediator to process  JSON payload

usecase:

When the JSON payload has spaces and special characters for element names, then replace those spaces and characters as required

sample JSON:

{
  "result": [
    {
      "id": [
        "22174"
      ],
      "description": [
        "test 123"
      ],
      "Application Type": [
        "Sample Application"
      ],
      "{Sample} ID": [
        "ID1"
      ]
    }
  ]
}


Please follow below steps:

1. In the proxy service configuration, first you need to assign the JSON payload to a property as below, (this will assign the array inside the 'result')

       <property name="JSONPayload" expression="json-eval($.result[0])" />
      
2. Then define the script mediator as below

       <script language="js" key="conf:/repository/transform.js" function="transform" />
      
based on this you need to create a registry resource (.js) in the registry ( eg: at conf:/repository/) and need to add the js script into that file

3. In this sample we are going to remove the spaces and curly braces from the elements, hence we have used below script.

function transform(mc) {
    var obj = mc.getProperty('JSONPayload'); //gets the property from the message context
    var jsonObject = JSON.parse(obj); // casting the json string to a json object

    var jsonArray = {
        result: []     // initializing the array
    };
    var item = {}
    for (var prop in jsonObject) {
        var attrName = prop;
        var att = attrName.replace(/ /g, '');  //replacing white spaces
        var att = att.replace(/[{}]/g, ""); //replacing curly braces
        var attrValue = jsonObject[prop];
        var jsonText = JSON.stringify(att);
        item[att] = attrValue;
    }
    jsonArray.result.push(item); //adds the sanitized json to the defined array
    mc.setPayloadJSON(jsonArray); //set the created json payload to the message context
 }



Please find the below complete proxy configuration as a reference

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="sampleProxy" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
   <target>
      <inSequence>
         <call>
            <endpoint key="conf:repository/sampleEP" />
         </call>

         <property name="JSONPayload" expression="json-eval($.result[0])" />
         <script language="js" key="conf:/repository/transform.js" function="transform" />
           <log level="full">
            <property name="************RESULT************" expression="$body" />
         </log>
      </inSequence>
   </target>
   <description />
</proxy>


Final result will be as below:


<jsonObject xmlns="http://ws.apache.org/ns/synapse">
   <result>
      <id>22174</id>
      <description>test 123</description>
      <ApplicationType>Sample Application</ApplicationType>
      <SampleID>ID1</SampleID>
   </result>
</jsonObject>



Script Mediator - https://docs.wso2.com/display/ESB481/Script+Mediator
JSON support in ESB - https://docs.wso2.com/display/ESB481/JSON+Support

Jul 29, 2016

WSO2 Data Mapper Operators

This post describes about the available operators of the data mapper and the functionality of each operator

Basically there are 7 categories of operators as shown below

Please refer the above links for more details

WSO2 Data Mapper Operators - String category

This post describes about the operators in the String category







  • Concat

This can be used to concat two or more string values

1.Drag and drop the operator to the editor
concat1.png 
2. To configure the operator by specifying the number of inputs and the concat delimiter, right click and select “Configure concat operator” menu action

concat2.png



Eg: name and the origin will concat using the delimiter “,” and maps the result to the description

concatEx.png
  • Split
This can be used to split a string value using a specified delimiter 

split.png

Eg: if the oring value is “French:FR” the the split the origin from “:” and map the ‘French’ and ‘FR’ to origin and value fields


spitEx.png
  • Uppercase

This can be used to convert a string value to uppercase

upper1.png
Eg: make the name to uppercase
upperEx.png
  • Lowercase

This can be used to convert a string value to lowercase

lower.png
Eg: converts the origin to lowercase
lowerEx.png
  • String Length
This can be used to get the length of a string

stringLe.png
Eg: get the length of the value field and map
stringLEx.png
  • StartsWith



This can be used to check whether a String starts with a specific value ( This is not supported in Java 7)

Eg: if the origin value if ORI-French, then we can check if it’s starts with ‘ORI’


1.Drag and drop the operator to the editor
str.png




2. You can give the String value you need to check into the first input box and the string pattern to the other input box. String pattern can be given in two ways as below

-Can give via the dialog box by right click and select “Configure StartsWith operator” menu action and then specify the pattern at {$Pattern}

startEx.png


start2.png



-Can give as an input to the operator either using another operator as shown below or using the input value from the data mapper input tree


startwith3.png

  • Endswith

This can be used to check whether a String ends with a specific value. ( This is not supported in Java 7)

(Works similar to the startsWith operator)
ends.png


  • SubString



This can be used to extracts a part of the String value

Eg: if the description is “VEG-Vegetarian”, then we can extract the VEG part and maps the value


1.Drag and drop the operator to the editor
sub.png


2. You can give the String value into the first input box and the start index and the length to the other two input boxes. Those can be given in two ways as below


-Can give via the dialog box by right click and select “Configure SubString operator” menu action and then specify the start {$Index} and {$Length}

subSt1.png


subst2.png


-Can give as an input to the operator either using two other operators as shown below or using the input values from the data mapper input tree


substr4.png


  • Trim
This can be used to remove white spaces from the beginning and end of a String


trim.png


  • Replace

This can be used to replace the first occurrence of a target String with another


Eg: if the description is “Ctg:Vegetarian”, then we can replace Vegetarian with VEG and maps the value


1.Drag and drop the operator to the editor

replace1.png



2. You can give the String value into the first input box and the target string and the replace with string to the other two input boxes. Those can be given in two ways as below
 
-Can give via the dialog box by right click and select “Configure Replace operator” menu action and then specify the {$Target} and {$Replace}


replace2.png

replace3.png


-Can give as an input to the operator either using two other operators as shown below or using the input values from the data mapper input tree

relce4.png

  • Match

This can be used to check whether the input match with a (JS) Regular Expression

1.Drag and drop the operator to the editor



match1.png


2. You can give the String value into the first input box and the pattern the other input box. The pattern can be given in two ways as below
 

-Can give via the dialog box by right click and select “Configure Match operator” menu action and then specify the {$Pattern}
match2.png

match3.png


-Can give as an input to the operator either using another operator as shown below or using the input values from the data mapper input tree

match4.png






WSO2 Data Mapper Operators - Type Conversion category

This post describes about the operators in the Type conversion category



  • StringToNumber

This converts a String value to a number



StoNum1.png
Eg: convert the price value from String to a number


StToNum2.png

  • StringToBoolean

This converts a String value to a boolean


stToBool1.png


Eg: This converts the veg value from String “true” to boolean true

StroBool2.png

  • ToString
This converts a boolean or a number to a String value


toString1.png


Eg: The calories value is converting from number to string and the veg value is converting from boolean to a string



toString2.png




WSO2 Data Mapper Operators - Boolean category

This post describes about the operators in the Arithmetic category

 





  • AND

This performs the boolean AND operation on inputs


and_3.png

Eg: according to the below example if it’s Veg and the calories are less than 10, then the approval value should be true

AND_ex.png


  • OR
This perform the boolean OR operation on inputs

or1.png



Eg: according to the below example if it’s Veg or the calories are less than 10, then the approval value should be true
 
OR_EX.png


  • NOT
This performs the boolean NOT operation

not1.png

Eg: If the calories are greater than 10, then the approval value should be false


not2.png

 







WSO2 Data Mapper Operators - Conditional category

This post describes about the operators in the Conditional category


  • IfElse

Here it uses a condition and based on that condition this selects one input from given two.

ifelse1.png


eg:According to the below example if the veg value is “true” then the output value should be “VEG” else the value should be “NON-VEG”



ifelseEx.png



 

WSO2 Data Mapper Operators - Arithmetic category

This post describes about the operators in the Arithmetic category




  • Add
This operator can be used to add two or more numbers
1.Drag and drop the operator to the editor

add1.png


2. To configure the number of inputs, right click and select “Configure Add Operator” menu action and then you can add the number of inputs you require to add 



add2.png

Eg:Adds the calories and count and maps the result to value

addex.png

  • Subtract
This operator can be used to subtract two numbers
subtract1.png
Eg: Subtract 5 from calories and map the result 


subEx2.png

  • Multiply
This can be used to multiply two or more numbers

1. Drag and drop the operator to the editor

mul1.png
2. To configure the number of inputs, right click and select “Configure Multiply Operator” menu action and then you can add the number of inputs you require

mul2.png

Eg: Multiplies the calories by 1% and map the result



mulEx.png

  • Divide
This can be used to divide two numbers

divide1.png

Eg: Divide the calories by 2 and map the result



devideEx.png

  • Ceiling

This can be used to derive the ceiling value of a number (the least integer that is greater than the input value)

ceiling1.png
Eg:Maps the ceiling value of the price


ceilEx.png

  • Floor
This can be used to derive the floor value of a number (the greatest integer that is less than the input value)

floor1.png
Eg:Maps the floor value of the price

floorEx.png
  • Round
This can be used to derive the next integer value by either increasing or decreasing the number 

round.png

Eg: Get the round value of price



roundEx.png

  • Set Precision

This can be used to specify a number into a specified length.

Eg: Nmber as 5.5433
Number of decimals as 2
The result would be 5.54
 
1.Drag and drop the operator to the editor

setPre1.png

2. You can give the number which you need to convert into the first input box and the number of decimals to the other input box. No of decimals can be given in two ways as below-Can give via the dialog box by right click and select “Configure Set Precision Operator” menu action and specify the value for {$NoOfDigits} 

setPre2.png


setPre1.png
-Can give as an input to the operator either using another operator as shown below or using the input value from the data mapper input tree


setPre2.png 

  • Absolute value
This can be used to derive the absolute value of a rational number

abs 1.png

  • Min
This can be used to derive the minimum number of the given set of numbers

1.Drag and drop the operator to the editor

min1.png
2. Configure the operator to add the number of inputs by right click and select “Configure min operator” menu action

min2.png


  • Max
This can be used to derive the maximum number of the given set of numbers

1.Drag and drop the operator to the editor



max1.png
2. . Configure the operator to add the number of inputs by right click and select “Configure max operator” menu action


max2.png