Tuesday, February 3, 2015

Setting up 2 VM subnets each with 2 virtual machines and add routing between them in VirtualBox


I'm going to create 4 virtual machines running on VirtualBox and 2 Subnets with 2 VMs per each subnet and add routing between those 2 subnets.

If you are new to VirtualBox it's better to go thru the network types available in VirtualBox [1]

First you need to enable a new network adapter and attach the network to "Internal network". use the same internal network name for each VM.
After enabling start the VMs and configure each VM as follows in the interface configuration
/etc/network/interfaces

Subnet 01 contains VM01 and VM02
10.1.0.0/24

Subnet 02 contains VM03 and VM04
10.1.1.0/24

Following shows the configuration which should be added to Subnet 01's one VM.

iface eth1 inet static
         address 10.1.0.1
         netmask 255.255.255.0
         network 10.1.0.0
         broadcast 10.1.0.255

likewise configure each VM with the relevant configuration

after that stop the interface and start the interface using following commands
sudo ifdown eth1
sudo ifup eth1

you might sometimes need to restart the network-manager service too. in that case use command
sudo service network-manager restart

After configuring subnets you will be able to ping from/to VM01 from/to VM02 and  from/to VM03 from/to VM04

By executing following command you will be able to add routing between the subnets
route add -net 10.0.1.0/24 dev eth1 (this is for subnet 02 machines)

you can view the routing table by executing "route -n"

Now you will be able to communicate with each and every node in the two subnets


[1] https://www.virtualbox.org/manual/ch06.html

Quick-tips

SSH Tunneling


ssh -f -N -L local-port:host:remote-port user@personal-sever

-N instructs OpenSSH to not execute a command on the remote system
-f tells ssh to go into the background just before it executes the command
-L tells how the traffic through person-server to tunnel to local machine as in local-port:host:remote-port

example usage: ssh -f -N -L 9443:10.0.69.42:9443 rajith@54.124.15.43

Traffic from 10.0.69.42 port 9443 will be tunneled via 54.124.15.43 to my local machine under port 9443


Java Cryptography Extension (JCE) unlimited strength jurisdiction policy


How install

How to test

Execute the following,

import javax.crypto.Cipher;
import java.security.NoSuchAlgorithmException;

public class Main {

    public static void main(String[] args) throws NoSuchAlgorithmException {
        int maxKeyLen = Cipher.getMaxAllowedKeyLength("AES");
        System.out.println(maxKeyLen);
    }
}

Without the JCE unlimited strength policy files the result would be 128. if the installation is successful the result will be 2147483647


Sunday, February 1, 2015

Generating UUIDs for WSO2 Identity Server creating/provisioning users

Username is the default identifier for users created/provisioned by the WSO2 Identity Server. If you need UUIDs for users you'll have write a custom listener by implementing the "doPostAddUser" method in "UserOperationEventListener" interface to generate UUIDs.

The new implementation of the interface should be bundled as a carbon component so that it can be registered by copying the jar to [IS_HOME]/repository/components/dropins.

Following code chuck provides a sample implementation of the method using the "AbstractUserOperationEventListener"

import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.user.core.UserRealm;
import org.wso2.carbon.user.core.UserStoreException;
import org.wso2.carbon.user.core.UserStoreManager;
import org.wso2.carbon.user.core.common.AbstractUserOperationEventListener;

import java.util.Map;

public class UserAttributeListener extends AbstractUserOperationEventListener {

    public static final int ID_LENGTH = 30; // set the length of the unique identifier
    private static final Log log = LogFactory.getLog(UserAttributeListener.class);
    private static final int EXECUTION_ORDER = 520; // this is for internal use, can keep as it is
    private static final String CLAIM_URI = "http://wso2.org/claims/uniqueId"; // Claim URI for unique identifier as
    // configured in management console

