Tuesday, January 31, 2017

Data Masking using class mediator in WSO2 ESB

If you are looking for an easy way to mask a sensitive information in the soap body inside the WSO2 ESB, then this would be the best option. You can go for a class mediator to achieve your requirement and please follow below steps in oder to achieve .

Step1

Create a mediator project and add following dependencies to pom file.


<dependencies>
   <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.21</version>
   </dependency>
   <dependency>
      <groupId>org.json.wso2</groupId>
      <artifactId>json</artifactId>
      <version>2.0.0.wso2v1</version>
   </dependency>
</dependencies>

Step 2

After modifying the pom file if those libraries available to import in java code, go to mediator project root directory from and run below command


mvn eclipse:eclipse

Step 3

Add following code to your class.


package com.sachini.sample;


import org.apache.synapse.MessageContext;

import org.apache.synapse.mediators.AbstractMediator;

import org.json.JSONArray;

import org.json.JSONException;

import org.json.JSONObject;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;


public class DatamaskMediator extends AbstractMediator {


    private static final Logger LOGGER = LoggerFactory

            .getLogger(DatamaskMediator.class);


    public boolean mediate(MessageContext context)


    {

        JSONObject jsonObject = maskJsonPayload(context);

        context.setProperty("MASKED_PAYLOAD", jsonObject.toString());

        return true;

    }


    public JSONObject maskJsonPayload(MessageContext messageContext) {

        // extract properties

        String maskingKeys = (String) messageContext

                .getProperty("MASKING_KEYS");

        String stringPayload = (String) messageContext

                .getProperty("TARGET_PAYLOAD");


        JSONArray keys;

        try {

            keys = new JSONObject(maskingKeys).getJSONArray("keysToBeMasked");

        } catch (JSONException e) {

            LOGGER.error("Error parsing masking key array. > " + e.toString());

            return null;

        }

        JSONObject jsonPayload;

        try {

            jsonPayload = new JSONObject(stringPayload);

        } catch (JSONException e) {

            LOGGER.error("Error parsing Json payload. recived payload is : "

                    + messageContext.getProperty("TARGET_PAYLOAD"));

            return null;

        }

        maskJsonPayload(jsonPayload, keys);

        return jsonPayload;


    }


    public void maskJsonPayload(JSONObject jsonPayload, JSONArray keys) {


        // String contexts=null;

        JSONArray innerArray = null;

        JSONArray replacementArray = null;

        String lastContext = null;

        String contexts[] = null;

        JSONObject tmpJsonObject = jsonPayload;

        for (int k = 0; k < keys.length(); k++) {


            try {

                contexts = keys.getString(k).split("\\.");

            } catch (JSONException e) {

                LOGGER.error("Error parsing Keys. May be in invalid format");

            }

            lastContext = contexts[contexts.length - 1];

            for (String context : contexts) {


                if (!jsonPayload.has(context)) {

                    break;

                } else if (jsonPayload.optJSONObject(context) != null) {

                    if (context.equals(lastContext)) {

                        // this mean entire onject to be masked.

                        JSONObject tmpJson = new JSONObject();

                        try {

                            tmpJson.put("********", "************");

                            jsonPayload.put(context, tmpJson);

                        } catch (JSONException e) {

                            LOGGER.error("Error replace data with mask value :"

                                    + e.getMessage());

                            return;

                        }

                        break;

                    } else {


                        try {

                            jsonPayload = jsonPayload.getJSONObject(context);

                        } catch (JSONException e) {

                            LOGGER.error("Error parsing Json payload.");

                            return;

                        }

                        continue;

                    }

                } else if (jsonPayload.optJSONArray(context) != null) {

                    try {

                        innerArray = jsonPayload.getJSONArray(context);


                        replacementArray = new JSONArray();

                        for (int i = 0; i < innerArray.length(); i++) {

                            replacementArray.put("************");

                        }


                        jsonPayload.put(context, replacementArray);

                    } catch (JSONException e) {

                        LOGGER.error("Error replace data with mask value :"

                                + e.getMessage());

                        return;

                    }

                    break;

                } else {

                    try {

                        jsonPayload.put(context, "************");

                    } catch (JSONException e) {

                        LOGGER.error("Error replace data with mask value :"

                                + e.getMessage());

                        return;

                    }

                    break;

                }


            }

            // toupdate the this cycle results to next iteration

            jsonPayload = tmpJsonObject;

        }

        return;


    }

}

