Wednesday, July 13, 2016

Overcoming “ps: write error: Bad file descriptor” Error at WSO2 ESB 4.8.1 startup as background service.

When you try to start up the WSO2 ESB 4.8.1 as a background service in linux, sometimes you will get the below error.

ajanthan@ajanthan-ThinkPad-T440p:~/wso2/queries/wso2esb-4.8.1/bin$ sh wso2server.sh start
ps: write error: Bad file descriptor

Even we get this error, the ESB console will be accessible through management console. To overcome this issue we need to do the below modification at the wso2server.sh file line number 177.


"if ps p $PID >& ; then" TO "if ps -p $PID > /dev/null ; then". 



WSO2 ESB API to create user in WSO2 IS RemoteUserStoreManagerService

The below sample expalains how to create a user in WSO2 IS with multiple claims using WSO2 ESB API.

The sample ESB API:

<api xmlns="http://ws.apache.org/ns/synapse" name="AdminServiceCall" context="/v8">
   <resource methods="POST" url-mapping="/addUser3" protocol="http">
      <inSequence>
         <log level="custom">
            <property name="STATUS" value="---------------------------AdminServiceCall IN Invoked------------"/>
         </log>
         <payloadFactory media-type="xml">
            <format>
               <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://common.mgt.user.carbon.wso2.org/xsd" xmlns:ser="http://service.ws.um.carbon.wso2.org">
                  <soapenv:Header/>
                  <soapenv:Body>
                     <ser:addUser>
                        <ser:userName>$1</ser:userName>
                        <ser:credential>$2</ser:credential>
                        <ser:roleList>$3</ser:roleList>
                        <ser:claims>
                           <xsd:claimURI>$4</xsd:claimURI>
                           <xsd:value>$5</xsd:value>
                        </ser:claims>
                        <ser:claims>
                           <xsd:claimURI>$6</xsd:claimURI>
                           <xsd:value>$7</xsd:value>
                        </ser:claims>
                        <ser:claims>
                           <xsd:claimURI>$8</xsd:claimURI>
                           <xsd:value>$9</xsd:value>
                        </ser:claims>
                        <ser:claims>
                           <xsd:claimURI>$10</xsd:claimURI>
                           <xsd:value>$11</xsd:value>
                        </ser:claims>
                        <ser:profileName>$12</ser:profileName>
                        <ser:requirePasswordChange>false</ser:requirePasswordChange>
                     </ser:addUser>
                  </soapenv:Body>
               </soapenv:Envelope>
            </format>
            <args>
               <arg evaluator="json" expression="$.userName"/>
               <arg evaluator="json" expression="$.password"/>
               <arg evaluator="json" expression="$.roles"/>
               <arg evaluator="json" expression="$.claims.claimURIAddress"/>
               <arg evaluator="json" expression="$.claims.claimValueAddress"/>
               <arg evaluator="json" expression="$.claims.claimURICountry"/>
               <arg evaluator="json" expression="$.claims.claimURIValueCountry"/>
               <arg evaluator="json" expression="$.claims.claimURIName"/>
               <arg evaluator="json" expression="$.claims.claimURIValueName"/>
               <arg evaluator="json" expression="$.claims.claimURIEmail"/>
               <arg evaluator="json" expression="$.claims.claimValueEmail"/>
               <arg evaluator="json" expression="$.profileName"/>
            </args>
         </payloadFactory>
         <property xmlns:ns="http://org.apache.synapse/xsd" name="Authorization" expression="fn:concat('Basic ', base64Encode('admin:admin'))" scope="transport"/>
         <send>
            <endpoint>
               <address uri="https://localhost:9446/services/RemoteUserStoreManagerService" trace="disable" format="soap12"/>
            </endpoint>
         </send>
      </inSequence>
      <outSequence>
         <log level="custom">
            <property name="STATUS" value="---------------------------AdminServiceCall Out Sequence Invoked------------"/>
         </log>
         <send/>
      </outSequence>
   </resource>
</api>  

Sample Request:
{
    "userName": "ajanthan_15",
    "password": "batticaloa",
    "roles": "Internal/everyone",
    "claims": {
        "claimURIAddress": "http://wso2.org/claims/streetaddress",
        "claimValueAddress": "15 Colombo Srilanka",
        "claimURICountry": "http://wso2.org/claims/country",
        "claimURIValueCountry": "Srilanka",
        "claimURIName": "http://wso2.org/claims/displayName",
        "claimURIValueName": "Ajanthan",
        "claimURIEmail": "http://wso2.org/claims/emailaddress",
        "claimValueEmail": "aja00@yahoo.com"
    },
    "profileName": "default"
}