    @Override
    public boolean doPostAddUser(String userName, Object credential, String[] roleList,
                                 Map<String, String> claims, String profile,
                                 UserStoreManager userStoreManager) throws UserStoreException {

        UserRealm realm = (UserRealm) CarbonContext.getThreadLocalCarbonContext().getUserRealm();
        if (log.isDebugEnabled()) {
            log.debug("Post add user is called in UserAttributeListener");
        }
        try {
            String uniqueId = generateUniqueId();
            realm.getUserStoreManager().setUserClaimValue(userName, CLAIM_URI, uniqueId, profile);
        } catch (UserStoreException e) {
            log.error("Error occurred while adding custom attribute to user : " + userName, e);
        }
        return true;
    }

    /*
        Generates the unique identifier. Customize this method to generate a unique identifier using a preferred way.
     */
    private String generateUniqueId() {
        return RandomStringUtils.randomAlphanumeric(ID_LENGTH);
    }

    @Override
    public int getExecutionOrderId() {
        return EXECUTION_ORDER;
    }
}
You can customize the method "generateUniqueId()" to generate the unique ID as required.
After deploying the bundle you have to configure a custom claim as follows,
  1. Navigate to Configure --> Claim Management in management console
  2. Select "http://wso2.org/claims"
  3. Add New Claim Mapping
  4. Give a display name and description accordingly. Claim URL should be "http://wso2.org/claims/uniqueId". Check both boxes of "Supported by Default" and "Required". Mapped Attribute must be a valid attribute in the underlying user store and the uniquer identifier will be stored in the User store under this attribute of the User
  5. Add the claim
Now when adding Users using any of the methods (Federeated with JIT provisioning, Using Managerment Console and etc), custom listener will be triggered and a Unique identifier will be generated.

Sending e-mails in HTML format in WSO2 ESB

Enabling mail transport sender and configuring message builder and message formatter. 


1. Uncomment the mail transport sender configuration in the <ESB_HOME>/repository/conf/axis2/axis2.xml file and make sure it points to a valid SMTP configuration for an actual scenario [1]


<transportSender name="mailto" class="org.apache.synapse.transport.mail.MailTransportSender">
    <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">synapse.demo.0</parameter>
    <parameter name="mail.smtp.password">mailpassword</parameter>
    <parameter name="mail.smtp.from">synapse.demo.0@gmail.com</parameter>
</transportSender>

2. Next configure the following builder and formatter in axis2 configuration for given content-type (text/html).

<messageBuilder contentType="text/html" class="org.apache.axis2.builder.ApplicationXMLBuilder"/> 
<messageFormatter contentType="text/html" class="org.apache.axis2.transport.http.ApplicationXMLFormatter"/>

However if you include special html tags to the email content like

<DOCTYPE> , <!-- Comment --> <?xml - xml declaration tags for rich content validating and rendering purposes you cannot use above mentioned XML builder and formatter and you will get errors while passing the mail message through ESB [2]

In that case you'll have to use BinaryRelayBuilder & ExpandingMessageFormatter. [2]

<messageBuilder contentType="text/html" class="org.wso2.carbon.relay.BinaryRelayBuilder"/>
<messageFormatter contentType="text/html" class="org.wso2.carbon.relay.ExpandingMessageFormatter"/> 

You can use following two options of using PayloadFactory mediator or using XSLT mediator to transform request payload into html.

Option 1: HTML template given as a local entry and map the request payload values into the place holders in html (Using PayloadFactory mediator)


Let's take a simple scenario of sending a simple email with adding the symbol taken from the request payload.

html email template as a local entry


<localEntry key="email_template_01">
<html>
    <body>
        <h2 style="color:green">$1</h2>
        <p>email template 01</p>
    </body>
</html>
<description/>
</localEntry>

Synapse configuration

MailTestProxy sets the property "SYMBOL" from the request payload and map the "symbol" value to the template.