Step 5

Create an api to call the above sequence.


<api xmlns="http://ws.apache.org/ns/synapse" name="sampleAPI" context="/sampleAPI">
   <resource methods="POST GET" inSequence="dataMaskerSeq"/>
</api>

Step 6

Add this keysToBeMask.json to the registry path (/_system/governance/custom/keysToBeMasked.json) which is referred in your sequence. From this json file we are defining what will be the fields we need to mask from the payload.

keysToBeMask.json


<api xmlns="http://ws.apache.org/ns/synapse" name="sampleAPI" context="/sampleAPI">
   <resource methods="POST GET" inSequence="dataMaskerSeq"/>
</api>

Step 7

Send the request to api as following.

<account>
   <name>Borella</name>
   <password>12345</password>
   <active>yes</active>
   <code>sacfiles</code>
</account>

Then you will get a response like this.

<account>
   <name>Borella</name>
   <password>*****</password>
   <active>yes</active>
   <code>*****</code>
</account>

Thanks and have a nice day......

Monday, January 16, 2017

How to add external jar libraries to the Carbon Application Project in WSO2

WSO2 Carbon is a componentized Service Oriented Platform(SOA) platform which is build on top OSGi. Since WSO2 Carbon is based on OSGi, you can only extend the platform by dropping OSGi bundles.

The OSGi repository of WSO2 Carbon is located inside the $CARBON_HOME/repository/components folder. $CARBON_HOME is the folder where you extracted an Carbon or Carbon based product. 

You can use following directories to drop external user libraries. But you need to restart the server after adding libraries.

$CARBON_HOME/repository/components/dropins

This is the place where you can drop OSGi bundles.

$CARBON_HOME/repository/components/lib

The jar files you drop into this folder will be converted to OSGi bundles during the next server startup.

So if you want to hot deploy your custom jar files without adding to $CARBON_HOME/repository/components/lib as mentioned, you can use Java Library Project and follow below steps in WSO2 Developer Studio.

Java Library Project

With Java Library Project, you can refer a jar file or a project in your workspace and make it a bundle which will be available in to bundle classpath during the runtime. 

1) Create a Java Library Project, open WSO2 Developer Studio Dashboard and select Java Library Project from Carbon category


2) Provide a project name and click Next, Then you will navigate to a screen where you have to add your artifact.

There are two ways to create a Java Library Artifact.

  • From File System
  • From Workspace
In here we go for "File System" option, since we assume that we do have the custom jar created in our file system.

3) Upload your custom jar and click Finish.

4) Then create Carbon Application Project,  add the created Library Project to it and make a Carbon Application Archive out of it. (Make sure to set the Server Role to "Enterprise Service Bus" for Library Project)

5) Upload the .CAR to ESB server, then you will be able to see following log for successful deployment of the custom jar file.



[2017-01-17 10:25:01,731]  INFO - ApplicationManager Deploying Carbon Application : DISCOVERY_1.0.0.car...
[2017-01-17 10:25:02,710]  INFO - DefaultAppDeployer OSGi bundle in file:///home/sachini/Documents/Projects/DISCOVERY/wso2esb-5.0.0/tmp/carbonapps/-1234/1484628901732DISCOVERY_1.0.0.car/JavaLibProject_1.0.0/JavaLibProject-1.0.0.jar location is about to be installed to Carbon Server.
[2017-01-17 10:25:02,712]  INFO - DefaultAppDeployer OSGi bundle JavaLibProject installed to Carbon Server.
[2017-01-17 10:25:02,718]  INFO - DefaultAppDeployer OSGi bundle JavaLibProject successfully started on Carbon Server.