Tuesday, July 5, 2016

Overcoming proxy / non proxy host issue in axis2.xml WSO2 ESB ( Resolving Host to IP )

When using the WSO2 ESB and configuring the HTTP Proxy in axis2.xml, indicating that all the requests out from ESB should or shouldn't go through a HTTP Proxy ( eg: Squid Proxy ), will encounter a problem that when we use wild card inside the axis2.xml to filter the requests and use Host name inside the call mediator or send mediator, then due to ESB not able to convert the host name to IP, the HTTP Proxy configuration will not work.

To overcome the issue, need to use a custom class mediator which can convert the Host name to IP and set it to message context and then use uri-template in WSO2 ESB to call the URL as dynamic.


Below given is the sample axis configuration, proxy service and the custom class mediator.

<transportSender name="http" class="org.apache.synapse.transport.passthru.PassThroughHttpSender">
        <parameter name="non-blocking" locked="false">true</parameter>
        <parameter name="non-blocking" locked="false">true</parameter>
        <parameter name="http.proxyHost" locked="false">172.22.217.35</parameter>
        <parameter name="http.proxyPort" locked="false">3128</parameter>
        <parameter locked="false" name="http.nonProxyHosts">172.22.217.*</parameter>
        <parameter name="HostnameVerifier">AllowAll</parameter>
    </transportSender>

    <transportSender name="https" class="org.apache.synapse.transport.passthru.PassThroughHttpSSLSender">
        <parameter name="non-blocking" locked="false">true</parameter>
        <parameter name="http.proxyHost" locked="false">172.22.217.35</parameter>
        <parameter name="http.proxyPort" locked="false">3128</parameter>
        <parameter locked="false" name="http.nonProxyHosts">172.22.217.*</parameter>
        <parameter name="HostnameVerifier">AllowAll</parameter>
        <parameter name="keystore" locked="false">
            <KeyStore>
                <Location>repository/resources/security/wso2carbon.jks</Location>
                <Type>JKS</Type>
                <Password>wso2carbon</Password>
                <KeyPassword>wso2carbon</KeyPassword>
            </KeyStore>
        </parameter>
        <parameter name="truststore" locked="false">
            <TrustStore>
                <Location>repository/resources/security/client-truststore.jks</Location>
                <Type>JKS</Type>
                <Password>wso2carbon</Password>
            </TrustStore>
        </parameter>
        <!--<parameter name="HostnameVerifier">DefaultAndLocalhost</parameter>-->
            <!--supports Strict|AllowAll|DefaultAndLocalhost or the default if none specified -->
    </transportSender>

Sample Proxy Service

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="HostToIPResolver"
       transports="https http"
       startOnLoad="true"
       trace="disable">
   <description/>
   <target>
      <inSequence>
         <log level="custom">
            <property name="STATUS:"
                      value="----------------HostToIPResolver Proxy Invoked--------------------------"/>
         </log>
         <class name="com.custom.hostip.reslver.CustomHostToIPResolver">
            <property name="endpointHostName" value="ajanthan.wso2.com"/>
         </class>
         <property name="url_1" value="http://"/>
         <property name="url_2" expression="get-property('ResolvedIP')"/>
         <property name="url_3" value=":8088/mockechoSoap11Binding"/>
         <property name="concat_url"
                   expression="fn:concat(get-property('url_1'),get-property('url_2'), get-property('url_3'))"/>
         <log level="custom">
            <property name="Concatenated_URL:" expression="get-property('concat_url')"/>
         </log>
         <call>
            <endpoint name="endpointName"
                      template="HostEndpointTemplate"
                      uri="${concat_url}"/>
         </call>
         <respond/>
      </inSequence>
   </target>
</proxy>


Custom Class Mediator
package com.custom.hostip.reslver;

import java.net.InetAddress;
import java.net.UnknownHostException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.synapse.MessageContext;
import org.apache.synapse.mediators.AbstractMediator;

public class CustomHostToIPResolver extends AbstractMediator {

 private static Log log = LogFactory.getLog(CustomHostToIPResolver.class);
 private String endpointHostName;