<proxy name="MailTestProxy" 
       transports="https http"
       startOnLoad="true"
       trace="disable">
    <description/>
    <target>
        <inSequence>
            <property name="Subject" value="Testing email template" scope="transport"/>
            <property name="SYMBOL" expression="$body//symbol"/>
            <payloadFactory media-type="xml">
                <format key="email_template_01"/>
                <args>
                    <arg evaluator="xml" expression="get-property('SYMBOL')"/>
                </args>
            </payloadFactory>
            <property name="OUT_ONLY" value="true"/>
            <property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
            <send>
                <endpoint>
                    <address uri="mailto:xxx@xxx.com"/>
                </endpoint>
            </send>
            <drop/>
        </inSequence>
    </target> 
<proxy>

SOAP request

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
    <symbol>WSO2</symbol>
</soapenv:Body>
</soapenv:Envelope>


Option 2: HTML template given as a xsl style sheet and using xslt mediator to transform the request payload values to the html tag values.


Let's take a simple scenario transforming Order details (which contains several items) into a simple email

Transforming the following request payload 


<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/> 
  <soapenv:Body> 
    <order id="54"> 
      <items> 
        <item> 
          <name>Cap</name> 
          <price>10.90</price> 
        </item> 
        <item> 
          <name>Hat</name> 
          <price>12.90</price> 
        </item> 
      </items> 
    </order> 
  </soapenv:Body> 
</soapenv:Envelope>

Into email body of 

<html xmlns=3D"http://ws.apache.org/ns/synapse"> 
   <body> 
      <h2>My Order</h2> 
      <h3>54</h3> 
      <table border=3D"1"> 
         <tr bgcolor=3D"#9acd32"> 
            <th>Item</th> 
            <th>Price</th> 
         </tr> 
         <tr> 
            <td>Cap</td> 
            <td>10.90</td> 
         </tr> 
         <tr> 
            <td>Hat</td> 
            <td>12.90</td> 
         </tr> 
      </table> 
   </body> 
</html>

Synapse configuration

<proxy name="MailTestProxy"
             transports="https http"
             startOnLoad="true"
             trace="disable">
    <description/>
    <target>
        <inSequence>
            <property name="Subject" value="My Orders" scope="transport"/> 
            <xslt key="html_transform"/> <property name="OUT_ONLY" value="true"/> 
            <property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
            <send>
                <endpoint>
                    <address uri="mailto:xxx@xxx.com"/>
                </endpoint>
            </send>
            <drop/>
        </inSequence>
    </target>
</proxy>


xsl style sheet as a local entry (e-mail template)


<localEntry key="html_transform"> 
      <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
         <xsl:output indent="yes" method="xml" omit-xml-declaration="yes"/> 
         <xsl:template match="/"> 
            <html> 
               <body> 
                  <h2>My Order</h2> 
                  <h3> 
                     <xsl:value-of select="order/@id"/> 
                  </h3> 
                  <table border="1"> 
                     <tr bgcolor="#9acd32"> 
                        <th>Item</th> 
                        <th>Price</th> 
                     </tr> 
                     <xsl:for-each select="order/items/item"> 
                        <tr> 
                           <td> 
                              <xsl:value-of select="name"/> 
                           </td> 
                           <td> 
                              <xsl:value-of select="price"/> 
                           </td> 
                        </tr> 
                     </xsl:for-each> 
                  </table> 
               </body> 
            </html> 
         </xsl:template> 
      </xsl:stylesheet> 
      <description/> 
</localEntry>

If you want to take the email address also from the request payload then add the following part to synapse configuration


<header name="To" expression="fn:contact('mailto:',[This can be //Xpath or if comes from transport $trp:header] )"/> 
<send> 
    <endpoint> 
        <default/>
    </endpoint> 
</send>

and remove following part from the synapse configuration

<send>
    <endpoint>
        <address uri="mailto:xxx@xxx.com"/>
    </endpoint>
</send>