So from this, you don't need to add the .jar manually to lib folder. You can add all your synapse configurations (proxy,api etc) along with the dependent custom jars to a single .car and deploy it in ESB server at run time.

Thanks...

Tuesday, June 7, 2016

Sending mails with attachments via WSO2 ESB

1) Enable mail transport in axis2.xml

Navigate to <ESB_HOME>/repository/conf and enable following in axis2.xml


<transportReceiver name="mailto" class="org.apache.axis2.transport.mail.MailTransportListener">
        <!-- configure any optional POP3/IMAP properties
        check com.sun.mail.pop3 and com.sun.mail.imap package documentation for more details-->
  </transportReceiver>

<transportSender class="org.apache.axis2.transport.mail.MailTransportSender" name="mailto">
        <parameter name="mail.smtp.host">smtp.gmail.com</parameter>
        <parameter name="mail.smtp.port">587</parameter>
        <parameter name="mail.smtp.starttls.enable">true</parameter>
        <parameter name="mail.smtp.auth">true</parameter>
        <parameter name="mail.smtp.user">abc@gmail.com</parameter>
        <parameter name="mail.smtp.password">abc123</parameter>
        <parameter name="mail.smtp.from">abc@gmail.com</parameter>
</transportSender>

2) Create following proxy 


<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="MTOMService"
       transports="http"
       statistics="disable"
       trace="disable"
       startOnLoad="true">
   <target>
      <inSequence>
         <log level="custom">
            <property name="sequence" value="sendMailSequence"/>
         </log>
         <property name="Subject" value="sac" scope="transport"/>
         <property name="OUT_ONLY" value="true" scope="default" type="STRING"/>
         <log level="full"/>
         <send>
            <endpoint name="FileEpr">
               <address uri="mailto:mymail@gmail.com" optimize="mtom"/>
            </endpoint>
         </send>
      </inSequence>
      <outSequence>
         <send/>
      </outSequence>
   </target>
   <publishWSDL key="gov:/trunk/services/wsdl/mywsdl"/>
   <description/>
</proxy>

3) Go to soap UI and set Enable MTOM to true which is in left side of UI.

4) Attach the file you want  to send and set the cid:filename in your request as below


<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:mtom="http://org.wso2/sample/mtom">
   <soapenv:Header/>
   <soapenv:Body>
      <mtom:getBinaryData>
         <!--Optional:-->
         <mtom:dataHandler>cid:sac.pdf</mtom:dataHandler>
      </mtom:getBinaryData>
   </soapenv:Body>
</soapenv:Envelope>    

            
       
5) Once you invoke the proxy you will be able to see the attached file (sac.pdf) in recipient side.

6)  In here you will get the message body as "Web Service Message Attached" in receiving mail. This is the default message body sent by ESB. So if you want to add a customized body add the following property to the proxy.


<property name="transport.mail.bodyWhenAttached"
                   value="This text will appear in body" 
                   scope="axis2"/> 

Then you will get "This text will appear in body" message as the body of receiving email.

Monday, February 29, 2016

ESB Debugging Code ,Building and Do Patching

From this blog I will explain following.
  1. Debug the source code of ESB 4.9.0
  2. Apply a diff to ESB and build the code to do patching
  1. Debug ESB 4.9.0
  • Download the source code from https://github.com/wso2/wso2-synapse/tree/Apache-Synapse-2.1.3-wso2v11
  • Add the pom located in <CODE_BASE_490>/wso2-synapse-Apache-Synapse-2.1.3-wso2v11 to Intellij Idea
  • Navigate to Run-> Edit Configuration and add a new configuration by giving a name and a port (I have set up to 5008)
  • Then add debug points to code and you will be able to see the added  points by clicking view Breakpoints

  • Then start the ESB Server by ./wso2server.sh -debug 5008 and you will see "Listening for transport dt_socket at address: 5008 " in your terminal
  • Go to intellij and and click on green colour insect icon or Run-> Debug <your configuration name>