 public boolean mediate(MessageContext context) {

  if (log.isDebugEnabled()) {
   log.debug("[CUSTOM_LOG] CustomHostToIPResolver mediate method invoked.");
  }

  InetAddress address = null;

  try {
   address = InetAddress.getByName(endpointHostName);
  } catch (UnknownHostException e) {
   if (log.isDebugEnabled()) {
    log.debug("[CUSTOM_LOG] Exception Occured while resolving the IP Address."
      + e.getMessage());
   }
  }
  log.info("[CUSTOM_LOG] Resolved IP Address: "
    + address.getHostAddress());
  context.setProperty("ResolvedIP", address.getHostAddress());
  return true;
 }

 public String getEndpointHostName() {
  return endpointHostName;
 }

 public void setEndpointHostName(String endpointHostName) {
  this.endpointHostName = endpointHostName;
 }

}


pom.xml used to build the maven project

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.custom.hostip.reslver.CustomHostToIPResolver</groupId>
  <artifactId>CustomHostToIPResolver</artifactId>
  <version>1.0.0</version>
  <packaging>bundle</packaging>
  <name>CustomHostToIPResolver</name>
  <description>CustomHostToIPResolver</description>
  <properties>
    <CApp.type>lib/synapse/mediator</CApp.type>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.apache.synapse</groupId>
      <artifactId>synapse-core</artifactId>
      <version>2.1.2-wso2v2</version>
    </dependency>
    <dependency>
      <groupId>commons-httpclient.wso2</groupId>
      <artifactId>commons-httpclient</artifactId>
      <version>3.1.0.wso2v2</version>
    </dependency>
    <dependency>
      <groupId>commons-codec.wso2</groupId>
      <artifactId>commons-codec</artifactId>
      <version>1.4.0.wso2v1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.woden.wso2</groupId>
      <artifactId>woden</artifactId>
      <version>1.0.0.M8-wso2v1</version>
    </dependency>
    <dependency>
      <groupId>wsdl4j.wso2</groupId>
      <artifactId>wsdl4j</artifactId>
      <version>1.6.2.wso2v4</version>
    </dependency>
    <dependency>
      <groupId>org.apache.abdera.wso2</groupId>
      <artifactId>abdera</artifactId>
      <version>1.0.0.wso2v3</version>
    </dependency>
    <dependency>
      <groupId>org.apache.geronimo.specs.wso2</groupId>
      <artifactId>geronimo-stax-api_1.0_spec</artifactId>
      <version>1.0.1.wso2v2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.ws.commons.schema.wso2</groupId>
      <artifactId>XmlSchema</artifactId>
      <version>1.4.7.wso2v2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.httpcomponents.wso2</groupId>
      <artifactId>httpcore</artifactId>
      <version>4.3.0.wso2v1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.neethi.wso2</groupId>
      <artifactId>neethi</artifactId>
      <version>2.0.4.wso2v4</version>
    </dependency>
    <dependency>
      <groupId>org.apache.ws.commons.axiom.wso2</groupId>
      <artifactId>axiom</artifactId>
      <version>1.2.11.wso2v4</version>
    </dependency>
    <dependency>
      <groupId>org.apache.axis2.wso2</groupId>
      <artifactId>axis2</artifactId>
      <version>1.6.1.wso2v10</version>
    </dependency>
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1.1</version>
    </dependency>
    <dependency>
      <groupId>commons-io.wso2</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.0.0.wso2v2</version>
    </dependency>
  </dependencies>
  <repositories>
    <repository>
      <releases>
        <enabled>true</enabled>
        <updatePolicy>daily</updatePolicy>
        <checksumPolicy>ignore</checksumPolicy>
      </releases>
      <id>wso2-nexus</id>
      <url>http://maven.wso2.org/nexus/content/groups/wso2-public/</url>
    </repository>
  </repositories>
  <pluginRepositories>
    <pluginRepository>
      <releases>
        <enabled>true</enabled>
        <updatePolicy>daily</updatePolicy>
        <checksumPolicy>ignore</checksumPolicy>
      </releases>
      <id>wso2-nexus</id>
      <url>http://maven.wso2.org/nexus/content/groups/wso2-public/</url>
    </pluginRepository>
  </pluginRepositories>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.felix</groupId>
        <artifactId>maven-bundle-plugin</artifactId>
        <version>2.3.4</version>
        <extensions>true</extensions>
        <configuration>
          <instructions>
            <Bundle-SymbolicName>CustomHostToIPResolver</Bundle-SymbolicName>
            <Bundle-Name>CustomHostToIPResolver</Bundle-Name>
            <Export-Package>com.custom.hostip.reslver</Export-Package>
            <DynamicImport-Package>*</DynamicImport-Package>
          </instructions>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-eclipse-plugin</artifactId>
        <version>2.9</version>
        <configuration>
          <buildcommands>
            <buildcommand>org.eclipse.jdt.core.javabuilder</buildcommand>
          </buildcommands>
          <projectnatures>
            <projectnature>org.wso2.developerstudio.eclipse.artifact.mediator.project.nature</projectnature>
            <projectnature>org.eclipse.jdt.core.javanature</projectnature>
          </projectnatures>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>




Saturday, June 11, 2016

[RABBITMQ - ARTICLE:2] Connecting to RabbitMQ using Java Client

Consider, here the samples are given to the Queue / Topic is created in RabbitMQ virtual host, not in the default / host.

For the installation of RabbitMQ, follow my previous post on it. http://ajanthane.blogspot.com/2016/06/rabbitmq-article-1-installing-rabbitmq.html

Creating a Virtual Host, Queue, Topic and User in RabbitMQ through management console. You can follow the below screen shots to achieve it.

Log into Management Console -> Select Virtual Hosts 

 Create New Virtual Host
 Select Users
Create a New User
 Give permission to the created user to access the created virtual host.


Give permission to guest user to access new virtual host, this will help us to use guest user to create queue, topic through management console.

Create a queue in virtual host.

Create a new Exchange.

Publishing Directly to Queue in RabbitMQ

 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>RabbitMQClient</groupId>
  <artifactId>RabbitMQClient</artifactId>
  <version>0.0.1</version>
  <name>RabbitMQClient</name>
  <description>RabbitMQClient</description>
  <dependencies>
  <dependency>
    <groupId>com.rabbitmq</groupId>
    <artifactId>amqp-client</artifactId>
    <version>3.6.1</version>
</dependency>
</dependencies>
<repositories>
<repository>
        <id>sonatype-nexus-staging</id>
        <name>Nexus Release Repository</name>
        <url>http://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
      </repository>
  </repositories>  
</project>


import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;


public class SendMessageToQueue {
 
 private static final String QUEUE_NAME = "TEST_EVENT_Q";

    public static void main(String[] argv)
            throws java.io.IOException, TimeoutException {

        System.out.println("Message Sending started........");

        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        factory.setVirtualHost("EVENTS");
        factory.setUsername("wso2user");
        factory.setPassword("wso2user");
        factory.setPort(5671); // Here the 5671 is the TCP Listener Port
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        // channel.queueDeclare(QUEUE_NAME, true, false, false, null); 
        // If queue created already the above queue declaration is not needed.
        String message = "Test Message to Queue";
        channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
        System.out.println(" [x] Sent '" + message + "'");

        channel.close();
        connection.close();
    }

}


Publishing Through Topic Exchange


Here we need to bind the Topic to a queue. So, when we send a message with a routing key to the exchange, based on the routing key it will be routed to Queue.



import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;

public class SendMessageToRabbitMQ {

    private static final String EXCHANGE_NAME = "EVENTS_EXC";

    public static void main(String[] argv)
            throws java.io.IOException, TimeoutException {

        System.out.println("Message Sending started........");

        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        factory.setVirtualHost("EVENTS");
        factory.setUsername("wso2user");
        factory.setPassword("wso2user");
        factory.setPort(5671); // Here the 5671 is the TCP Listener Port
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        //channel.exchangeDeclare(EXCHANGE_NAME, "topic", true, false, false, null);
        // As we already have the exchange the decalaration is not needed.
        String message = "Test Message to RabbitMQ Exchange from Java Client";

        channel.basicPublish(EXCHANGE_NAME, "test", null, message.getBytes());
        System.out.println(" [STATUS] Sent '" + message + "'");

        channel.close();
        connection.close();
    }
}

References


[1] https://www.rabbitmq.com/tutorials/tutorial-one-java.html
[2] https://www.rabbitmq.com/tutorials/tutorial-three-java.html

[RABBITMQ - ARTICLE:1] Installing RabbitMQ in Ubuntu

This article describes about how to install RabbitMQ in Ubuntu and how to configure it for our use and also explains about the logs available.

Versions: RabbitMQ 3.6.1
Dependency: Erlang 18.2

Before start the installation, we need to install Erlang 18.2 which is a dependency for RabbitMQ. You can find the installation steps for Erlang in my previous blog:

http://ajanthane.blogspot.com/2016/06/installing-erlang-in-ubuntu.html