2.jpg

  • Once the first breakpoint reached it will stop so you can see how the code is running after the breakpoint by clicking F8. You can see what are values in variables etc.

  • You can navigate through by breakpoints by clicking green arrow (similar to play icon)Apply a diff to ESB and build the code to do patching.
     2. Apply a diff to ESB and build the code to do patching

  • Copy the diff you are having and paste to wso2-synapse-Apache-Synapse-2.1.3-wso2v11 from intellij (which is the root directory) 
  • Then right click on the uploaded .diff file and click Apply patch
  • If we made any changes inside the synapse core then go to <CODE_BASE_490>/wso2-synapse-Apache-Synapse-2.1.3-wso2v11 and run mvn clean install -Dmaven.test.skip=true
  • To reflect the changes you have done to code, you need to put the generated jar to the repository/components/patches folder inside the remote ESB. For that the newly build jar can be found at <CODE_BASE_490>/wso2-synapse-Apache-Synapse-2.1.3-wso2v11\modules\core\target
  • Copy the synapse-core-2.1.3-wso2v11.jar file to the patches directory in the ESB and rename it as the name inside the (mostly instead of - need to put _) repository/components/plugin folder(synapse-core_2.1.3.wso2v11.jar).
  • Restart the ESB to apply the patch.

Friday, October 16, 2015

Adding namespace and prefix to tags inside payload in wso2 ESB using XSLT

In this post I will share how to add namespace and prefix to tags inside payload in wso2 ESB using XSLT Mediator


We are getting following soap request


  1. <soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">  
  2.    <soapenv:Body>  
  3.     <catalog>       
  4.        <product>    
  5.           <number>100</number>    
  6.           <name>BaseBall</name>    
  7.           <colourChoices>Black</Currency>    
  8.           <price>$50</DateTime>  
  9.        </product> 
  10.       </ExchangeRate 
  11.     </catalog>  
  12.    <soapenv:Body>  
  13. <soapenv:Envelope>  


Then we want to add ex0 prefix to catalog tag and namespace must be http://sample.com/test//blog/Sample 


So we need to create sample.xslt style sheet like below


  1.   <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">  
  2.     <xsl:output indent="yes"/>  
  3.     <xsl:strip-space elements="*"/>  
  4.     <!--match all the nodes and attributes-->  
  5.     <xsl:template match="node()|@*">  
  6.         <xsl:copy>  
  7.             <xsl:apply-templates select="node()|@*">  
  8.         </xsl:apply-templates></xsl:copy>  
  9.     </xsl:template>  
  10.     <!--Select the element need to be apply the namespace and prefix -->  
  11.     <xsl:template match="catalog">  
  12.         <!--Define the namespace with prefix ns0 -->  
  13.         <xsl:element name="ex0:{name()}" namespace="http://sample.com/test/blog/Sample">  
  14.             <!--apply to above selected node-->  
  15.             <xsl:apply-templates select="node()|@*">  
  16.         </xsl:apply-templates></xsl:element>  
  17.     </xsl:template>  
  18. </xsl:stylesheet>  



Then Go to Manage-> Service Bus-> Local Entries and add the created sample.xslt file.


Then in your proxy add xslt mediator as <xslt key="sample.xslt"/> and refer the sample.xslt. Add a log mediator after that to check the changed payload


  1. <soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">  
  2.    <soapenv:Body>  
  3.       <ex0:catalog xmlns:ex0="http://sample.com/test/blog/Sample">  
  4.          <product>  
  5.             <number>100</number>  
  6.             <name>BaseBall</name>  
  7.             <colourChoices>Black</colourChoices>  
  8.             <price>50</price>  
  9.          </product>  
  10.       </ex0:catalog>  
  11.    </soapenv:Body>  
  12. </soapenv:Envelope>
 





Blogger Widgets