After successfully installed the Erlang, download the RabbitMQ Server Generic Unix from the below location.
https://www.rabbitmq.com/install-generic-unix.html , Here you can find the latest version.

To find previous versions, you can follow this link.

As here our version is 3.6.1, go to the above link and download the rabbitmq-server-generic-unix-3.6.1.tar.xz.

After extracting, we can start the RabbitMQ Server. Go to

/home/ajanthan/rabbitmq_server-3.6.1/sbin

and execute the below command

ajanthan@ajanthan-ThinkPad-T440p:~/rabbitmq_server-3.6.1/sbin$
./rabbitmq-server start

By Default the management console is not enabled in the installation. To enable it you need to run the below command to install the management plugins.
ajanthan@ajanthan-ThinkPad-T440p:~/rabbitmq_server-3.6.1/sbin$
./rabbitmq-plugins enable rabbitmq_management

After installing the management plugins, if we done a restart the console will look like this.



Commands for start and stop RabbitMQ Server:
ajanthan@ajanthan-ThinkPad-T440p:~/rabbitmq_server-3.6.1/sbin$ ./rabbitmq-server start

ajanthan@ajanthan-ThinkPad-T440p:~/rabbitmq_server-3.6.1/sbin$ ./rabbitmqctl stop
Command to check log files:
ajanthan@ajanthan-ThinkPad-T440p:~/rabbitmq_server-3.6.1$ sudo tail -f var/log/rabbitmq/rabbit@ajanthan-ThinkPad-T440p.log


Now you can access the management console using:
URL: http://localhost:15672
Username: guest
Password: guest

References


[1] https://www.rabbitmq.com/

Installing Erlang in Ubuntu

When installing RabbitMQ, Erlang is a dependency. To install specific version of Erlang you can follow this article.

All the Erlang versions can be downloaded from http://www.erlang.org/download/ location. After selecting the correct version use the below commands to install Erlang in Ubuntu.
sudo apt-get update
sudo apt-get --fix-missing -y install build-essential m4 libncurses5-dev libssh-dev unixodbc-dev libgmp3-dev libwxgtk2.8-dev libglu1-mesa-dev fop xsltproc 
mkdir -p /src/erlang
cd /src/erlang
wget http://www.erlang.org/download/otp_src_18.2.tar.gz 
tar -xvzf otp_src_18.2.tar.gz
chmod -R 777 otp_src_18.2 
cd otp_src_18.2 
./configure
make
sudo make install

Saturday, May 28, 2016

Handling Content-Type when connecting to Weblogic Message Queue through WSO2 ESB

Some of the Message broker's do not accept "-" in headers. Eg. Weblogic do not support Content-type parameter. Below is a solution to get rid of the issue, by
setting transport.jms.ContentTypeProperty in the jms URL and setting the value as below:

      
         JMSContentType
         application/xml
      


A sample proxy service to achieve this requirement is as below:

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="WeblogicJMSSenderProxy"
       transports="http"
       statistics="disable"
       trace="disable"
       startOnLoad="true">
   <target>
      <inSequence>
         <property name="Accept-Encoding" scope="transport" action="remove"/>
         <property name="Content-Length" scope="transport" action="remove"/>
         <property name="Content-Type" scope="transport" action="remove"/>
         <property name="User-Agent" scope="transport" action="remove"/>
         <log level="custom">
            <property name="STATUS:"
                      value="------Message Sent by WeblogicJMSConsumerProxy--------"/>
         </log>
         <send>
            <endpoint>
               <address uri="jms:/jms/TestJMSQueue1?transport.jms.ConnectionFactoryJNDIName=jms/TestConnectionFactory1&java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory&java.naming.provider.url=t3://localhost:7001&transport.jms.DestinationType=queue&transport.jms.ReplyDestination=jms/Queue2&transport.jms.ContentTypeProperty=JMSContentType"/>
            </endpoint>
         </send>
      </inSequence>
      <outSequence>
         <log level="custom">
            <property name="STATUS:"
                      value="------------------Out sequence invoked---------------------"/>
         </log>
         <log level="full"/>
         <log level="custom">
            <property name="STATUS:"
                      value="------------------Out sequence invoked - Before content type set ---------------------"/>
         </log>
         <send/>
      </outSequence>
   </target>
   <parameter name="transport.jms.ContentType">
      <rules>
         <jmsProperty>JMSContentType</jmsProperty>
         <default>application/xml</default>
      </rules>
   </parameter>
   <description/>
</proxy>